Android系统按键映射过程。
ScanCode -> KeyCodeLabel -> KeyCode -> KeyEvent

ScanCode(键扫描码)

  • ScanCode是由Input驱动框架定义的整数值;
  • 内容:#define KEY_TEST_KEY 232
  • 路径:external/kernel-headers/original/linux/input.h
  • 即getevent获取的键值;

键盘布局文件(*.kl)

  • 键盘布局文件将input event上报的键值转换为KeyCodeLabel;
  • *.kl文件路径,
    • 通常在devices目录下
    • /system/usr/keylayout/.kl
  • 添加键值
    • key 233 TEST_KEY

定义KeyLabel

  • 通过查找KEYCODES[]数组,得到KeyCodeLabel字符串对应的KeyCode值;
  • KEYCODES[]所在文件
    • 4.4以前版本:frameworks/base/include/ui/KeycodeLabels.h
    • 4.4版:framework/native/include/input/KeyCodelabels.h
    • 5.0以后:framework/native/include/input/InputEventLabels.h
  • 定义KeyLabel
    • DEFINE_KEYCODE(TEST_KEY)
    • or: { “TEST_KEY”, 233 }

定义KeyCode

  • 定义native的KeyCode枚举值
    • 路径:frameworks/base/include/android/keycodes.h
    • 内容:AKEYCODE_TEST_KEY = 233
  • 定义java的KeyCode
    • 路径:frameworks/base/core/java/android/view/KeyEvent.java
    • 内容:
      • public static final int KEYCODE_TEST_KEY = 233;
      • private static final int LAST_KEYCODE = KEYCODE_TEST_KEY;
      • names.append(KEYCODE_TEST_KEY, “KEYCODE_TEST_KEY”);
    • Java上层主要通过该值来判定按键;
  • 定义资源文件的KeyCode
    • 路径:frameworks\base\core\res\res\values\attrs.xml
    • 内容:< enum name=“KEYCODE_TEST_KEY” value=“233” / >

监听按键

  • 路径:frameworks/policies/base/phone/com/android/internal/policy/impl/PhoneWindowManager.java
  • 内容:

    // onKeyDown
    case KeyEvent.KEYCODE_TEST_KEY: {
        Intent testIntent = new Intent("neolink.intent.action.KEY_EVENTS")
            .putExtra("key_event", KeyEvent.KEYCODE_TEST_KEY);
        getContext().sendBroadcast(testIntent);
        return true;
    }
    

Tips

  • 在修改了KeyEvent后影响到API,需要执行make update-api
  • getevent确认驱动键值;

参考