基于Android 13.
一、映射步骤
-
确定要映射的物理按键值
-
在kl文件中增加键值对
-
在InputEventLabels.cpp增加AKEYCODE
-
在keycodes.h中定义AKEYCODE值
-
attrs.xml中增加KEYCODE
-
KeyEvent.java中增加KEYCODE
-
在PhoneManagerWindow等相关类中进行拦截处理相关KEYCODE,属于具体的业务逻
二、确定要映射的物理按键值
通过getevent,可以知道对应的物理按键值。
输入getevent后,按一次对应的物理按键,会有相应的值输出:

/dev/input/event0:按键对应的设备节点(也就是getevent读哪个设备节点读出的按键信息)
name:这个设备节点对应的名字,如/dev/input/event0设备节点对应的名字为"gpio-keys"
00b5:按键对应的物理按键值(也就是kernel层冒上来的按键值)
00b5是十六进制值,在frameworks层进行映射的时候需要转化为十进制,为181。
这样就确定了要映射的物理按键值。
三、在kl文件中增加键值对
在kl文件中增加键值对之前,先要找到对应的kl文件。(kl文件即按键布局文件)
通过getevent,可以知道这个按键对应的设备节点,以及设备节点对应的名字:
这个b5按键对应设备节点是/dev/input/event0,这个设备节点对应的name为"gpio-keys"
通过adb shell dumpsys input查看对应的kl文件:
XML
7: gpio-keys
Classes: KEYBOARD
Path: /dev/input/event0
Enabled: true
Descriptor: 485d69228e24f5e46da1598745890b214130dbc4
Location: gpio-keys/input0
ControllerNumber: 0
UniqueId:
Identifier: bus=0x0019, vendor=0x0001, product=0x0001, version=0x0100
KeyLayoutFile: /system/usr/keylayout/gpio-keys.kl
KeyCharacterMapFile: /system/usr/keychars/Generic.kcm
ConfigurationFile:
VideoDevice: <none>
故我们需要在gpio-keys.kl中增加键值对:
XML
key 181 KEY_XXX
PS:
AOSP原生代码中放置kl的路径:frameworks/base/data/keyboards
设备中放置kl的路径:/system/usr/keylayout
四、在InputEventLabels.cpp增加AKEYCODE
在InputEventLabels.cpp通DEFINE_KEYCODE宏,增加AKEYCODE
frameworks/native/libs/input/InputEventLabels.cpp
XML
DEFINE_KEYCODE(KEY_XXX)
这里有一个小小的地方需要注意下:
cpp
#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }
...
DEFINE_KEYCODE(THUMBS_DOWN), \
DEFINE_KEYCODE(PROFILE_SWITCH), \
DEFINE_KEYCODE(KEY_XXX)/* add by xxx */
在两行DEFINE_KEYCODE之间添加注释的时候,不要采用// comment;会导致编译不过。
DEFINE_KEYCODE外面是个宏,需要用/**/而且不能漏了 \
cpp
DEFINE_KEYCODE(PROFILE_SWITCH), \
DEFINE_KEYCODE(KEY_XXX)/* add by ... */
或者:
DEFINE_KEYCODE(PROFILE_SWITCH), \
/* add by ... */ \
DEFINE_KEYCODE(KEY_XXX)
五、在keycodes.h中定义AKEYCODE值
在keycodes.h中增加AKEYCODE键值对
frameworks/native/include/android/keycodes.h
cpp
/** Used to switch current account that is consuming content.
* May be consumed by system to switch current viewer profile. */
AKEYCODE_PROFILE_SWITCH = 288,
/** add by start. */
AKEYCODE_SKY_XXX = 701
/** add by end. */
PS.这个701是自己定义的,只要取比上一个大的值(这里是288)即可,但是考虑到289在attrs.xml中已经被占用,故这里取大一点的值,给AOSP预留一部分取值范围。
六、attrs.xml中增加KEYCODE
在attrs.xml中增加KEYCODE_XXX:
frameworks/base/core/res/res/values/attrs.xml
XML
<!-- add by start. -->
<enum name="KEYCODE_KEY_XXX" value="701" />
<!-- add by end. -->
七、KeyEvent.java中增加KEYCODE
在KeyEvent.java中增加KEYCODE_XXX:
frameworks/base/core/java/android/view/KeyEvent.java
cpp
/** Key code constant: Demo Application key #4. */
public static final int KEYCODE_DEMO_APP_4 = 304;
/** add by start. */
public static final int KEYCODE_KEY_XXX = 701;
/** add by end. */
到这里,框架层映射按键值就完成了,接下来进行按键拦截测试。
八、拦截处理
在PhoneManagerWindow等相关类中进行拦截处理相关KEYCODE_XXX,属于具体的业务逻辑。