Android添加新按鍵


1、前言

在Android開發中可能會遇到添加新的按鍵的需求,本文將簡單介紹如何在Android系統中完成一個新的按鍵的添加。

當系統有新的按鍵需要添加時,Linux內核下的鍵碼到Android系統中鍵碼是如何進行轉換映射的?

 

2、內核添加設備節點

首先,我們需要在Linux內核添加新的按鍵值,在Linux內核中提供了按鍵的驅動程序gpio_keys.c,該驅動是基於設備樹實現的,因此,先添加自己的設備節點,如下:

gpio_keys {
    status = "okay";
    compatible = "gpio-keys";
    #address-cells = <1>;
    #size-cells = <0>;
    input-name = "test-keys";
    pinctrl-names = "tlmm_gpio_key_active","tlmm_gpio_key_suspend";
    pinctrl-0 = <&gpio_key_active>;
    pinctrl-1 = <&gpio_key_suspend>;
    
    key1@1 {
        label = "key1";
        gpios = <&msm_gpio 96 1>;
        linux,code = <116>;
        linux,input-type = <1>;
    };
    
    key2@2 {
        label = "key2";
        gpios = <&msm_gpio 98 0>;
        linux,code = <102>;
        linux,input-type = <1>;
    };
};

在該設備樹節點中,定義了兩個按鍵,分別是key1(鍵碼值為116)和key2(鍵碼值為102),關於該設備節點的更詳細介紹,可以查看下面的設備樹綁定文檔:

AOSP/kernel/Documentation/devicetree/bindings/gpio/gpio_keys.txt

關於Linux內核中的鍵碼值定義在文件:

AOSP/kernel/include/uapi/linux/input.h

鍵碼值如下所示:

#define KEY_RESERVED        0
#define KEY_ESC            1
#define KEY_1            2
#define KEY_2            3
#define KEY_3            4
#define KEY_4            5
#define KEY_5            6
#define KEY_6            7
#define KEY_7            8
...
...
...

添加設備樹節點完成后,將Linux內核進行編譯並燒寫,查看新添加的設備節點是否已經添加完成:

$ cd/sys/class/input/input2/device
$ cat uevent

查看設備節點的uevent信息,如下所示,則在Linux內核中完成了新的按鍵設備節點添加:

 

3、鍵值上報到應用層

在上面,已經完成了Linux內核中按鍵的設備節點的添加,但是這僅僅是在Linux內核里面的鍵值,因此,我們需要修改按鍵的布局文件,並完成按鍵的鍵值上報到應用層。

(1)添加按鍵布局文件

按鍵布局文件是用來完成映射過程的,文件以kl結尾,用於將Linux內核中input子系統上報的鍵值轉換成對應得按鍵值供Android系統上層使用,在下面的目錄添加test-keys.kl文件:

AOSP/device/qcom/msm8909/

如下所示:

key 116   POWER
key 102   HOME

需要注意的是,按鍵布局文件的名稱必須與input輸入設備的名稱一致,否則將EvenHub在加載設備時將找不到對應得kl文件而加載默認的kl文件,從而鍵值轉換錯誤,在kl文件中,key是固定的,中間的數字代表的是Linux內核對應得鍵碼。

接下來需要將按鍵的kl文件添加到系統中:

在AndroidBoard.mk中添加編譯的命令,文件如下:

AOSP/device/qcom/msm8909/AndroidBoard.mk

添加的內容如下:

include $(CLEAR_VARS)
LOCAL_MODULE        := test-keys.kl
LOCAL_MODULE_TAGS    := optional eng
LOCAL_MODULE_CLASS    := ETC
LOCAL_SRC_FILES        := $(LOCAL_MODULE)
LOCAL_MODULE_PATH    := $(TARGET_OUT_KEYLAYOUT)
include $(BUILD_PREBUILT)

修改base.mk文件,否則該kl文件將不會被打包,文件如下:

AOSP/device/qcom/common/base.mk

添加內容如下:

# add new kl
KEYPAD += test-keys.kl

(2)Android上層添加按鍵

在上面,我們已經完成了按鍵布局文件的添加,接下來將在Android Framework層完成按鍵的添加。

需要注意的是,在實例中,關於POWER和HOME的按鍵,Android系統中默認已經定義了,如果需要添加新的,則需要自己完成定義:

首先需要添加按鍵對應得KeycodeLable,文件:

AOSP/frameworks/native/include/input/InputEventLabels.h

添加內容如下:

static const InputEventLabel KEYCODES[] = {
    ...
    ...

      DEFINE_KEYCODE(SYSTEM_NAVIGATION_LEFT),
      DEFINE_KEYCODE(SYSTEM_NAVIGATION_RIGHT),

    { NULL, 0 }
};

接下來,進行鍵碼定義,在文件:

AOSP/frameworks/native/include/android/keycodes.h

添加內容如下:

enum {
...
...
/** fingerprint navigation key, left. */ AKEYCODE_SYSTEM_NAVIGATION_LEFT = 282, /** fingerprint navigation key, right. */ AKEYCODE_SYSTEM_NAVIGATION_RIGHT = 283 };

還需要修改java定義,在文件:

AOSP/frameworks/base/core/java/android/view/KeyEvent.java

添加內容如下:

public class KeyEvent extends InputEvent implements Parcelable {
    ...
    ...
    ...
    /** Key code constant: Consumed by the system for navigation left*/
    public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282;
    /** Key code constant: Consumed by the system for navigation right */
    public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283;
private static final
int LAST_KEYCODE = KEYCODE_SYSTEM_NAVIGATION_RIGHT; ... ... ... }

需要注意的是,該文件的鍵碼必須與前面定義的一致。

接下來修改資源文件:

AOSP/frameworks/base/core/res/res/values/attrs.xml

到這里,Android系統添加新鍵值就完成了,接下來進行按鍵測試。

 

4、按鍵測試

將系統重新編譯,並且將新的鏡像進行燒寫,使用下面命令查看,新的按鍵與布局文件:

# dumpsys input

輸出如下:

從打印的結果來看,已經匹配上對應得keylayout文件,在上面的添加實例為POWER相應的鍵值,當按鍵被觸發后,Android終端的屏幕將會被點亮,測試完成。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM