参考:
1.https://ask.csdn.net/questions/767179
概述
按键信息上报是input系统里面一个最基本,最简单,也是最常用的功能.一般直接配置dts即可,但是也有可能有定制需求,比如自定义按键和上报特殊按键.
新增按键
内核已经实现了通用按键驱动,优先建议使用.
gpio_keys: gpio_keys {
compatible = "gpio-keys";
pinctrl-names = "default";
pinctrl-0 = <&gpio_keys_sensor>;
#address-cells = <1>;
#size-cells = <0>;
button0 {
label = "Lhead";
linux,code = <0x101>; /*BTN_1*/
debounce-interval = <10>;
gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
};
button1 {
label = "Rhead";
linux,code = <0x102>; /*BTN_2*/
debounce-interval = <10>;
gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
};
};
自定义按键
当前按键定义无法满足的情况下可以 自定义按键.主要修改以下文件:
[kernel]
内核按键定义:kernel/include/uapi/linux/input-event-codes.h
添加按键驱动,上报按键事件:kernel/drivers/input/keyboard/gpio_keys.c(或自己写驱动)
dts添加:kernel/arch/arm64/boot/dts/rockchip(board)/XXXX.dts
[android]
.kl文件添加键值:
frameworks/base/data/keyboards/Generic.kl(通用键值,可自定义kl文件)
frameworks/base/data/keyboards/qwerty.kl
键值映射:
frameworks/native/include/input/InputEventLabels.h
frameworks/native/include/android/keycodes.h
frameworks/base/core/java/android/view/KeyEvent.java
frameworks/base/core/res/res/values/attrs.xml
[系统目录]
/system/usr/keylayout/Generic.kl
[handle]
按键处理:可以增加响应处理逻辑
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
特殊按键上报
对于HOME,POWR等特殊按键,apk正常是无法监听到的,但是也有方法:
对于9.0以下:
android.intent.action.ACTION_CLOSE_SYSTEM_DIALOGS
对于9.0以上:
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
也可以修改PhoneWindowManager.java中对应的处理逻辑:
@@ -6111,12 +6111,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} catch (RemoteException e) {
}
- result &= ~ACTION_PASS_TO_USER;
+ result |= ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
这样apk就可以监听到power按键了,其他特殊按键类似.
常见问题
按键误触发
如果按键配置为BTN_0~9,那么在按按键的时候,会导致页面按钮响应,处理按键事件.比如在拍照界面,BTN会被处理为按下拍照.这通常不是我们所希望的.
有两种修改方式:
方式一:
修改linux,code,对应其他未使用,且对activity无影响的code值.
方法二:
修改frameworks/base/data/keyboards/Generic.kl中的映射,重映射到其他code.
后台应用无法监听
对于power或其他按键,后台应用是无法监听的,此时可以采用广播的方式:
mContext.sendBroadcast(new Intent("com.xxx.keycode.power"));
这样所有注册了对应广播的apk都可以监听到了.
每次按键都有两次上报
每个按键都会上报两次(up,down),但是对于特殊按键(power等),使用上面的方法会广播两次,但是无法分辨up和dow,所以需要进一步改进
@@ -6111,12 +6111,14 @@ public class PhoneWindowManager implements WindowManagerPolicy {
} catch (RemoteException e) {
}
- result &= ~ACTION_PASS_TO_USER;
+ result |= ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
+ mContext.sendBroadcast(new Intent("com.xxx.keycode.power.down"));
} else {
interceptPowerKeyUp(event, interactive, canceled);
+ mContext.sendBroadcast(new Intent("com.xxx.keycode.power.up"));
}
break;
}
这样就可以区分up和down了.
按键无触发或一直触发
对于高有效的按键(具有按键功能的设备):
如果默认上拉:会一直触发.
如果默认下拉:会几乎无法触发,或者非常难触发.
建议采用pcfg_pull_none.
rockchip,pins =
<1 18 RK_FUNC_GPIO &pcfg_pull_none>, //GPIO1_C2
<1 20 RK_FUNC_GPIO &pcfg_pull_none>; //GPIO1_C4
};