天天看點

Android按鍵上報

概述

按鍵資訊上報是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了.

按鍵無觸發或一直觸發

對于高有效的按鍵(具有按鍵功能的裝置):

如果預設上拉:會一直觸發.

如果預設下拉:會幾乎無法觸發,或者非常難觸發.

rockchip,pins =
                                <1 18 RK_FUNC_GPIO &pcfg_pull_none>, //GPIO1_C2
                                <1 20 RK_FUNC_GPIO &pcfg_pull_none>; //GPIO1_C4
                        };