Android按键上报

参考:
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
                        };

你可能感兴趣的:(Android按键上报)