按键布局文件

按键布局文件(.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_GASAXIS_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

虚拟软键

输入系统为在以下用例中实现虚拟软键提供了特殊功能

  1. 如果虚拟软键以图形方式显示在屏幕上(例如在 Galaxy Nexus 上),它们由 System UI 包中的导航栏组件实现。由于图形虚拟软键在系统的较高层实现,因此不涉及按键布局文件,以下信息不适用。
  2. 如果虚拟软键被实现为作为主触摸屏一部分的扩展可触摸区域(例如在 Nexus One 上),则输入系统使用虚拟按键映射文件将 X/Y 触摸坐标转换为 Linux 键代码,然后使用按键布局文件将 Linux 键代码转换为 Android 键代码(有关虚拟按键映射文件的详细信息,请参阅 触摸设备)。触摸屏输入设备的按键布局文件必须为每个按键指定适当的按键映射并包含 VIRTUAL 标志。
  3. 如果虚拟软键被实现为与主触摸屏分离的电容按钮(例如在 Nexus S 上),则内核设备驱动程序或固件负责将触摸转换为 Linux 键代码,然后输入系统使用按键布局文件将 Linux 键代码转换为 Android 键代码。电容按钮输入设备的按键布局文件必须为每个按键指定适当的按键映射并包含 VIRTUAL 标志。

当虚拟软键位于触摸屏内或与其物理位置非常接近时,用户在触摸屏幕底部附近或在屏幕上从上到下或从下到上滑动手指时,很容易意外按下按钮。为了防止这种情况,输入系统应用了少量防抖动,以便在最近一次触摸触摸屏后的一小段时间内忽略虚拟软键按下(此延迟称为*虚拟按键静默时间*)。

要启用虚拟软键防抖动

  1. 为触摸屏或电容按钮输入设备提供一个按键布局文件,其中为每个按键设置了 VIRTUAL 标志。
    key 139    MENU           VIRTUAL
    key 172    HOME           VIRTUAL
    key 158    BACK           VIRTUAL
    key 217    SEARCH         VIRTUAL
    
  2. 在框架 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 工具来验证您的按键布局文件。