目录
前言
最近在做遥控器适配的时候,需要把遥控器一个按键做成特殊功能按键,它通过长按来是实现自定义的功能。
之前在做Linux相关项目的时候,基本上红外解码驱动收到什么key就传什么key给应用层,但是在Android上,发现其实有三层:
- 红外接收到的码值
- Linux层转换的keycode
- Android Framework层自定义的keycode
以下代码以Android10,realtek开发平台,新增按键名字为TouchPad为例
Linux层
1、修改rtd-1319-xxxx.dtsi
文件位置:arch/arm/boot/dts/realtek/rtd13xx/rtd-1319-xxxx.dtsi
文件修改,新增按键touchpad
0x78 531 //KEY_TOUCHPAD_ON //GESTURE
说明:第一列0x78为红外接收到的码值,第二列531是Linux层定义的keycode,第三列按键名称
2、修改相关kl文件
这里说明一下,不同平台kl文件具体位置可以通过deviceCommon.mk文件里面的描述找到对应的kl文件位置一般都在Android/device目录下
找到keylayout这区块就可以找到venus_IR_input.kl、gpio_cmd.kl需要修改
# keylayout
PRODUCT_COPY_FILES += device/realtek/hank/common/venus_IR_input.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/venus_IR_input.kl
PRODUCT_COPY_FILES += device/realtek/hank/common/gpio_cmd.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/gpio_cmd.kl
venus_IR_input.kl 新增key
key 531 TOUCHPAD_ON
gpio_cmd.kl 新增key
key 531 TOUCHPAD_ON
Android 层
1、framework层承上启下文件
从Linux到Android必须有一个承上启下的,默认情况都是
frameworks/base/data/keyboards/qwerty.kl
frameworks/base/data/keyboards/Generic.kl
这两个文档,都依葫芦画瓢,增加新的key
key 531 TOUCHPAD_ON
注意到这里依然用的是Linux层的keycode
2、Android层文件
2.1 Base层
路径:frameworks/base/api/current.txt
public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable{
...
field public static final int KEYCODE_TOUCHPAD_ON = 289; // 0x121
...
}
路径:frameworks/base/core/java/android/view/KeyEvent.java
public class KeyEvent extends InputEvent implements Parcelable{
...
public static final int KEYCODE_TOUCHPAD_ON = 289;
...
}
路径:frameworks/base/core/res/res/values/attrs.xml
<attr name="keycode">
<enum name="KEYCODE_TOUCHPAD_ON" value="289" />
</attr>
2.2 Native层
路径:frameworks/native/include/android/keycodes.h
enum {
...
AKEYCODE_TOUCHPAD_ON = 289
};
路径:frameworks/native/include/input/InputEventLabels.h
static const InputEventLabel KEYCODES[] = {
...
DEFINE_KEYCODE(TOUCHPAD_ON),
...
};
路径:prebuilts/sdk/29/public/api/android.txt
public class KeyEvent extends android.view.InputEvent implements android.os.Parcelable{
...
field public static final int KEYCODE_TOUCHPAD_ON = 289; // 0x120
...
}
以上配置之后,按键定义基本就可完成了,有看过一些其他文章也有相关描述,但是通过打印发现所定义的按键还是没有传上来,Linux层可以看到keycode跟预想的一样,但是Android层却拿到的是0,所以问题应该是出现在这两个中间衔接上,最后发现venus_IR_input.kl、gpio_cmd.kl是跟这两个文件有关。
2.3 Java层实现自定义功能
有了上面的准备,如果需要自定义按键做什么事情,可以在PhoneWindowManager.java中实现
路径:frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
这里我是从按键拦截interceptKeyBeforeDispatchingInner函数里面做处理,具体细节可以根据自己的需求来实现,这里不贴了。