Android поддерживает различные сенсорные экраны и сенсорные панели, включая планшеты-дигитайзеры на основе стилуса.
Сенсорные экраны – это сенсорные устройства, связанные с дисплеем, которые позволяют пользователю напрямую управлять элементами на экране.
Сенсорные панели – это сенсорные устройства, не связанные с экраном, например графический планшет. Сенсорные панели обычно используются для указания, абсолютного непрямого позиционирования или управления пользовательским интерфейсом с помощью жестов.
На сенсорных устройствах могут быть кнопки, выполняющие те же функции, что и кнопки мыши.
В зависимости от технологии сенсорного датчика, сенсорными устройствами можно управлять с помощью различных инструментов, таких как пальцы или стилус.
Сенсорные устройства иногда используются для реализации виртуальных клавиш. Например, на некоторых устройствах Android сенсорная область экрана выходит за его пределы и служит частью сенсорной клавиатуры.
Из-за большого разнообразия сенсорных устройств Android полагается на большое количество свойств конфигурации для описания характеристик и желаемого поведения каждого устройства.
Классификация сенсорных устройств
Устройство ввода классифицируется как устройство с поддержкой мультисенсорного ввода, если выполняются оба следующих условия:
- Устройство ввода сообщает о наличии абсолютных осей
ABS_MT_POSITION_XиABS_MT_POSITION_Y. - На устройстве ввода нет кнопок геймпада. Это условие устраняет неоднозначность с некоторыми геймпадами, которые сообщают об осях с кодами, перекрывающими коды осей MT.
Устройство ввода классифицируется как устройство с одинарным касанием, если выполняются оба следующих условия:
- Устройство ввода не классифицируется как устройство с поддержкой мультисенсорного ввода. Устройство ввода классифицируется как устройство с поддержкой одного касания или мультисенсорное устройство, но не оба одновременно.
- Устройство ввода сообщает о наличии абсолютных осей
ABS_XиABS_Y, а также кода клавишиBTN_TOUCH.
Если устройство ввода классифицируется как сенсорное, наличие виртуальных клавиш определяется путем попытки загрузить файл раскладки виртуальных клавиш для устройства. Если доступна виртуальная раскладка клавиатуры, то также загружается файл раскладки клавиатуры для устройства. Информацию о расположении и формате этих файлов можно найти в разделе [Файлы сопоставления виртуальных клавиш](#virtual-key-map-files).
Затем система загружает файл конфигурации устройства ввода для сенсорного устройства.
У всех встроенных сенсорных устройств должны быть файлы конфигурации устройств ввода. Если файл конфигурации устройства ввода отсутствует, система выбирает конфигурацию по умолчанию, которая подходит для сенсорных периферийных устройств общего назначения, таких как внешние сенсорные экраны или сенсорные панели USB или Bluetooth HID. Эти настройки по умолчанию не предназначены для встроенных сенсорных экранов и могут привести к некорректному поведению.
После загрузки конфигурации устройства ввода система классифицирует его как сенсорный экран, сенсорную панель или указывающее устройство.
- Устройство с сенсорным экраном используется для непосредственного управления объектами на экране. Пользователь напрямую касается экрана, поэтому системе не требуются дополнительные средства для указания объектов, которыми манипулируют.
- Сенсорная панель передает приложению информацию об абсолютном положении касаний в заданной области датчика. Это может быть полезно для графических планшетов.
- Указывающее устройство используется для косвенного управления объектами на экране с помощью курсора. Пальцы интерпретируются как жесты указателя с несколькими касаниями. Другие инструменты, например стилусы, интерпретируются с использованием абсолютных позиций. Подробную информацию вы найдете в разделе Косвенные мультисенсорные жесты.
Для классификации устройства ввода как сенсорного экрана, сенсорной панели или указывающего устройства используются следующие правила.
- Если свойство
touch.deviceTypeзадано, то тип устройства устанавливается в соответствии с ним. - Если устройство ввода сообщает о наличии свойства ввода
INPUT_PROP_DIRECT(через ioctlEVIOCGPROP), то тип устройства устанавливается как сенсорный экран. Это условие предполагает, что сенсорные устройства прямого ввода подключены к дисплею, который также подключен. - Если устройство ввода сообщает о наличии свойства ввода
INPUT_PROP_POINTER(через ioctlEVIOCGPROP), то для типа устройства устанавливается значение pointer. - Если устройство ввода сообщает о наличии относительных осей
REL_XилиREL_Y, то тип устройства устанавливается как сенсорная панель. Это условие устраняет неоднозначность для устройств ввода, состоящих из мыши и сенсорной панели. В этом случае сенсорная панель не используется для управления указателем, поскольку им уже управляет мышь. - В противном случае тип устройства будет задан как pointer. Это значение по умолчанию гарантирует, что сенсорные панели, которым не назначено никакое другое специальное назначение, управляют указателем.
Кнопки
Кнопки – это необязательные элементы управления, которые можно использовать в приложениях для выполнения дополнительных функций. Кнопки на сенсорных устройствах работают так же, как кнопки мыши, и в основном используются с сенсорными устройствами типа указатель или со стилусом.
Поддерживаются следующие кнопки:
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 multi-touch 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.Инструмент считается активным при соблюдении следующих условий:
При использовании протокола Single-touch инструмент активен, если
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 события "up" регистрировались при отправке значения давления, равного 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, если оно недоступно.
Необработанные диапазоны осей
Ниже приведены выражения, обозначающие границы необработанных значений. Они получаются путем вызова EVIOCGABS ioctl для каждой оси.
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
Определение: 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.
-
Если выбрано значение
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, size fields
Поля touchMajor и touchMinor описывают приблизительные размеры области касания в единицах вывода (пикселях).
Поля toolMajor и toolMinor описывают приблизительные размеры самого инструмента в единицах вывода (пикселях).
Поле size описывает нормализованный размер касания относительно самого большого касания, которое может распознать сенсорное устройство. Минимальное возможное нормализованное значение – 0,0 (касания нет или его невозможно измерить), а максимальное – 1,0 (область датчика заполнена).
Если можно измерить приблизительную длину и ширину, то в поле touchMajor указывается больший размер, а в поле touchMinor – меньший размер области контакта. Если можно измерить только приблизительный диаметр области касания, то значения полей touchMajor и touchMinor равны.
Аналогично, поле toolMajor определяет большую сторону, а поле toolMinor – меньшую сторону площади поперечного сечения инструмента.
Если размер касания недоступен, но доступен размер инструмента, то размер инструмента устанавливается равным размеру касания. И наоборот, если размер инструмента недоступен, а размер касания доступен, то размер касания устанавливается равным размеру инструмента.
Сенсорные устройства измеряют и передают размер касания и размер инструмента разными способами. Текущая реализация поддерживает три различных вида измерений: диаметр, площадь и геометрическую ограничивающую рамку в единицах площади.
<touch.size.calibration< h4=""></touch.size.calibration<>
Определение. touch.size.calibration = none |
geometric | diameter
| area | default
Указывает, какой тип измерения используется драйвером сенсорного экрана для передачи данных о размере касания и размере инструмента.
-
Если значение равно
none, размер устанавливается равным нулю. -
Если значение равно
geometric, то предполагается, что размер указан в тех же единицах, что и позиция, поэтому он масштабируется таким же образом. -
Если задано значение
diameter, размер считается пропорциональным диаметру (ширине) касания или инструмента. -
Если значение равно
area, размер считается пропорциональным площади касания или инструмента. -
Если значение равно
default, система использует калибровкуgeometric, если доступна осьraw.touchMajorилиraw.toolMajor, в противном случае используется калибровкаnone.
touch.size.scale
Определение: touch.size.scale = <неотрицательное число с плавающей запятой>
Указывает постоянный коэффициент масштабирования, используемый при калибровке.
Значение по умолчанию: 1.0 .
touch.size.bias
Определение: 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
Определение: touch.pressure.calibration = none |
physical | amplitude | default
Указывает тип измерения, используемый драйвером сенсорного экрана для передачи данных о силе нажатия.
-
Если значение равно
none, сила нажатия неизвестна, поэтому при касании она устанавливается равной 1,0, а при наведении – 0,0. -
Если выбрано значение
physical, предполагается, что ось давления измеряет фактическую физическую интенсивность давления, прикладываемого к сенсорной панели. -
Если значение равно
amplitude, предполагается, что ось давления измеряет амплитуду сигнала, которая связана с размером контакта и приложенным давлением. -
Если значение равно
default, система использует калибровкуphysical, если доступна ось давления, в противном случае –none.
touch.pressure.scale
Определение: touch.pressure.scale = <неотрицательное число с плавающей запятой>
Указывает постоянный коэффициент масштабирования, используемый при калибровке.
Значение по умолчанию: 1.0 / raw.pressure.max .
Вычисления
Расчет поля pressure зависит от указанных параметров калибровки.
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 описывает ориентацию касания и инструмента в виде углового измерения. Значение 0 указывает, что главная ось ориентирована вертикально, -PI/2 – влево, PI/2 – вправо. Если используется стилус, диапазон ориентации может быть описан в виде полного круга от -PI или PI.
Поле tilt описывает наклон инструмента в виде углового измерения.
Значение 0 указывает, что инструмент расположен перпендикулярно поверхности.
Значение PI/2 указывает, что инструмент лежит на поверхности.
touch.orientation.calibration
Определение: touch.orientation.calibration = none |
interpolated | vector | default
Указывает тип измерения, используемый драйвером сенсорного экрана для передачи данных об ориентации.
- Если указано значение
none, ориентация неизвестна и задано значение 0. - Если значение равно
interpolated, ориентация интерполируется линейно, так что исходное значениеraw.orientation.minсопоставляется с-PI/2, а исходное значениеraw.orientation.max– сPI/2. Значение center в(raw.orientation.min + raw.orientation.max) / 2сопоставляется с0. - Если значение равно
vector, ориентация интерпретируется как упакованный вектор, состоящий из двух полей со знаком по 4 бита. Это представление используется в компонентах Atmel Object Based Protocol. При декодировании вектор дает угол ориентации и величину достоверности. Величина достоверности используется для масштабирования информации о размере, если она не является геометрической. - Если значение равно
default, система использует калибровкуinterpolated, если доступна ось ориентации, в противном случае –none.
Вычисления
Расчет полей orientation и tilt зависит от указанных параметров калибровки и доступных входных данных.
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 описывает расстояние между инструментом и поверхностью сенсорного устройства. Значение 0,0 указывает на прямой контакт, а более высокие значения – на увеличивающееся расстояние от поверхности.
touch.distance.calibration
Определение: touch.distance.calibration = none |
scaled | default
Указывает, в каких единицах драйвер сенсорного экрана передает данные о расстоянии.
-
Если значение равно
none, расстояние неизвестно и задано как 0. -
Если значение равно
scaled, то расстояние умножается на постоянный коэффициент масштабирования. -
Если значение равно
default, система использует калибровкуscaled, если доступна ось расстояния, в противном случае –none.
touch.distance.scale
Определение: touch.distance.scale = <неотрицательное число с плавающей запятой>
Указывает постоянный коэффициент масштабирования, используемый при калибровке.
Значение по умолчанию: 1.0 .
Вычисления
Расчет поля distance зависит от указанных параметров калибровки.
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
Примечания о совместимости
В Android 4.0 (Ice Cream Sandwich) свойства конфигурации для сенсорных устройств были значительно изменены. Все файлы конфигурации устройств ввода для сенсорных устройств должны быть обновлены, чтобы использовать новые свойства конфигурации.
Также может потребоваться обновить драйверы старых сенсорных устройств.
Файлы сопоставления виртуальных клавиш
Сенсорные устройства можно использовать для реализации виртуальных клавиш.
Это можно сделать несколькими способами в зависимости от возможностей сенсорного контроллера. Некоторые сенсорные контроллеры можно настроить непосредственно для реализации программных клавиш путем установки регистров встроенного ПО. В других случаях может потребоваться сопоставить координаты касания с кодами клавиш в программном обеспечении.
Если виртуальные клавиши реализованы в программном обеспечении, ядро должно экспортировать файл сопоставления виртуальных клавиш virtualkeys.<devicename> в качестве свойства платы. Например, если драйверы сенсорного экрана сообщают, что его название – touchyfeely, то файл раскладки виртуальных клавиш должен находиться по пути /sys/board_properties/virtualkeys.touchyfeely.
Файл раскладки виртуальных клавиш описывает координаты и коды клавиш Linux для виртуальных клавиш на сенсорном экране.
Помимо файла раскладки виртуальных клавиш, должен быть соответствующий файл раскладки клавиш и файл раскладки символов, чтобы сопоставить коды клавиш Linux с кодами клавиш Android и указать тип клавиатуры (обычно SPECIAL_FUNCTION).
Синтаксис
Файл раскладки виртуальной клавиатуры – это обычный текстовый файл, состоящий из последовательности описаний раскладки виртуальной клавиатуры, разделенных символами новой строки или двоеточиями.
Строки комментариев начинаются с символа # и продолжаются до конца строки.
Каждый виртуальный ключ состоит из шести компонентов, разделенных двоеточиями:
0x01– код версии. Всегда должно быть0x01.- <Linux key code> – код виртуальной клавиши в Linux.
- <centerX>: пиксельная координата X центра виртуальной клавиши.
- <centerY> – пиксельная координата Y центра виртуальной клавиши.
- <width> – ширина виртуальной клавиши в пикселях.
- <height> – высота виртуальной клавиши в пикселях.
Все координаты и размеры указываются в соответствии с системой координат экрана.
Ниже приведен пример файла раскладки виртуальной клавиатуры, записанный в одну строку.
# 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
Файл сопоставления виртуальных клавиш также можно записать в несколько строк.
# 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
В примере выше разрешение сенсорного экрана составляет 480 x 800. Соответственно, все виртуальные клавиши имеют координату <centerY> 835, что немного ниже видимой области сенсорного экрана.
Первая клавиша имеет скан-код Linux 158 (KEY_BACK), centerX 55, centerY 835, ширину 90 и высоту 55.
Пример
Файл раскладки виртуальной клавиатуры: /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
Файл раскладки клавиатуры: /system/usr/keylayout/touchyfeely.kl.
key 158 BACK key 139 MENU key 172 HOME key 217 SEARCH
Файл раскладки клавиатуры: /system/usr/keychars/touchyfeely.kcm.
type SPECIAL_FUNCTION
Косвенные жесты указателя с несколькими касаниями
В режиме указателя система распознает следующие жесты:
- Нажатие одним пальцем – клик.
- Движение одним пальцем – перемещение указателя.
- Перетаскивание указателя: перемещение одним пальцем и нажатие кнопок.
- Проведите двумя пальцами в одном направлении, чтобы перетащить область под указателем в этом направлении. Сам указатель при этом не перемещается.
- Движение двумя пальцами навстречу друг другу или в разные стороны: панорамирование, масштабирование или поворот области вокруг указателя. Сам указатель при этом не перемещается.
- Жест несколькими пальцами: произвольный жест.
Игнорирование касаний ладонью
Начиная с Android 13 система может автоматически отклонять ввод ладонью, если включен встроенный фреймворк. Собственные решения по-прежнему поддерживаются, но их может потребоваться изменить, чтобы они возвращали флаг TOOL_TYPE_PALM при обнаружении ладони. Встроенный фреймворк также работает в сочетании с пользовательскими решениями.
Модель анализирует первые 90 мс данных о жесте, текущий указатель и окружающие указатели, а затем определяет, насколько далеко от края экрана находятся касания.
Затем система определяет, какие из указателей являются ладонями. Также учитывается размер каждого контакта, сообщаемый touchMajor и touchMinor. Затем фреймворк Android удаляет указатели, помеченные как ладони, из потока касаний.
Если указатель уже был отправлен приложениям, система выполняет одно из следующих действий:
- Если есть другие активные указатели, отменяет указатель с заданными значениями
ACTION_POINTER_UPиFLAG_CANCELED. - Если это единственный указатель, отменяет указатель с помощью
ACTION_CANCEL.
MotionEvent.FLAG_CANCELED – общедоступный API, который указывает, что текущее событие не должно вызывать действие пользователя. Этот флаг устанавливается и для ACTION_CANCEL, и для ACTION_POINTER_UP.
Если указатель ладони не был отправлен в приложения, система просто удаляет его.
Включить игнорирование касаний ладонью
- В драйвере сенсорного экрана используйте макрос
input_abs_set_res, чтобы задать разрешение для следующих полей (в пикселях на миллиметр):ABS_MT_POSITION_XABS_MT_POSITION_YABS_MT_TOUCH_MAJORABS_MT_TOUCH_MINOR
Поддержка
ABS_MT_TOUCH_MINORнеобязательна. Если же ваше устройство поддерживает 4K, убедитесь, что разрешение установлено правильно. - Чтобы убедиться, что поля настроены правильно, выполните следующую команду:
$ adb shell getevent -li - Чтобы включить функцию во время выполнения, выполните следующую команду:
$ adb shell device_config put input_native_boot palm_rejection_enabled 1 - Перезапустите процесс
system_server.$ adb shell stop && adb shell start - Убедитесь, что в
adb shell dumpsys inputуказано, что вUnwantedInteractionBlockerесть отклонители ладоней. Если этого не происходит, проверьте журналы, связанные с вводом, чтобы найти подсказки о том, что может быть неправильно настроено.Ниже приведен пример.
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: {} - Чтобы включить функцию навсегда, добавьте соответствующую команду sysprop в файл
init**rc:setprop persist.device_config.input_native_boot.palm_rejection_enabled 1