Android поддерживает различные сенсорные экраны и сенсорные панели, включая планшеты со стилусом.
Сенсорные экраны — это сенсорные устройства, которые связаны с дисплеем таким образом, что у пользователя создается впечатление непосредственного манипулирования элементами на экране.
Сенсорные панели — это сенсорные устройства, не связанные с дисплеем, например, планшеты для цифровых планшетов. Сенсорные панели обычно используются для указания, абсолютного непрямого позиционирования или управления пользовательским интерфейсом с помощью жестов.
Сенсорные устройства могут иметь кнопки, функции которых аналогичны кнопкам мыши.
В зависимости от технологии сенсорного датчика, используемой в сенсорных устройствах, иногда можно управлять с помощью различных инструментов, например пальцев или стилуса.
Сенсорные устройства иногда используются для реализации виртуальных клавиш. Например, на некоторых устройствах Android область сенсорного экрана выходит за пределы края дисплея и выполняет двойную функцию, являясь частью сенсорной клавиатуры.
Ввиду большого разнообразия сенсорных устройств Android использует большое количество свойств конфигурации для описания характеристик и желаемого поведения каждого устройства.
Классификация сенсорных устройств
Устройство ввода классифицируется как устройство с поддержкой мультитач, если выполняются оба следующих условия:
- Устройство ввода сообщает о наличии абсолютных осей
ABS_MT_POSITION_X
иABS_MT_POSITION_Y
. - Устройство ввода не имеет кнопок геймпада. Это условие устраняет неоднозначность, связанную с некоторыми геймпадами, которые сообщают об осях с кодами, перекрывающими коды осей MT.
Устройство ввода классифицируется как устройство с одним касанием, если выполняются оба следующих условия:
- Устройство ввода не классифицируется как устройство с поддержкой нескольких касаний. Устройство ввода классифицируется либо как устройство с однокасание, либо как устройство с поддержкой нескольких касаний, но не как устройство с обоими типами касаний.
- Устройство ввода сообщает о наличии абсолютных осей
ABS_X
иABS_Y
, а также о наличии кода клавишиBTN_TOUCH
.
Если устройство ввода классифицируется как сенсорное, наличие виртуальных клавиш определяется путём попытки загрузки файла карты виртуальных клавиш для устройства. Если карта виртуальных клавиш доступна, также загружается файл раскладки клавиш для устройства. Информация о расположении и формате этих файлов представлена в разделе [Файлы карт виртуальных клавиш](#virtual-key-map-files).
Далее система загружает файл конфигурации устройства ввода для сенсорного устройства.
Все встроенные сенсорные устройства должны иметь файлы конфигурации устройств ввода. Если файл конфигурации отсутствует, система выбирает конфигурацию по умолчанию, подходящую для универсальных сенсорных периферийных устройств, таких как внешние сенсорные экраны HID с USB-портом или Bluetooth, а также сенсорные панели. Эти настройки по умолчанию не предназначены для встроенных сенсорных экранов и могут привести к некорректной работе.
После загрузки конфигурации устройства ввода система классифицирует устройство ввода как сенсорный экран , сенсорную панель или указательное устройство.
- Сенсорный экран используется для непосредственного управления объектами на экране. Пользователь непосредственно прикасается к экрану, поэтому системе не требуются дополнительные возможности для обозначения объектов, которыми он управляет.
- Сенсорная панель используется для предоставления приложению информации об абсолютном местоположении касаний к заданной области сенсора. Она может быть полезна для планшетов-дигитайзеров.
- Указательное устройство используется для косвенного управления объектами на экране с помощью курсора. Пальцы интерпретируются как многосенсорные жесты. Другие инструменты, такие как стилусы, интерпретируются с использованием абсолютных положений. Подробнее см. в разделе Косвенные многосенсорные жесты .
Для классификации устройств ввода на сенсорный экран, сенсорную панель или указательное устройство используются следующие правила.
- Если свойство
touch.deviceType
задано, то тип устройства устанавливается указанным образом. - Если устройство ввода сообщает о наличии свойства ввода
INPUT_PROP_DIRECT
(через ioctl-вызовEVIOCGPROP
), то тип устройства устанавливается как сенсорный экран . Это условие предполагает, что устройства прямого сенсорного ввода подключены к дисплею, который также подключен. - Если устройство ввода сообщает о наличии свойства ввода
INPUT_PROP_POINTER
(через ioctlEVIOCGPROP
), то тип устройства устанавливается на указатель . - Если устройство ввода сообщает о наличии относительных осей
REL_X
илиREL_Y
, то тип устройства устанавливается как сенсорная панель . Это условие устраняет неоднозначность для устройств ввода, которые представляют собой как мышь, так и сенсорную панель. В этом случае сенсорная панель не используется для управления указателем, поскольку ею уже управляет мышь. - В противном случае тип устройства устанавливается как «указатель» . Это значение по умолчанию гарантирует, что сенсорные панели, не предназначенные для какого-либо другого специального назначения, будут управлять указателем.
Кнопки
Кнопки — это дополнительные элементы управления, которые приложения могут использовать для выполнения дополнительных функций. Кнопки на сенсорных устройствах работают аналогично кнопкам мыши и используются в основном с сенсорными устройствами указателя или стилусом.
Поддерживаются следующие кнопки:
-
BTN_LEFT
: Сопоставлено сMotionEvent.BUTTON_PRIMARY
. -
BTN_RIGHT
: сопоставлено сMotionEvent.BUTTON_SECONDARY
. -
BTN_MIDDLE
: Сопоставлено сMotionEvent.BUTTON_MIDDLE
. -
BTN_BACK
иBTN_SIDE
: сопоставлены сMotionEvent.BUTTON_BACK
. Нажатие этой кнопки также синтезирует нажатие клавиши с кодомKeyEvent.KEYCODE_BACK
. -
BTN_FORWARD
иBTN_EXTRA
: сопоставлены сMotionEvent.BUTTON_FORWARD
. Нажатие этой кнопки также синтезирует нажатие клавиши с кодомKeyEvent.KEYCODE_FORWARD
. -
BTN_STYLUS
: Сопоставлено сMotionEvent.BUTTON_SECONDARY
. -
BTN_STYLUS2
: Сопоставлено сMotionEvent.BUTTON_TERTIARY
.
Инструменты и типы инструментов
Инструмент — это палец, стилус или другой предмет, используемый для взаимодействия с сенсорным устройством. Некоторые сенсорные устройства различают разные типы инструментов.
В других частях Android, например в API MotionEvent
, инструмент часто называют указателем .
Поддерживаются следующие типы инструментов:
-
BTN_TOOL_FINGER
иMT_TOOL_FINGER
: сопоставлены сMotionEvent.TOOL_TYPE_FINGER
. -
BTN_TOOL_PEN
иMT_TOOL_PEN
: сопоставлены сMotionEvent.TOOL_TYPE_STYLUS
. -
BTN_TOOL_RUBBER
: Сопоставлено сMotionEvent.TOOL_TYPE_ERASER
. -
BTN_TOOL_BRUSH
: Сопоставлено сMotionEvent.TOOL_TYPE_STYLUS
. -
BTN_TOOL_PENCIL
: Сопоставлено сMotionEvent.TOOL_TYPE_STYLUS
. -
BTN_TOOL_AIRBRUSH
: Сопоставлено сMotionEvent.TOOL_TYPE_STYLUS
. -
BTN_TOOL_MOUSE
: Сопоставлено сMotionEvent.TOOL_TYPE_MOUSE
. -
BTN_TOOL_LENS
: Сопоставлено сMotionEvent.TOOL_TYPE_MOUSE
. -
BTN_TOOL_DOUBLETAP
,BTN_TOOL_TRIPLETAP
иBTN_TOOL_QUADTAP
: сопоставлены сMotionEvent.TOOL_TYPE_FINGER
.
Инструменты наведения и прикосновения
Инструменты могут либо контактировать с сенсорным устройством, либо находиться в зоне его действия и парить над ним. Не все сенсорные устройства способны распознавать наличие инструмента, парящего над сенсорным устройством. Те, которые это делают, например, дигитайзеры с радиочастотным стилусом, часто способны определять, когда инструмент находится в ограниченном диапазоне от дигитайзера.
Компонент InputReader
различает инструменты, находящиеся под действием нажатия, и инструменты, находящиеся под действием наведения. Аналогично, инструменты, находящиеся под действием нажатия, и инструменты, находящиеся под действием наведения, сообщаются приложениям по-разному.
Инструменты прикосновения передаются приложениям как события прикосновения с помощью MotionEvent.ACTION_DOWN
, MotionEvent.ACTION_MOVE
, MotionEvent.ACTION_DOWN
, MotionEvent.ACTION_POINTER_DOWN
и MotionEvent.ACTION_POINTER_UP
.
Инструменты наведения передаются приложениям как общие события движения с использованием MotionEvent.ACTION_HOVER_ENTER
, MotionEvent.ACTION_HOVER_MOVE
и MotionEvent.ACTION_HOVER_EXIT
.
Требования к драйверам сенсорных устройств
- Драйверы сенсорных устройств должны регистрировать только оси и коды клавиш для поддерживаемых ими осей и кнопок. Регистрация неподдерживаемых осей или кодов клавиш может сбить с толку алгоритм классификации устройств или привести к неправильному определению системой его возможностей. Например, если устройство сообщает код клавиши
BTN_TOUCH
, система предполагает, чтоBTN_TOUCH
всегда используется для указания того, касается ли инструмент экрана. ПоэтомуBTN_TOUCH
не следует использовать для указания того, что инструмент просто находится в зоне действия и завис. - Устройства с одним касанием используют следующие события ввода Linux:
-
ABS_X
: (ОБЯЗАТЕЛЬНО) Сообщает координату X инструмента. -
ABS_Y
: (ОБЯЗАТЕЛЬНО) Сообщает координату Y инструмента. -
ABS_PRESSURE
: (необязательно) Сообщает физическое давление, приложенное к кончику инструмента, или силу сигнала сенсорного контакта. -
ABS_TOOL_WIDTH
: (необязательно) Сообщает площадь поперечного сечения или ширину сенсорного контакта или самого инструмента. -
ABS_DISTANCE
: (необязательно) Сообщает расстояние инструмента от поверхности сенсорного устройства. -
ABS_TILT_X
: (необязательно) Сообщает наклон инструмента относительно поверхности сенсорного устройства вдоль оси X. -
ABS_TILT_Y
: (необязательно) Сообщает наклон инструмента относительно поверхности сенсорного устройства вдоль оси Y. -
BTN_TOUCH
: (ОБЯЗАТЕЛЬНО) Указывает, касается ли инструмент устройства. -
BTN_LEFT
,BTN_RIGHT
,BTN_MIDDLE
,BTN_BACK
,BTN_SIDE
,BTN_FORWARD
,BTN_EXTRA
,BTN_STYLUS
,BTN_STYLUS2
: (необязательно) Сообщает о состояниях кнопок . -
BTN_TOOL_FINGER
,BTN_TOOL_PEN
,BTN_TOOL_RUBBER
,BTN_TOOL_BRUSH
,BTN_TOOL_PENCIL
,BTN_TOOL_AIRBRUSH
,BTN_TOOL_MOUSE
,BTN_TOOL_LENS
,BTN_TOOL_DOUBLETAP
,BTN_TOOL_TRIPLETAP
,BTN_TOOL_QUADTAP
: (необязательно) Сообщает тип инструмента .
-
- Мультисенсорные устройства используют следующие события ввода Linux:
-
ABS_MT_POSITION_X
: (ОБЯЗАТЕЛЬНО) Сообщает координату X инструмента. -
ABS_MT_POSITION_Y
: (ОБЯЗАТЕЛЬНО) Сообщает координату Y инструмента. -
ABS_MT_PRESSURE
: (необязательно) Сообщает физическое давление, приложенное к кончику инструмента, или силу сигнала сенсорного контакта. -
ABS_MT_TOUCH_MAJOR
: (необязательно) Сообщает площадь поперечного сечения сенсорного контакта или длину более длинного измерения сенсорного контакта. -
ABS_MT_TOUCH_MINOR
: (необязательно) Сообщает длину наименьшего измерения сенсорного контакта. Эту ось не следует использовать, еслиABS_MT_TOUCH_MAJOR
сообщает измерение площади. -
ABS_MT_WIDTH_MAJOR
: (необязательно) Сообщает площадь поперечного сечения самого инструмента или длину его наибольшей стороны. Не используйте эту ось, если вам неизвестны размеры самого инструмента. -
ABS_MT_WIDTH_MINOR
: (необязательно) Сообщает длину наименьшего размера самого инструмента. Эту ось не следует использовать, еслиABS_MT_WIDTH_MAJOR
сообщает об измерении площади или если размеры самого инструмента неизвестны. -
ABS_MT_ORIENTATION
: (необязательно) Сообщает ориентацию инструмента. -
ABS_MT_DISTANCE
: (необязательно) Сообщает расстояние инструмента от поверхности сенсорного устройства. -
ABS_MT_TOOL_TYPE
: (необязательно) Сообщает тип инструмента какMT_TOOL_FINGER
илиMT_TOOL_PEN
. -
ABS_MT_TRACKING_ID
: (необязательно) Сообщает идентификатор отслеживания инструмента. Идентификатор отслеживания — это произвольное неотрицательное целое число, используемое для независимой идентификации и отслеживания каждого инструмента при использовании нескольких инструментов. Например, при касании устройства несколькими пальцами каждому пальцу должен быть назначен отдельный идентификатор отслеживания, который будет использоваться до тех пор, пока палец остается в контакте. Идентификаторы отслеживания можно использовать повторно, когда соответствующие инструменты выходят за пределы диапазона. -
ABS_MT_SLOT
: (необязательно) Сообщает идентификатор слота инструмента при использовании протокола мультитач Linux «B». Подробнее см. в документации по протоколу мультитач Linux. -
BTN_TOUCH
: (ОБЯЗАТЕЛЬНО) Указывает, касается ли инструмент устройства. -
BTN_LEFT
,BTN_RIGHT
,BTN_MIDDLE
,BTN_BACK
,BTN_SIDE
,BTN_FORWARD
,BTN_EXTRA
,BTN_STYLUS
,BTN_STYLUS2
: (необязательно) Сообщает о состояниях кнопок . -
BTN_TOOL_FINGER
,BTN_TOOL_PEN
,BTN_TOOL_RUBBER
,BTN_TOOL_BRUSH
,BTN_TOOL_PENCIL
,BTN_TOOL_AIRBRUSH
,BTN_TOOL_MOUSE
,BTN_TOOL_LENS
,BTN_TOOL_DOUBLETAP
,BTN_TOOL_TRIPLETAP
,BTN_TOOL_QUADTAP
: (необязательно) Сообщает тип инструмента .
-
- Если определены оси как для протокола одиночного касания, так и для протокола множественного касания, то используются только оси множественного касания, а оси единичного касания игнорируются.
Минимальные и максимальные значения осей
ABS_X
,ABS_Y
,ABS_MT_POSITION_X
иABS_MT_POSITION_Y
определяют границы активной области устройства в единицах измерения поверхности, характерных для данного устройства. В случае сенсорного экрана активная область описывает ту часть сенсорного устройства, которая фактически покрывает дисплей.Для сенсорного экрана система автоматически интерполирует сообщаемые позиции касания в единицах поверхности для получения позиций касания в пикселях дисплея в соответствии со следующим расчетом:
displayX = (x - minX) * displayWidth / (maxX - minX + 1) displayY = (y - minY) * displayHeight / (maxY - minY + 1)
Сенсорный экран может сообщать о касаниях за пределами активной области.
Касания, инициированные за пределами активной области, не передаются приложениям, но могут использоваться для виртуальных клавиш.
Касания, инициированные внутри активной области, а также входящие и выходящие из области отображения, передаются приложениям. Следовательно, если касание начинается в пределах приложения, а затем выходит за пределы активной области, приложение может получать события касания с отрицательными координатами отображения или выходящими за границы дисплея. Это ожидаемое поведение.
Сенсорное устройство никогда не должно ограничивать координаты касания границами активной области. Если касание выходит за пределы активной области, оно должно быть зафиксировано как находящееся за её пределами, или не должно быть зафиксировано вообще.
Например, если палец пользователя касается экрана в районе верхнего левого угла, он может сообщить координаты (minX, minY). Если палец продолжает двигаться дальше за пределы активной области, сенсорный экран должен либо начать сообщать координаты с компонентами, меньшими minX и minY, например (minX - 2, minY - 3), либо полностью прекратить сообщать о касании. Другими словами, сенсорный экран не должен сообщать координаты (minX, minY), когда палец пользователя действительно касается экрана за пределами активной области.
Привязка координат касания к краю дисплея создает искусственную жесткую границу по краю экрана, что не позволяет системе плавно отслеживать движения, входящие или выходящие за пределы области отображения.
Значения, сообщаемые
ABS_PRESSURE
илиABS_MT_PRESSURE
, если они вообще сообщаются, должны быть ненулевыми, когда инструмент касается устройства, и нулевыми в противном случае, чтобы указать, что инструмент завис.Сообщать информацию о давлении необязательно , но настоятельно рекомендуется. Приложения могут использовать эту информацию для реализации рисования с учётом давления и других эффектов.
Значения, возвращаемые
ABS_TOOL_WIDTH
,ABS_MT_TOUCH_MAJOR
,ABS_MT_TOUCH_MINOR
,ABS_MT_WIDTH_MAJOR
илиABS_MT_WIDTH_MINOR
, должны быть ненулевыми, когда инструмент касается устройства, и нулевыми в противном случае, но это не обязательно. Например, сенсорное устройство может измерять размер касаний пальцем, но не стилусом.Сообщать информацию о размере необязательно , но настоятельно рекомендуется. Приложения могут использовать информацию о нажиме для реализации рисования с учётом размера и других эффектов.
Значения, возвращаемые
ABS_DISTANCE
илиABS_MT_DISTANCE
должны стремиться к нулю при касании инструмента устройства. Расстояние может оставаться отличным от нуля даже при прямом контакте инструмента. Точные значения зависят от способа измерения расстояния оборудованием.Предоставление информации о расстоянии необязательно , но рекомендуется для устройств со стилусом.
Значения
ABS_TILT_X
иABS_TILT_Y
должны быть равны нулю, когда инструмент расположен перпендикулярно устройству. Наклон, отличный от нуля, указывает на то, что инструмент находится под наклоном.Углы наклона по осям X и Y задаются в градусах от перпендикуляра. Центральная точка (абсолютно перпендикулярная) определяется как
(max + min) / 2
для каждой оси. Значения, меньшие, чем центральная точка, соответствуют наклону вверх или влево, значения, большие, чем центральная точка, соответствуют наклону вниз или вправо.InputReader
преобразует компоненты наклона по осям X и Y в перпендикулярный угол наклона в диапазоне от 0 доPI / 2
радиан и угол ориентации в плоскости в диапазоне от-PI
доPI
радиан. Это представление приводит к описанию ориентации, совместимому с описанием прикосновений пальцев.Предоставление информации о наклоне не является обязательным , но рекомендуется для устройств со стилусом.
Если тип инструмента указан в
ABS_MT_TOOL_TYPE
, он заменяет любую информацию о типе инструмента, указанную вBTN_TOOL_*
. Если информация о типе инструмента отсутствует, по умолчанию используется типMotionEvent.TOOL_TYPE_FINGER
.Инструмент определяется как активный на основании следующих условий:
При использовании протокола одного касания инструмент активен, если
BTN_TOUCH
илиBTN_TOOL_*
равен 1.Это условие подразумевает, что
InputReader
должен иметь хотя бы некоторую информацию о природе инструмента: касается ли он объекта или, по крайней мере, его тип. Если информация отсутствует, инструмент считается неактивным (вне диапазона).- При использовании протокола мультитач «A» инструмент активен всегда, когда он появляется в последнем отчёте синхронизации. Когда инструмент перестаёт появляться в отчётах синхронизации, он перестаёт существовать.
- При использовании протокола мультитач «B» инструмент активен, пока у него есть активный слот. После освобождения слота инструмент перестаёт существовать.
- Инструмент определяется как зависший на основании следующих условий:
- Если инструмент —
BTN_TOOL_MOUSE
илиBTN_TOOL_LENS
, то инструмент не зависает, даже если выполняется любое из следующих условий. - Если инструмент активен и водитель сообщает информацию о давлении, а сообщаемое давление равно нулю, то инструмент завис.
- Если инструмент активен и драйвер поддерживает код клавиши
BTN_TOUCH
, аBTN_TOUCH
имеет значение ноль, то инструмент зависает.
- Если инструмент —
-
InputReader
поддерживает оба протокола мультитач: A и B. Новые драйверы должны использовать протокол B, но работает любой из них. Начиная с Android 4.0, может потребоваться изменение драйверов сенсорного экрана для соответствия спецификации протокола ввода Linux.
Могут потребоваться следующие изменения:
Когда инструмент становится неактивным (палец поднят вверх), он должен перестать отображаться в последующих отчётах синхронизации мультисенсорных устройств. Когда все инструменты становятся неактивными (все пальцы подняты вверх), драйвер должен отправить пустой пакет отчёта синхронизации, например,
SYN_MT_REPORT
, а затемSYN_REPORT
.В предыдущих версиях Android события «вверх» ожидались путем отправки значения давления, равного 0. Старое поведение было несовместимо со спецификацией протокола ввода Linux и больше не поддерживается.
Информацию о физическом давлении или силе сигнала следует сообщать с помощью
ABS_MT_PRESSURE
.Предыдущие версии Android получали информацию о давлении из
ABS_MT_TOUCH_MAJOR
. Старое поведение было несовместимо со спецификацией протокола ввода Linux и больше не поддерживается.- Информацию о размере сенсорного экрана следует сообщать с помощью
ABS_MT_TOUCH_MAJOR
.Предыдущие версии Android получали информацию о размере из
ABS_MT_TOOL_MAJOR
. Старое поведение было несовместимо со спецификацией протокола ввода Linux и больше не поддерживается.
Управление сенсорным устройством
Ниже приведен краткий обзор работы сенсорного устройства на базе Android.
-
EventHub
считывает необработанные события из драйвераevdev
. -
InputReader
получает необработанные события и обновляет внутреннее состояние положения и других характеристик каждого инструмента. Он также отслеживает состояния кнопок. - Если была нажата или отпущена клавиша BACK или FORWARD ,
InputReader
уведомляетInputDispatcher
о событии клавиши. -
InputReader
определяет, произошло ли нажатие виртуальной клавиши. Если да, он уведомляетInputDispatcher
о событии нажатия клавиши. -
InputReader
определяет, было ли касание инициировано в пределах экрана. Если да, он уведомляетInputDispatcher
о событии касания. - Если нет соприкасающихся инструментов, но есть хотя бы один наведенный инструмент,
InputReader
уведомляетInputDispatcher
о событии наведения. - Если тип сенсорного устройства — указатель ,
InputReader
выполняет обнаружение жеста указателя, перемещает указатель и точки соответствующим образом и уведомляетInputDispatcher
о событии указателя. -
InputDispatcher
используетWindowManagerPolicy
для определения необходимости отправки событий и необходимости пробуждения устройства. ЗатемInputDispatcher
доставляет события соответствующим приложениям.
Конфигурация сенсорного устройства
Поведение сенсорного устройства определяется осями устройства, кнопками, свойствами ввода, конфигурацией устройства ввода, картой виртуальных клавиш и расположением клавиш.
Более подробную информацию о файлах, участвующих в настройке клавиатуры, можно найти в следующих разделах:
Характеристики
Система использует множество свойств конфигурации устройства ввода для настройки и калибровки поведения сенсорного устройства.
Одной из причин этого является то, что драйверы сенсорных устройств часто сообщают характеристики касаний, используя единицы измерения, специфичные для данного устройства.
Например, многие сенсорные устройства измеряют площадь контакта с сенсором, используя собственную шкалу, специфичную для данного устройства, например, общее количество сенсорных узлов, активированных касанием. Это необработанное значение размера не будет иметь смысла для приложений, поскольку им необходимо знать физический размер и другие характеристики сенсорных узлов сенсорного устройства.
Система использует параметры калибровки, закодированные в файлах конфигурации устройства ввода, для декодирования, преобразования и нормализации значений, сообщаемых сенсорным устройством, в более простое стандартное представление, понятное приложениям.
Соглашения о документации
В целях документирования мы используем следующие условные обозначения для описания значений, используемых системой в процессе калибровки.
Исходные значения осей
Следующие выражения обозначают необработанные значения, сообщаемые драйвером сенсорного устройства как события EV_ABS
.
-
raw.x
- Значение оси
ABS_X
илиABS_MT_POSITION_X
. -
raw.y
- Значение оси
ABS_Y
илиABS_MT_POSITION_Y
. -
raw.pressure
- Значение оси
ABS_PRESSURE
илиABS_MT_PRESSURE
, или 0, если недоступно. -
raw.touchMajor
- Значение оси
ABS_MT_TOUCH_MAJOR
или 0, если недоступно. -
raw.touchMinor
- Значение оси
ABS_MT_TOUCH_MINOR
илиraw.touchMajor
, если оно недоступно. -
raw.toolMajor
- Значение оси
ABS_TOOL_WIDTH
илиABS_MT_WIDTH_MAJOR
, или 0, если недоступно. -
raw.toolMinor
- Значение оси
ABS_MT_WIDTH_MINOR
илиraw.toolMajor
, если оно недоступно. -
raw.orientation
- Значение оси
ABS_MT_ORIENTATION
или 0, если недоступно. -
raw.distance
- Значение оси
ABS_DISTANCE
илиABS_MT_DISTANCE
, или 0, если недоступно. -
raw.tiltX
- Значение оси
ABS_TILT_X
или 0, если недоступно. -
raw.tiltY
- Значение оси
ABS_TILT_Y
или 0, если недоступно.
Диапазоны необработанных осей
Следующие выражения определяют границы исходных значений. Они получаются путем вызова ioctl-функции EVIOCGABS
для каждой оси.
-
raw.*.min
- Минимальное включенное значение исходной оси.
-
raw.*.max
- Максимальное значение необработанной оси.
-
raw.*.range
- Эквивалентно
raw.*.max - raw.*.min
. -
raw.*.fuzz
- Точность необработанной оси. Например, fuzz = 1 подразумевает, что значения имеют точность +/- 1 единица.
-
raw.width
- Общая ширина сенсорной области, эквивалентная
raw.x.range + 1
. -
raw.height
- Высота сенсорной области (включая ее), эквивалентная
raw.y.range + 1
.
Выходные диапазоны
Следующие выражения определяют характеристики выходной системы координат. Система использует линейную интерполяцию для перевода информации о положении касания из единиц измерения поверхности, используемых сенсорным устройством, в выходные единицы, которые передаются приложениям, например, в пиксели дисплея.
-
output.width
- Ширина выходного изображения. Для сенсорных экранов (связанных с дисплеем) это ширина изображения в пикселях. Для сенсорных панелей (не связанных с дисплеем) ширина выходного изображения равна
raw.width
, что означает, что интерполяция не выполняется. -
output.height
- Высота вывода. Для сенсорных экранов (связанных с дисплеем) это высота отображения в пикселях. Для сенсорных панелей (не связанных с дисплеем) высота вывода равна
raw.height
, что означает, что интерполяция не выполняется. -
output.diag
- Длина диагонали выходной системы координат, эквивалентная
sqrt(output.width ^2 + output.height ^2)
.
Базовая конфигурация
Сенсорный преобразователь сенсорного ввода использует множество свойств конфигурации из файла конфигурации устройства ввода для задания значений калибровки. В следующей таблице описаны некоторые общие свойства конфигурации. Все остальные свойства описаны в следующих разделах вместе с полями, которые они используют для калибровки.
тип сенсорного устройства
Определение: touch.deviceType
= touchScreen
| touchPad
| pointer
| default
Указывает тип сенсорного устройства.
Если значение равно
touchScreen
, то сенсорное устройство представляет собой сенсорный экран, связанный с дисплеем.Если значение равно
touchPad
, сенсорное устройство представляет собой сенсорную панель, не связанную с дисплеем.Если значение равно
pointer
, сенсорное устройство представляет собой сенсорную панель, не связанную с дисплеем, а ее движения используются для косвенных многосенсорных жестов указателя .Если установлено значение
default
, система автоматически определяет тип устройства в соответствии с алгоритмом классификации.
Более подробную информацию о том, как тип устройства влияет на поведение сенсорного устройства, см. в разделе «Классификация» .
В Android 3 и ниже все сенсорные устройства предполагались как сенсорные экраны.
touch.orientationAware
Определение: touch.orientationAware
= 0
| 1
Указывает, должно ли сенсорное устройство реагировать на изменение ориентации дисплея.
Если значение равно
1
, позиции касания, сообщаемые сенсорным устройством, поворачиваются при каждом изменении ориентации дисплея.Если значение равно
0
, позиции касания, сообщаемые сенсорным устройством, не подвержены изменениям ориентации дисплея.
Значение по умолчанию — 1
если устройство имеет сенсорный экран, в противном случае 0
.
Система различает внутренние и внешние сенсорные экраны и дисплеи. Внутренний сенсорный экран с распознаванием ориентации поворачивается в зависимости от ориентации внутреннего дисплея. Внешний сенсорный экран с распознаванием ориентации поворачивается в зависимости от ориентации внешнего дисплея.
Распознавание ориентации используется для поддержки поворота сенсорных экранов на таких устройствах, как Nexus One. Например, при повороте устройства по часовой стрелке на 90 градусов от его естественной ориентации абсолютные координаты касаний переопределяются таким образом, что касание в верхнем левом углу абсолютной системы координат сенсорного экрана регистрируется как касание в верхнем левом углу повёрнутой системы координат дисплея. Это сделано для того, чтобы касания регистрировались в той же системе координат, которую приложения используют для отрисовки своих визуальных элементов.
До появления Honeycomb предполагалось, что все сенсорные устройства распознают ориентацию.
touch.gestureMode
Определение: touch.gestureMode
= pointer
| spots
| default
Задаёт режим представления для жестов указателя. Это свойство конфигурации актуально только для сенсорных устройств типа «указатель» .
Если значение равно
pointer
, жесты сенсорной панели представлены в виде курсора, похожего на указатель мыши.Если значение равно
spots
, жесты сенсорной панели представлены якорем, который представляет собой центроид жеста, и набором круглых точек, которые представляют положение отдельных пальцев.
Значение по умолчанию — pointer
, если задано свойство ввода INPUT_PROP_SEMI_MT
, в противном случае — spots
.
Поля X и Y
Поля X и Y предоставляют позиционную информацию для центра контактной области.
Расчет
Расчет прост: позиционная информация от сенсорного драйвера линейно интерполируется в выходную систему координат.
xScale = output.width / raw.width yScale = output.height / raw.height If not orientation aware or screen rotation is 0 degrees: output.x = (raw.x - raw.x.min) * xScale output.y = (raw.y - raw.y.min) * yScale Else If rotation is 90 degrees: output.x = (raw.y - raw.y.min) * yScale output.y = (raw.x.max - raw.x) * xScale Else If rotation is 180 degrees: output.x = (raw.x.max - raw.x) * xScale output.y = (raw.y.max - raw.y) * yScale Else If rotation is 270 degrees: output.x = (raw.y.max - raw.y) * yScale output.y = (raw.x - raw.x.min) * xScale End If
touchMajor, touchMinor, toolMajor, toolMinor, поля размера
Поля touchMajor
и touchMinor
описывают приблизительные размеры области контакта в выходных единицах (пикселях).
Поля toolMajor
и toolMinor
описывают приблизительные размеры самого инструмента в выходных единицах (пикселях).
Поле size
описывает нормализованный размер касания относительно максимально возможного касания, которое может распознать сенсорное устройство. Наименьший возможный нормализованный размер равен 0,0 (контакт отсутствует или измерение невозможно), а наибольший возможный нормализованный размер равен 1,0 (область сенсора заполнена).
Если можно измерить и приблизительную длину, и приблизительную ширину, поле touchMajor
определяет большую сторону, а поле touchMinor
— меньшую сторону контактной области. Если можно измерить только приблизительный диаметр контактной области, поля touchMajor
и touchMinor
равны.
Аналогично, поле toolMajor
определяет больший размер, а поле toolMinor
определяет меньший размер площади поперечного сечения инструмента.
Если размер касания недоступен, но доступен размер инструмента, то размер инструмента устанавливается равным размеру касания. И наоборот, если размер инструмента недоступен, но доступен размер касания, то размер касания устанавливается равным размеру инструмента.
Сенсорные устройства измеряют или сообщают размер касания и размер инструмента различными способами. Текущая реализация поддерживает три различных типа измерений: диаметр, площадь и геометрическую ограничивающую рамку в единицах измерения поверхности.
Определение: touch.size.calibration
= none
| geometric
| diameter
| area
| default
Указывает тип измерения, используемый драйвером сенсора для определения размера касания и размера инструмента.
Если значение равно
none
, размер устанавливается равным нулю.Если значение является
geometric
, предполагается, что размер указан в тех же единицах измерения поверхности, что и положение, поэтому он масштабируется таким же образом.Если значение равно
diameter
, размер считается пропорциональным диаметру (ширине) прикосновения или инструмента.Если значение равно
area
, размер считается пропорциональным площади касания или инструмента.Если задано значение
default
, система используетgeometric
калибровку, если доступна осьraw.touchMajor
илиraw.toolMajor
, в противном случае используетсяnone
калибровки.
сенсорный.размер.масштаб
Определение: touch.size.scale
= <неотрицательное число с плавающей точкой>
Задает постоянный масштабный коэффициент, используемый при калибровке.
Значение по умолчанию — 1.0
.
сенсорный.размер.предвзятость
Определение: touch.size.bias
= <неотрицательное число с плавающей точкой>
Задает постоянное значение смещения, используемое при калибровке.
Значение по умолчанию — 0.0
.
touch.size.isSummed
Определение: touch.size.isSummed
= 0
| 1
Указывает, указывается ли размер как сумма размеров всех активных контактов или указывается отдельно для каждого контакта.
Если значение равно
1
, сообщаемый размер делится на количество контактов до использования.Если значение равно
0
, указанный размер используется как есть.
Значение по умолчанию — 0
.
Некоторые сенсорные устройства, особенно устройства «Semi-MT», не различают отдельные размеры нескольких контактов, поэтому они сообщают размер, представляющий их общую площадь или ширину. Для таких устройств это свойство следует устанавливать только равным 1
В случае сомнений установите значение 0
.
Расчет
Расчет полей touchMajor
, touchMinor
, toolMajor
, toolMinor
и size
зависит от указанных параметров калибровки.
If raw.touchMajor and raw.toolMajor are available: touchMajor = raw.touchMajor touchMinor = raw.touchMinor toolMajor = raw.toolMajor toolMinor = raw.toolMinor Else If raw.touchMajor is available: toolMajor = touchMajor = raw.touchMajor toolMinor = touchMinor = raw.touchMinor Else If raw.toolMajor is available: touchMajor = toolMajor = raw.toolMajor touchMinor = toolMinor = raw.toolMinor Else touchMajor = toolMajor = 0 touchMinor = toolMinor = 0 size = 0 End If size = avg(touchMajor, touchMinor) If touch.size.isSummed == 1: touchMajor = touchMajor / numberOfActiveContacts touchMinor = touchMinor / numberOfActiveContacts toolMajor = toolMajor / numberOfActiveContacts toolMinor = toolMinor / numberOfActiveContacts size = size / numberOfActiveContacts End If If touch.size.calibration == "none": touchMajor = toolMajor = 0 touchMinor = toolMinor = 0 size = 0 Else If touch.size.calibration == "geometric": outputScale = average(output.width / raw.width, output.height / raw.height) touchMajor = touchMajor * outputScale touchMinor = touchMinor * outputScale toolMajor = toolMajor * outputScale toolMinor = toolMinor * outputScale Else If touch.size.calibration == "area": touchMajor = sqrt(touchMajor) touchMinor = touchMajor toolMajor = sqrt(toolMajor) toolMinor = toolMajor Else If touch.size.calibration == "diameter": touchMinor = touchMajor toolMinor = toolMajor End If If touchMajor != 0: output.touchMajor = touchMajor * touch.size.scale + touch.size.bias Else output.touchMajor = 0 End If If touchMinor != 0: output.touchMinor = touchMinor * touch.size.scale + touch.size.bias Else output.touchMinor = 0 End If If toolMajor != 0: output.toolMajor = toolMajor * touch.size.scale + touch.size.bias Else output.toolMajor = 0 End If If toolMinor != 0: output.toolMinor = toolMinor * touch.size.scale + touch.size.bias Else output.toolMinor = 0 End If output.size = size
поле давления
Поле pressure
описывает приблизительное физическое давление, прилагаемое к сенсорному устройству, как нормализованное значение между 0,0 (нет касания) и 1,0 (нормальное давление).
Нулевое давление указывает на то, что инструмент завис.
калибровка.сенсорного.давления
Определение: touch.pressure.calibration
= none
| physical
| amplitude
| default
Указывает тип измерения, используемый драйвером сенсора для определения давления.
Если значение равно
none
, давление неизвестно, поэтому оно устанавливается равным 1,0 при касании и 0,0 при наведении.Если значение
physical
, предполагается, что ось давления измеряет фактическую физическую интенсивность давления, прилагаемого к сенсорной панели.Если значение равно
amplitude
, предполагается, что ось давления измеряет амплитуду сигнала, которая связана с размером контакта и приложенным давлением.If the value is
default
, the system uses thephysical
calibration if the pressure axis available, otherwise usesnone
.
touch.pressure.scale
Definition: touch.pressure.scale
= <a non-negative floating point number>
Specifies a constant scale factor used in the calibration.
The default value is 1.0 / raw.pressure.max
.
Расчет
The calculation of the pressure
field depends on the specified calibration parameters.
If touch.pressure.calibration == "physical" or "amplitude": output.pressure = raw.pressure * touch.pressure.scale Else If hovering: output.pressure = 0 Else output.pressure = 1 End If End If
orientation and tilt fields
The orientation
field describes the orientation of the touch and tool as an angular measurement. An orientation of 0
indicates that the major axis is oriented vertically, -PI/2
indicates that the major axis is oriented to the left, PI/2
indicates that the major axis is oriented to the right. When a stylus tool is present, the orientation range can be described in a full circle range from -PI
or PI
.
The tilt
field describes the inclination of the tool as an angular measurement. A tilt of 0
indicates that the tool is perpendicular to the surface. A tilt of PI/2
indicates that the tool is flat on the surface.
touch.orientation.calibration
Definition: touch.orientation.calibration
= none
| interpolated
| vector
| default
Specifies the kind of measurement used by the touch driver to report the orientation.
- If the value is
none
, the orientation is unknown so it is set to 0. - If the value is
interpolated
, the orientation is linearly interpolated such that a raw value ofraw.orientation.min
maps to-PI/2
and a raw value ofraw.orientation.max
maps toPI/2
. The center value of(raw.orientation.min + raw.orientation.max) / 2
maps to0
. - If the value is
vector
, the orientation is interpreted as a packed vector consisiting of two signed 4-bit fields. This representation is used on Atmel Object Based Protocol parts. When decoded, the vector yields an orientation angle and confidence magnitude. The confidence magnitude is used to scale the size information, unless it is geometric. - If the value is
default
, the system uses theinterpolated
calibration if the orientation axis available, otherwise usesnone
.
Расчет
The calculation of the orientation
and tilt
fields depends on the specified calibration parameters and available input.
If touch.tiltX and touch.tiltY are available: tiltXCenter = average(raw.tiltX.min, raw.tiltX.max) tiltYCenter = average(raw.tiltY.min, raw.tiltY.max) tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180 tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180 output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle)) output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle)) Else If touch.orientation.calibration == "interpolated": center = average(raw.orientation.min, raw.orientation.max) output.orientation = PI / (raw.orientation.max - raw.orientation.min) output.tilt = 0 Else If touch.orientation.calibration == "vector": c1 = (raw.orientation & 0xF0) >> 4 c2 = raw.orientation & 0x0F If c1 != 0 or c2 != 0: If c1 >= 8 Then c1 = c1 - 16 If c2 >= 8 Then c2 = c2 - 16 angle = atan2(c1, c2) / 2 confidence = sqrt(c1*c1 + c2*c2) output.orientation = angle If touch.size.calibration == "diameter" or "area": scale = 1.0 + confidence / 16 output.touchMajor *= scale output.touchMinor /= scale output.toolMajor *= scale output.toolMinor /= scale End If Else output.orientation = 0 End If output.tilt = 0 Else output.orientation = 0 output.tilt = 0 End If If orientation aware: If screen rotation is 90 degrees: output.orientation = output.orientation - PI / 2 Else If screen rotation is 270 degrees: output.orientation = output.orientation + PI / 2 End If End If
distance field
The distance
field describes the distance between the tool and the touch device surface. A value of 0.0 indicates direct contact and larger values indicate increasing distance from the surface.
touch.distance.calibration
Definition: touch.distance.calibration
= none
| scaled
| default
Specifies the kind of measurement used by the touch driver to report the distance.
If the value is
none
, the distance is unknown so it is set to 0.If the value is
scaled
, the reported distance is multiplied by a constant scale factor.If the value is
default
, the system uses thescaled
calibration if the distance axis available, otherwise usesnone
.
touch.distance.scale
Definition: touch.distance.scale
= <a non-negative floating point number>
Specifies a constant scale factor used in the calibration.
The default value is 1.0
.
Расчет
The calculation of the distance
field depends on the specified calibration parameters.
If touch.distance.calibration == "scaled": output.distance = raw.distance * touch.distance.scale Else output.distance = 0 End If
Пример
# Input device configuration file for a touch screen that supports pressure, # size and orientation. The pressure and size scale factors were obtained # by measuring the characteristics of the device itself and deriving # useful approximations based on the resolution of the touch sensor and the # display. # # Note that these parameters are specific to a particular device model. # Different parameters need to be used for other devices. # Basic Parameters touch.deviceType = touchScreen touch.orientationAware = 1 # Size # Based on empirical measurements, we estimate the size of the contact # using size = sqrt(area) * 28 + 0. touch.size.calibration = area touch.size.scale = 28 touch.size.bias = 0 touch.size.isSummed = 0 # Pressure # Driver reports signal strength as pressure. # # A normal index finger touch typically registers about 80 signal strength # units although we don't expect these values to be accurate. touch.pressure.calibration = amplitude touch.pressure.scale = 0.0125 # Orientation touch.orientation.calibration = vector
Примечания о совместимости
The configuration properties for touch devices changed significantly in Android Ice Cream Sandwich 4.0. All input device configuration files for touch devices must be updated to use the new configuration properties.
Older touch device drivers might also need to be updated.
Virtual key map files
Touch devices can be used to implement virtual keys.
There are several ways of doing this, depending on the capabilities of the touch controller. Some touch controllers can be directly configured to implement soft keys by setting firmware registers. Other times it is desirable to perform the mapping from touch coordinates to key codes in software.
When virtual keys are implemented in software, the kernel must export a virtual key map file called virtualkeys.<devicename>
as a board property. For example, if the touch screen device drivers reports its name as "touchyfeely" then the virtual key map file must have the path /sys/board_properties/virtualkeys.touchyfeely
.
A virtual key map file describes the coordinates and Linux key codes of virtual keys on the touch screen.
In addition to the virtual key map file, there must be a corresponding key layout file and key character map file to map the Linux key codes to Android key codes and to specify the type of the keyboard device (usually SPECIAL_FUNCTION
).
Синтаксис
A virtual key map file is a plain text file consisting of a sequence of virtual key layout descriptions either separated by newlines or by colons.
Comment lines begin with '#' and continue to the end of the line.
Each virtual key is described by 6 colon-delimited components:
-
0x01
: A version code. Must always be0x01
. - <Linux key code>: The Linux key code of the virtual key.
- <centerX>: The X pixel coordinate of the center of the virtual key.
- <centerY>: The Y pixel coordinate of the center of the virtual key.
- <width>: The width of the virtual key in pixels.
- <height>: The height of the virtual key in pixels.
All coordinates and sizes are specified in terms of the display coordinate system.
Here is a virtual key map file all written on one line.
# All on one line 0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55
The same virtual key map file can also be written on multiple lines.
# One key per line 0x01:158:55:835:90:55 0x01:139:172:835:125:55 0x01:102:298:835:115:55 0x01:217:412:835:95:55
In the above example, the touch screen has a resolution of 480x800. Accordingly, all of the virtual keys have a <centerY> coordinate of 835, which is a little bit below the visible area of the touch screen.
The first key has a Linux scan code of 158
( KEY_BACK
), centerX of 55
, centerY of 835
, width of 90
, and height of 55
.
Пример
Virtual key map file: /sys/board_properties/virtualkeys.touchyfeely
.
0x01:158:55:835:90:55 0x01:139:172:835:125:55 0x01:102:298:835:115:55 0x01:217:412:835:95:55
Key layout file: /system/usr/keylayout/touchyfeely.kl
.
key 158 BACK key 139 MENU key 172 HOME key 217 SEARCH
Key character map file: /system/usr/keychars/touchyfeely.kcm
.
type SPECIAL_FUNCTION
Indirect multi-touch pointer gestures
In pointer mode, the system interprets the following gestures:
- Single finger tap: click.
- Single finger motion: move the pointer.
- Single finger motion plus button presses: drag the pointer.
- Two finger motion both fingers moving in the same direction: drag the area under the pointer in that direction. The pointer itself does not move.
- Two finger motion both fingers moving towards each other or apart in different directions: pan/scale/rotate the area surrounding the pointer. The pointer itself does not move.
- Multiple finger motion: freeform gesture.
Palm rejection
As of Android 13, the system can automatically reject inputs from palms when the built-in framework is enabled. In-house, custom-built solutions are still supported, though they might need to be modified to return the TOOL_TYPE_PALM
flag when a palm is detected. The built-in framework also works in conjunction with custom solutions.
The actual model looks at the first 90 ms of gesture data, at the current pointer, and at the surrounding pointers, then considers how far away from the display edge the touches are. It then determines, on a per-pointer basis, which of the pointers are palms. It also takes into account the size of each contact, as reported by touchMajor
and touchMinor
. The Android framework then removes the pointers that are marked as palms from the touch stream.
If a pointer was already sent to the apps, then the system either:
- (If there are other active pointers) Cancels the pointer with
ACTION_POINTER_UP
andFLAG_CANCELED
set. - (If this is the only pointer) Cancels the pointer with
ACTION_CANCEL
.
A public API, MotionEvent.FLAG_CANCELED
, indicates that the current event shouldn't trigger user action. This flag is set for both ACTION_CANCEL
and ACTION_POINTER_UP
.
If the palm pointer wasn't sent to apps, then the system simply drops the pointer.
Enable palm rejection
- In your touch driver, use the
input_abs_set_res
macro to set the resolutions for the following fields (units are pixels per mm ):-
ABS_MT_POSITION_X
-
ABS_MT_POSITION_Y
-
ABS_MT_TOUCH_MAJOR
-
ABS_MT_TOUCH_MINOR
Support for
ABS_MT_TOUCH_MINOR
is optional. However, if your device does support it, make sure the resolution is set correctly. -
- To confirm the fields are set correctly, run:
$ adb shell getevent -li
- To enable the feature during runtime, run:
$ adb shell device_config put input_native_boot palm_rejection_enabled 1
- Restart the
system_server
process.$ adb shell stop && adb shell start
- Confirm that
adb shell dumpsys input
shows that there are palm rejectors insideUnwantedInteractionBlocker
. If it doesn't, check the input-related logs to find clues on what might be misconfigured.See the following example for reference:
UnwantedInteractionBlocker: mEnablePalmRejection: true isPalmRejectionEnabled (flag value): true mPalmRejectors: deviceId = 3: mDeviceInfo: max_x =
max_y = x_res = 11.00 y_res = 11.00 major_radius_res = 1.00 minor_radius_res = 1.00 minor_radius_supported = true touch_major_res = 1 touch_minor_res = 1 mSlotState: mSlotsByPointerId: mPointerIdsBySlot: mSuppressedPointerIds: {} - To permanently enable the feature, add the corresponding sysprop command in your
init**rc
file:setprop persist.device_config.input_native_boot.palm_rejection_enabled 1