Android支持各种触摸屏和触摸板,包括基于触控笔的数字化板。
触摸屏是与显示屏相关联的触摸设备,使用户能够在屏幕上直接操纵内容。
触摸板是不与显示屏相关联的触摸设备(如数字化板)。触摸板通常用于指控或绝对间接定位或基于手势的界面控制。
触摸设备可能具有功能与鼠标按钮类似的按钮。
有时可以使用各种不同的工具(如手指或触控笔)操作触摸设备,具体取决于底层的触摸传感器技术。
触摸设备有时用于实现虚拟按键。例如,在某些Android设备上,触摸屏传感器区域延伸超出显示屏的边缘,作为触摸式键盘的一部分发挥双重作用。
由于触摸设备种类繁多,Android依赖于大量配置属性来描述每个设备的特征和期望的行为。
触摸设备分类:
如果同时满足以下两个条件,则输入设备属于多点触控设备:
输入设备报告存在ABS_MT_POSITION_X和ABS_MT_POSITION_Y绝对轴。
输入设备没有任何游戏手柄按钮。某些游戏手柄会使用与M 轴的代码重叠的代码来报告轴,而这一条件则消除了这种歧义。
如果同时满足以下两个条件,则输入设备属于单点触控设备:
输入设备不属于多点触控设备。输入设备要么属于单点触控设备,要么属于多点触控设备,而不会同时属于这两种类别。
输入设备报告存在ABS_X和ABS_Y绝对轴以及BTN_TOUCH按键代码。
一旦输入设备属于触摸设备,则通过尝试加载设备的虚拟按键映射文件来确定是否存在虚拟按键。如果存在虚拟按键映射,则还会加载设备的按键布局文件。
有关虚拟按键映射文件的位置和格式,请参阅下面的部分。
接下来,系统会加载触摸设备的输入设备配置文件。
所有内置触摸设备都应具有输入设备配置文件。如果没有输入设备配置文件,则系统将选择适用于典型通用触摸外设(如外部USB或蓝牙HID触摸屏或触摸板)的默认配置。这些默认配置不适用于内置触摸屏,很可能会导致错误的行为。
加载输入设备配置后,系统会将输入设备分类为触摸屏、触摸板或指控设备。
触摸屏设备用于直接操纵屏幕上的对象。由于用户直接触摸屏幕,因此系统不需要任何额外的感知性来指示被操纵的对象。
触摸板设备用于向应用提供关于在给定传感器区域上进行触摸时的绝对定位信息。它可能对数字化板有用。
指控设备用于使用光标间接操纵屏幕上的对象。手指被解释为多点触控指控手势。其他工具(如触控笔)则通过绝对位置来解释。
有关详情,请参阅间接多点触控指控手势。
以下规则用于将输入设备分类为触摸屏、触摸板或指控设备。
如果设置了touch.deviceType属性,则将按照指示设置设备类型。
如果输入设备报告存在 INPUT_PROP_DIRECT 输入属性(通过 EVIOCGPROP ioctl),则设备类型将设置为触摸屏。该条件假设直接输入触摸设备已连接到同样处于连接状态的显示屏。
如果输入设备报告存在 INPUT_PROP_POINTER 输入属性(通过 EVIOCGPROP ioctl),则设备类型将设置为指控设备。
如果输入设备报告存在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的其他位置(和在MotionEvent API中一样),“工具”通常被称为“指针”。
支持以下工具类型:
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将始终用于指示该工具是实际触摸屏幕还是只在感应范围内悬停。
单点触控设备使用以下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:可选,报告工具的跟踪ID。跟踪ID是一个任意的非负整数。当多个工具同时处于活动状态时,该ID用于独立地识别和跟踪各个工具。例如,当多个手指同时触摸设备时,会为每个手指分配一个不同的跟踪ID,用于在手指保持接触期间识别手指。跟踪ID可在其关联的工具移出感应范围后重复使用。
ABS_MT_SLOT:可选,在使用Linux多点触控协议“B”时,报告工具的槽位ID。有关详情,请参阅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 轴的最小值和最大值用于在特定于设备的Surface单元内指定设备有效区域的范围。如果是触摸屏,有效区域是指触摸设备实际覆盖显示屏的部分。
对于触摸屏,系统会自动插入报告的触摸位置(在Surface单元内),以通过以下公式计算得出采用显示像素表示的触摸位置:
displayX = (x - minX) * displayWidth / (maxX - minX + 1)
displayY = (y - minY) * displayHeight / (maxY - minY + 1)
触摸屏可能会报告在报告的有效区域之外发起的触摸。
在有效区域之外发起的触摸不会传递给应用,但可用于虚拟按键。
在有效区域内发起的触摸或进入和退出显示区域的触摸会传递给应用。因此,如果触摸是在应用的范围内开始,然后移动到有效区域之外,则应用可能会收到显示坐标为负或超出显示范围的触摸事件。这属于正常现象。
触摸设备不得限制有效区域的触摸坐标边界。如果触摸退出有效区域,则应将其报告为超出有效区域范围,或者根本不应报告。
例如,如果用户的手指在触摸屏左上角附近触摸,则可能会报告(minX, minY)坐标。如果手指继续移动到有效区域之外,触摸屏应该开始报告分量小于minX和min 的坐标(如(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 Ice Cream Sandwich 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系统专用的自定义设置。通过依靠标准的Linux输入协议,Android可以使用未经修改的驱动程序来支持更多种类的触摸外设,如外部HID多点触控触摸屏。
触摸设备操作:
下面简要汇总了Android上的触摸设备操作。
EventHub从evdev驱动程序读取原始事件。
InputReader消耗原始事件,并更新关于每个工具的位置和其他特征的内部状态。它还会跟踪按钮状态。
如果按下或释放“后退”或“前进”按钮,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。
输出范围
以下表达式表示输出坐标系的特性。系统使用线性插值将触摸设备使用的 Surface 单元的触摸位置信息转换成将报告给应用的输出单元(如显示像素)。
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,则系统将根据分类算法自动检测设备类型。
有关设备类型如何影响触摸设备的行为的详细信息,请参阅分类部分。
在Honeycomb之前,所有触摸设备都被视为触摸屏。
touch.orientationAware
定义:touch.orientationAware = 0 | 1
指定触摸设备是否应对显示屏的方向更改做出响应。
如果值为1,则只要显示屏的方向更改了,触摸设备报告的触摸位置就会旋转。
如果值为0,则触摸设备报告的触摸位置将不受显示屏方向更改的影响。
如果设备是触摸屏,则默认值为1,否则为0。
系统会区分内部和外部触摸屏与显示部分。方向感知型内部触摸屏基于内部显示部分的方向进行旋转。方向感知型外部触摸屏基于外部显示部分的方向进行旋转。
方向感知功能用于支持Nexus One等设备上的触摸屏旋转。例如,当设备从其自然方向顺时针旋转90度时,触摸的绝对位置将被重新映射,使得在触摸屏绝对坐标系左上角的触摸行为被报告为在显示屏旋转坐标系左上角的触摸行为。这样做是为了使用应用绘制其可见元素时所用的同一坐标系报告触摸行为。
在Honeycomb之前,所有触摸设备都被视为具有方向感知功能。
touch.gestureMode
定义:touch.gestureMode = pointer | spots | default
指定指控手势的表示模式。仅在触摸设备为指控类型时,该配置属性才具有相关性。
如果值为pointer,则触摸板手势将通过与鼠标指针相似的光标来表示。
如果值为spots,则触摸板手势由代表手势形心的锚点和代表各个手指位置的一组圆形斑点来表示。
如果设置了INPUT_PROP_SEMI_MT输入属性,则默认值为pointer,否则为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字段
TouchMajor和TouchMinor字段描述了在输出单元中接触区域的大致维度(单位为像素)。
ToolMajor和ToolMinor字段描述了在输出单元中工具本身的大致维度(单位为像素)。
Size字段描述了相对于触摸设备可以感知的最大可能触摸区域的标准化触摸区域尺寸。可能的最小标准化尺寸为 0.0(无接触或不可测量),可能的最大标准化尺寸为 1.0(传感器区域已经完全覆盖)。
如果可以同时测量近似长度和宽度,则 TouchMajor 字段会指定接触区域的较长维度,TouchMinor 字段会指定接触区域的较短维度。如果只能测量接触区域的大致直径,则 TouchMajor 和 TouchMinor 字段将相等。
同样,ToolMajor 字段会指定工具截断面的较长维度,ToolMinor 字段会指定工具截断面的较短维度。
如果触摸尺寸不可测量,但工具尺寸可测量,则工具尺寸将设为等于触摸尺寸。相反,如果工具尺寸不可测量,但触摸尺寸可测量,则触摸尺寸将设为等于工具尺寸。
触摸设备以各种方式测量或报告触摸尺寸和工具尺寸。目前的实现支持三种不同的测量方式:Surface 单元内的直径、面积和几何边界区域。
touch.size.calibration
定义:touch.size.calibration = none | geometric | diameter | area | default
指定触摸驱动程序报告触摸尺寸和工具尺寸时所用的测量类型。
如果值为none,则尺寸设为零。
如果值为geometric,则假定以与位置相同的Surface单元指定尺寸,从而以相同的方式对尺寸进行缩放。
如果值为diameter,则假定尺寸与触摸或工具直径(宽度)成比例。
如果值为area,则假定尺寸与触摸或工具面积成比例。
如果值为default,那么在raw.touchMajor或raw.toolMajor轴提供值的情况下,系统将使用geometric校准,否则将使用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字段
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 和 Tilt 字段
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。(raw.orientation.min + raw.orientation.max) / 2的中心值映射到0。
如果值为vector,则方向表示为包含两个带符号的4位字段的压缩向量。该表示用于Atmel基于对象的协议部分。当解码时,向量生成定向角和置信度。置信度用于缩放尺寸信息,除非它是几何图形。
如果值为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字段
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 will 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 Ice Cream Sandwich 4.0 中发生了重大变化。必须更新触摸设备的所有输入设备配置文件,才能使用新配置属性。
更旧的触摸设备驱动程序可能也需要更新。
虚拟按键映射文件:
触摸设备经常用于实现虚拟按键。
有几种方法可以做到这一点,具体取决于触摸控制器的功能。一些触摸控制器可以直接配置为通过设置固件寄存器来实现软键。其他时候,最好在软件中执行从触摸坐标到按键代码的映射。
在软件中实现虚拟按键时,内核必须将名为virtualkeys.<devicename>的虚拟按键映射文件作为本机已加载属性导出。例如,如果触摸屏设备驱动程序将其名称报告为“touchyfeely”,则虚拟按键映射文件的路径必须为 /sys/board_properties/virtualkeys.touchyfeely。
虚拟按键映射文件描述了触摸屏上虚拟按键的坐标和Linux按键代码。
除了虚拟按键映射文件外,还必须有一个对应的按键布局文件和按键字符映射文件,以将Linux按键代码映射到Android按键代码,并指定键盘设备的类型(通常为SPECIAL_FUNCTION)。
语法:
虚拟按键映射文件是一个纯文本文件,由一系列用换行符或冒号分隔的虚拟按键布局描述组成。
注释行以“#”开头,并持续到这一行的结束位置。
每个虚拟按键用由6个冒号分隔的组件进行描述:
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×800的分辨率。因此,所有虚拟按键的<centerY>坐标为835,位于略低于触摸屏可见区域的位置。
第一个按键的Linux扫描代码为158 (KEY_BACK),centerX为55,centerY为835,width为90,height为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 102 HOME
key 217 SEARCH
按键字符映射文件:/system/usr/keychars/touchyfeely.kcm。
type SPECIAL_FUNCTION
间接多点触控指控手势
在指控模式下,系统会解释以下手势:
单指点按:点击。
单指移动:移动指针。
单指移动加按下按钮:拖动指针。
两个手指移动(两个手指沿相同的方向移动):沿着该方向拖动指针下方的区域。指针本身不动。
两个手指移动(两个手指朝着彼此移动或者移向不同方向):平移/缩放/旋转指针周围的区域。指针本身不动。
多个手指移动:自由手势。