20140306更新:
今天再次遇到同样的问题,为Android添加按键。平台是rk30,Android版本是4.2.2。遇到了一些新问题和新的挑战,花费一天时间添加完毕。且做了完整的规划。以CAMERA和OTHAER键为例。
1.确认内核层的键值码
进入adb shell,使用toolbox中的getevent工具:type code value。主要看type为1时的code值是多少。
2.确认*.kl文件
确认方法是交换V+ 和V-的键值码,结果是:自定义:rk29-keypad.kl,一般键盘是:Generic.kl,qwerty.kl已经被Generic.kl取代。
3.确认如何修改*.kl会起效
重启后
4.确认两个kl区别
从里边内容可以大概分别出来rk29-keypad.kl决定新添加的,Generic.kl包含了所有的键,优先级低于rk29-keypad.kl,也就是两个kl文件可以同定义一个键值,但会以rk29-keypad.kl首先为准(如果rk29-keypad.kl中定义了,但是字串Android层没有处理比如”key 114 FUCK”,”FUCK”上层并没有处理,还是会去处理Generic.kl中的对应键串),所以新添加的键值都添加到rk29-keypad.kl中,Generic.kl是建议不动的。
注意事项:kl定义的键串必须是Android层进行处理的,如果有出现没有处理的键串会导致整个键盘都不能使用。如果是键盘只会读Generic.kl,而不会读rk29-keypad.kl。所以如果是一个特殊的键盘,那么要动手修改Generic.kl。这个是实践结果,具体源码还没有找到。
5.先打通一个已经半通的CAMERA
CAMERA是上层已经完善的,在kl文件将新按键映射到的CAMERA上(key 132 CAMERA),然后用一个apk来验证接收。结果OK。
6.打通整个通道-添加OTHER键值
在添加过程中还参考了篇文章《Android4.1添加新的按键(3)》,这里记录4.2.2中具体修改了哪些文件:
external/webkit/Source/WebKit/android/plugins/ANPKeyCodes.h
frameworks/base/api/current.txt
frameworks/base/core/java/android/view/KeyEvent.java (两处)
frameworks/base/core/res/res/values/attrs.xml
frameworks/base/data/keyboards/Generic.kl
frameworks/base/include/androidfw/KeycodeLabels.h
frameworks/base/libs/androidfw/Input.cpp
frameworks/native/include/android/keycodes.h
其中current.txt是在添加其它文件后执行make update-api编译自动修改的结果。关于Android上层在哪里解析的这个两个kl文件,要等下次更新了。
20141010更新:
Android上层也在不断的更新,4.0/4.2的时候亮度的调节还是要自己添加按键来实现,4.4中KeyEvent.java已经有了这两个按键键值,对应Generic.kl中已经已经有了对应到Linux内核的标准亮度调试键值。
From: https://github.com/android/platform_frameworks_base/commit/1df477acf60538f9de18bd597e090d075fa83509
不仅可以验证内核发出的输入事件,同样不可以模拟输入事件到Android上层。如下命令模拟「亮度减」的按键。
$ adb shell input keyevent BRIGHTNESS_DOWN
执行后就可以Android系统可以响应出来 调整亮度。就可以说明Android上层已经畅通无阻了。
根据以上分析,那么在Android4.4中配置内核中只上报标准的内核亮度键值KEY_BRIGHTNESSDOWN/KEY_BRIGHTNESSUP就可以正常的对接了。
但是我同样遇到了亮度按键不能响应的问题,通过上下观察值都对应上去的,但是却不能正常响应。
经实验,将如下「亮度键值」添加到rk29-keypad.kl中可以正常响应了:
key 224 BRIGHTNESS_DOWN
key 225 BRIGHTNESS_UP
事后根据Android官方教程Key Layout Files分析它会优先读取/system/usr/keylayout/DEVICE_NAME.kl按键映射文件。而设备上的物理按键的设备名正好是「rk29-keypad」,可以通过getevent查看出来。
这也解释了20140315添加红外遥控器的键值时不能添加到rk29-keypad.kl中,而添加到Generic.kl可以正常。因为Generic.kl的属于fallback级别的映射文件。针对遥控器正确的方法同样新建立一个DEVICE_NAME.kl的映射文件。比如遥控器设备名为rkxx-remotectl那么新建一个rkxx-remotectl.kl映射文件,内容是和Generic.kl中类似的每个键值对应的键码。这个方法要远比直接修改Generic.kl文件要好的多了。
其实同样也有了新的疑问,如果DEVICE_NAME.kl中没有声明的键值,那么就不会去Generic.kl中查找,这点我是有点自己的建议的,应该像字库一样,在相应的字库中查找不到的字都到fallback字体中查找一下。
20141018更新:
Keylayout文件中所有的「字串」必须在当前版本系统的源码的KeyEvent类中存在。否则系统会认为该Keylayout是无效的。所以可以添加Keylayout和添加「字串」到KeyEvent要同步进行。