按键布局文件(.kl
文件)将 Linux 按键代码和轴代码映射到 Android 按键代码和轴代码,并指定关联的政策标记。设备专用的按键布局文件
- 对于带有按键的内部(内置)输入设备(包括音量、电源和耳机媒体按键等特殊按键)是必需的。
- 对于其他输入设备是可选的,但建议用于专用键盘和操纵杆。
如果没有可用的设备专用按键布局文件,系统会选择默认文件。
位置
按键布局文件按 USB 供应商、产品(以及可选的版本)ID 或输入设备名称进行定位。系统会按顺序查询以下路径
/odm/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
/vendor/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
/system/usr/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl
/odm/usr/keylayout/Vendor_XXXX_Product_XXXX.kl
/vendor/usr/keylayout/Vendor_XXXX_Product_XXXX.kl
/system/usr/keylayout/Vendor_XXXX_Product_XXXX.kl
/data/system/devices/keylayout/Vendor_XXXX_Product_XXXX.kl
/odm/usr/keylayout/DEVICE_NAME.kl
/vendor/usr/keylayout/DEVICE_NAME.kl
/system/usr/keylayout/DEVICE_NAME.kl
/data/system/devices/keylayout/DEVICE_NAME.kl
/odm/usr/keylayout/Generic.kl
/vendor/usr/keylayout/Generic.kl
/system/usr/keylayout/Generic.kl
/data/system/devices/keylayout/Generic.kl
在构建包含设备名称的文件路径时,设备名称中除 '0'-'9'、'a'-'z'、'A'-'Z'、'-' 或 '_' 之外的所有字符都将替换为 '_'。
通用按键布局文件
系统提供一个名为 Generic.kl
的特殊内置通用按键布局文件。此按键布局旨在支持各种标准外部键盘和操纵杆。请勿修改通用按键布局!
语法
按键布局文件是一个纯文本文件,由按键或轴声明和标记组成。
按键声明
键声明由关键字 key
后跟 Linux 键代码编号和 Android 键代码名称,或者关键字 usage 后跟 HID 用法和 Android 键代码名称组成。HID 用法表示为 32 位整数,其中高 16 位表示 HID 用法页,低 16 位表示 HID 用法 ID。任一声明之后都可以跟一个可选的空格分隔的策略标志集。
key 1 ESCAPE key 114 VOLUME_DOWN key 16 Q VIRTUAL key usage 0x0c006F BRIGHTNESS_UP
以下是可识别的策略标志
FUNCTION
: 该键应被解释为如同 FUNCTION 键也被按下。GESTURE
: 用户手势生成的键,例如手掌触摸屏幕。VIRTUAL
: 该键是一个与主触摸屏相邻的虚拟软键(电容按钮)。这会导致启用特殊的防抖逻辑(见下文)。
轴声明
轴声明各自包含关键字 axis
,后跟 Linux 轴代码编号和限定符,这些限定符控制轴的行为,包括至少一个 Android 轴代码名称。
基本轴
基本轴只是将 Linux 轴代码映射到 Android 轴代码名称。以下声明将 ABS_X
(由 0x00
指示)映射到 AXIS_X
(由 X
指示)。
axis 0x00 X
在上面的例子中,如果 ABS_X
的值为 5
,则 AXIS_X
被设置为 5
。
拆分轴
拆分轴将一个 Linux 轴代码映射到两个 Android 轴代码名称,这样,当映射时,小于或大于阈值的值会被拆分到两个不同的轴上。当设备报告的单个物理轴编码两个不同的互斥逻辑轴时,此映射非常有用。
以下声明将 ABS_Y
轴(由 0x01
指示)的值在小于 0x7f
时映射到 AXIS_GAS
,或在大于 0x7f
时映射到 AXIS_BRAKE
。
axis 0x01 split 0x7f GAS BRAKE
在上面的例子中,如果 ABS_Y
的值为 0x7d
,则 AXIS_GAS
被设置为 2
(0x7f - 0x7d
),并且 AXIS_BRAKE
被设置为 0
。相反,如果 ABS_Y
的值为 0x83
,则 AXIS_GAS
被设置为 0
,并且 AXIS_BRAKE
被设置为 4
(0x83 - 0x7f
)。最后,如果 ABS_Y
的值等于拆分值 0x7f
,则 AXIS_GAS
和 AXIS_BRAKE
都被设置为 0
。
反转轴
反转轴反转轴值的符号。以下声明将 ABS_RZ
(由 0x05
指示)映射到 AXIS_BRAKE
(由 BRAKE
指示),并通过取反来反转输出。
axis 0x05 invert BRAKE
在上面的例子中,如果 ABS_RZ
的值为 2
,则 AXIS_BRAKE
被设置为 -2
。
中心平坦区选项
由于噪声,即使在未使用摇杆时,摇杆设备也可能报告输入事件。这种噪声通常来自左摇杆和/或右摇杆,并导致驱动程序报告接近 0 的位置值。“中心平坦区”值指定了控制器静止时预期的噪声量。
Linux 输入协议为输入设备驱动程序提供了一种指定摇杆轴中心平坦区值的方法,但并非所有驱动程序都报告它,并且其中一些驱动程序提供的值不正确。为了解决这个问题,轴声明之后可以跟一个 flat
选项,该选项指定轴中心位置周围应被视为居中的区域宽度。
例如,如果设备驱动程序报告的 AXIS_X
值在 0 到 100 之间,那么 Android 输入系统会将 0 映射到 -1,将 100 映射到 1。范围的中心在未缩放坐标中为 50,在缩放坐标中为 0。如果平坦区值等于 10,那么开发人员应该假设任何报告的 AXIS_X
值在 -0.1 和 0.1 之间(在未缩放坐标中为 40 到 60 之间)都是噪声,并将来自摇杆的这些值视为零。
注意:虽然按键布局文件指定了驱动程序坐标空间的值,但 android.view.InputDevice.MotionRange#getFlat() 报告的值是在 Android 坐标空间中。
axis 0x03 Z flat 4096
在上面的例子中,中心平坦区值被设置为 4096
。
注释
注释行以 # 开头,并持续到行尾
# A comment!
空行被忽略。
示例
键盘
# This is an example of a key layout file for a keyboard. key 1 ESCAPE key 2 1 key 3 2 key 4 3 key 5 4 key 6 5 key 7 6 key 8 7 key 9 8 key 10 9 key 11 0 key 12 MINUS key 13 EQUALS key 14 DEL # etc...
系统控制
# This is an example of a key layout file for basic system controls, # such as volume and power keys which are typically implemented as GPIO pins # the device decodes into key presses. key 114 VOLUME_DOWN key 115 VOLUME_UP key 116 POWER
电容按钮
# This is an example of a key layout file for a touch device with capacitive buttons. key 139 MENU VIRTUAL key 172 HOME VIRTUAL key 158 BACK VIRTUAL key 217 SEARCH VIRTUAL
耳机插孔媒体控制
# This is an example of a key layout file for headset mounted media controls. # A typical headset jack interface might have special control wires or detect known # resistive loads as corresponding to media functions or volume controls. # This file assumes that the driver decodes these signals and reports media # controls as key presses. key 163 MEDIA_NEXT key 165 MEDIA_PREVIOUS key 226 HEADSETHOOK
摇杆
# This is an example of a key layout file for a joystick. # These are the buttons that the joystick supports, represented as keys. key 304 BUTTON_A key 305 BUTTON_B key 307 BUTTON_X key 308 BUTTON_Y key 310 BUTTON_L1 key 311 BUTTON_R1 key 314 BUTTON_SELECT key 315 BUTTON_START key 316 BUTTON_MODE key 317 BUTTON_THUMBL key 318 BUTTON_THUMBR # Left and right stick. # The reported value for flat is 128 in a range of -32767 to 32768, which is absurd. # This confuses applications that rely on the flat value because the joystick # actually settles in a flat range of +/- 4096 or so. We override it here. axis 0x00 X flat 4096 axis 0x01 Y flat 4096 axis 0x03 Z flat 4096 axis 0x04 RZ flat 4096 # Triggers. axis 0x02 LTRIGGER axis 0x05 RTRIGGER # Hat. axis 0x10 HAT_X axis 0x11 HAT_Y
虚拟软键
输入系统为在以下用例中实现虚拟软键提供了特殊功能
- 如果虚拟软键以图形方式显示在屏幕上(例如在 Galaxy Nexus 上),它们由 System UI 包中的导航栏组件实现。由于图形虚拟软键在系统的较高层实现,因此不涉及按键布局文件,以下信息不适用。
- 如果虚拟软键被实现为作为主触摸屏一部分的扩展可触摸区域(例如在 Nexus One 上),则输入系统使用虚拟按键映射文件将 X/Y 触摸坐标转换为 Linux 键代码,然后使用按键布局文件将 Linux 键代码转换为 Android 键代码(有关虚拟按键映射文件的详细信息,请参阅 触摸设备)。触摸屏输入设备的按键布局文件必须为每个按键指定适当的按键映射并包含
VIRTUAL
标志。 - 如果虚拟软键被实现为与主触摸屏分离的电容按钮(例如在 Nexus S 上),则内核设备驱动程序或固件负责将触摸转换为 Linux 键代码,然后输入系统使用按键布局文件将 Linux 键代码转换为 Android 键代码。电容按钮输入设备的按键布局文件必须为每个按键指定适当的按键映射并包含
VIRTUAL
标志。
当虚拟软键位于触摸屏内或与其物理位置非常接近时,用户在触摸屏幕底部附近或在屏幕上从上到下或从下到上滑动手指时,很容易意外按下按钮。为了防止这种情况,输入系统应用了少量防抖动,以便在最近一次触摸触摸屏后的一小段时间内忽略虚拟软键按下(此延迟称为*虚拟按键静默时间*)。
要启用虚拟软键防抖动
- 为触摸屏或电容按钮输入设备提供一个按键布局文件,其中为每个按键设置了
VIRTUAL
标志。key 139 MENU VIRTUAL key 172 HOME VIRTUAL key 158 BACK VIRTUAL key 217 SEARCH VIRTUAL
- 在框架
config.xml
资源的资源覆盖中设置虚拟按键静默时间的值。<!-- Specifies the amount of time to disable virtual keys after the screen is touched to filter out accidental virtual key presses due to swiping gestures or taps near the edge of the display. May be 0 to disable the feature. It is recommended that this value be no more than 250 ms. This feature should be disabled for most devices. --> <integer name="config_virtualKeyQuietTimeMillis">250</integer>
验证
您应该使用 Validate Keymaps 工具来验证您的按键布局文件。