高通 Android 12 framework添加自定义按键上报应用层
2025-08-24 / 龙之叶   

Android下添加新的自定义键值和按键处理流程

首先分析下Android下怎么添加新的自定义键值。在Android的原生系统中键值默认情况下是92个,从0-91;一般情况下,这些键值是够用的,但是如果想扩充的话,还是需要添加新的键值的,那么如何将一个新的键值从驱动的设置映射到上层,使应用可以对我们自定义的键值进行相应的处理呢?

在介绍Android怎么添加新的键值以前先介绍下Android下INPUT子系统FLOW的流程,下面就是精简的流程图示意图:

1.添加按键及其映射

1 如果系统有新的按键需要添加,是怎么添加并上报到系统上层去的呢(这里的上层主要指的是Android应用层),首先要确定的是我们的遥控设备是通过/dev/input目录下那个event调用那个kl文件,这里可以通过如下命令查看 cat /proc/bus/input/devices ,下面是在Window终端下的打印信息

2 getevent -p得到以下数据信息

3 命令查看如下 通过getevent查看驱动调节的按键值是否上传ok。 adb shell getevent 驱动上报O按键键值 如下图所示 0259是16进制数 对应10进制601 1,0: 是指按下和弹起的动作。

Kernel修改

2 在qssi11/LINUX/android/vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi 中增加相关内容[key]: 添加方向键(上、下、左、右)、X/O 键、确认键、主页键、菜单键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
diff --git a/LINUX/android/vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi b/LINUX/android/vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi
index a6398b6..9de20ea 100755
--- a/LINUX/android/vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi
+++ b/LINUX/android/vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi
@@ -148,6 +148,31 @@
};
};
*/
+ tlmm_gpio_key {
+ gpio_key_em_active: gpio_key_em_active {
+ mux {
+ pins = "gpio160", "gpio161", "gpio164", "gpio165", "gpio166", "gpio167", "gpio168", "gpio169";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio160", "gpio161", "gpio164", "gpio165", "gpio166", "gpio167", "gpio168", "gpio169";
+ drive-strength = <4>;
+ bias-pull-up;
+ };
+ };
+ gpio_key_em_suspend: gpio_key_em_suspend {
+ mux {
+ pins = "gpio160", "gpio161", "gpio164", "gpio165", "gpio166", "gpio167", "gpio168", "gpio169";
+ function = "gpio";
+ };
+ config {
+ pins = "gpio160", "gpio161", "gpio164", "gpio165", "gpio166", "gpio167", "gpio168", "gpio169";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+ };
+
trigout_a: trigout_a {
mux {
:

framework修改

注意:需要注意 gpio 在其他地方的引用,这个会引起冲突。

3 QSSI12/device/qcom/qssi/gpio-keys.kl中增加键盘扫描码对应的键盘码key值X/O,600/601

1
2
3
4
5
6
7
8
key 114     VOLUME_DOWN
key 115 VOLUME_UP
key 116 POWER WAKE
key 212 CAMERA WAKE
key 0x210 FOCUS WAKE
key 59 F1 WAKE
key 172 HOME # X键目前替换HOME键
key 601 KEY_EM_O # 新增O键

4 在QSSI12/frameworks/base/data/keyboards/Generic.kl中增加X/O按键 如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
 
git diff frameworks/base/data/keyboards/Generic.kl
diff --git a/QSSI12/frameworks/base/data/keyboards/Generic.kl b/QSSI12/frameworks/base/data/keyboards/Generic.kl
index bd0e56a..e4eb2ae 100644
--- a/QSSI12/frameworks/base/data/keyboards/Generic.kl
+++ b/QSSI12/frameworks/base/data/keyboards/Generic.kl
@@ -410,6 +410,9 @@ key 580 APP_SWITCH
key 582 VOICE_ASSIST
# Linux KEY_ASSISTANT
key 583 ASSIST
+# ZM ADD KEY X O
+key 158 KEY_BACK(X键目前BACK键替换)
+key 601 KEY_EM_O

5 在 QSSI12/frameworks/native/include/android/keycodes.h路径中增加内容如下

1
2
3
4
5
6
7
8
9
10
11
12
--- a/QSSI12/frameworks/native/include/android/keycodes.h
+++ b/QSSI12/frameworks/native/include/android/keycodes.h
@@ -776,7 +776,11 @@ enum {
AKEYCODE_THUMBS_DOWN = 287,
/** Used to switch current account that is consuming content.
* May be consumed by system to switch current viewer profile. */
- AKEYCODE_PROFILE_SWITCH = 288
+ AKEYCODE_PROFILE_SWITCH = 288,
+ /** add custom key X */
+ AKEYCODE_KEY_EM_O = 289,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.

6 在Android 12目录下 QSSI12/frameworks/native/libs/input/InputEventLabels.cpp 将上面的宏展开就是 {KEY_EM_O, AKEYCODE_KEY_EM_O }

其中KEY_EM_O对应上面定制的字符串

1
2
3
4
5
6
7
8
9
10
@@ -314,7 +314,10 @@ namespace android {
DEFINE_KEYCODE(REFRESH), \
DEFINE_KEYCODE(THUMBS_UP), \
DEFINE_KEYCODE(THUMBS_DOWN), \
- DEFINE_KEYCODE(PROFILE_SWITCH)
+ DEFINE_KEYCODE(PROFILE_SWITCH), \
+ DEFINE_KEYCODE(KEY_EM_O)

// NOTE: If you add a new axis here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.

7 高通Android 10/11目录 LINUX/android/frameworks/native/include/input/InputEventLabels.h 添加DEFINE_KEYCODE 增加X/O按键映射

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
static const InputEventLabel KEYCODES[] = {

// NOTE: If you add a new keycode here you must also add it to several other files.

// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.

DEFINE_KEYCODE(UNKNOWN),

DEFINE_KEYCODE(SOFT_LEFT),

......

DEFINE_KEYCODE(PROFILE_SWITCH),

DEFINE_KEYCODE(KEY_EM_O),

{ nullptr, 0 }

};

8 在 QSSI12/frameworks/base/core/java/android/view/KeyEvent.java 增加X/O按键 经过如上的步骤就将”123”按键和Android系统中的KEYCODE_KEY_EM_X就对应起来,注意这里的”600键值并不是真正意义上的600键值,他只是linux驱动向上层抛出的键值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
--- a/QSSI12/frameworks/base/core/java/android/view/KeyEvent.java
+++ b/QSSI12/frameworks/base/core/java/android/view/KeyEvent.java
@@ -831,6 +831,9 @@ public class KeyEvent extends InputEvent implements Parcelable {
*/
public static final int KEYCODE_PROFILE_SWITCH = 288;

+ /** add by zm 2023/04/11*/
+ public static final int KEYCODE_KEY_EM_O = 289; /**
* Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
* @hide
@@ -1977,6 +1980,9 @@ public class KeyEvent extends InputEvent implements Parcelable {
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN:
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT:
case KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT:
+ case KeyEvent.KEYCODE_KEY_EM_O:
+
return true;
}

9 对应上层 KeyEvent.java 里面映射KEYCODE值

1
2
3
4
5
6
7
8
9
--- a/QSSI12/frameworks/base/core/res/res/values/attrs.xml
+++ b/QSSI12/frameworks/base/core/res/res/values/attrs.xml
@@ -1984,6 +1984,9 @@
<enum name="KEYCODE_THUMBS_UP" value="286" />
<enum name="KEYCODE_THUMBS_DOWN" value="287" />
<enum name="KEYCODE_PROFILE_SWITCH" value="288" />
+ <enum name="KEYCODE_KEY_EM_O" value="289" />
</attr>

10 最后在PhoneWindowManager增打开DEBUG_INPUT日志开关 如下代码所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
--- a/QSSI12/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/QSSI12/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -240,7 +240,7 @@ import java.util.HashSet;
public class PhoneWindowManager implements WindowManagerPolicy {
static final String TAG = "WindowManager";
static final boolean localLOGV = false;
- static final boolean DEBUG_INPUT = false;
+ static final boolean DEBUG_INPUT = true;
static final boolean DEBUG_KEYGUARD = false;
static final boolean DEBUG_SPLASH_SCREEN = false;
static final boolean DEBUG_WAKEUP = false;
@@ -2604,6 +2604,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
if (DEBUG_INPUT) {
Log.d(TAG, "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+ repeatCount + " keyguardOn=" + keyguardOn + " canceled=" + canceled);
+ Log.d("yeruilai", "interceptKeyBeforeDispatching KeyEvent="+event.toString());
+
}

if (mKeyCombinationManager.isKeyConsumed(event)) {
@@ -3448,6 +3450,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
Log.d(TAG, "interceptKeyTq keycode=" + keyCode
+ " interactive=" + interactive + " keyguardActive=" + keyguardActive
+ " policyFlags=" + Integer.toHexString(policyFlags));
+ Log.d("yeruilai", "interceptKeyBeforeQueueing KeyEvent="+event.toString());
}

11、编译之前执行 最后执行指令更新下api,再触发编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
make update-api

/frameworks/base/api/current.txt(qssi11路径)QSSI12 frameworks/base/core/api/current.txt

git diff frameworks/base/core/api/current.txt
diff --git a/QSSI12/frameworks/base/core/api/current.txt b/QSSI12/frameworks/base/core/api/current.txt
index 1dd401d..c8ad206 100644
--- a/QSSI12/frameworks/base/core/api/current.txt
+++ b/QSSI12/frameworks/base/core/api/current.txt
@@ -47609,6 +47609,8 @@ package android.view {
field public static final int KEYCODE_K = 39; // 0x27
field public static final int KEYCODE_KANA = 218; // 0xda
field public static final int KEYCODE_KATAKANA_HIRAGANA = 215; // 0xd7
+ field public static final int KEYCODE_KEY_EM_O = 289; // 0x121
field public static final int KEYCODE_L = 40; // 0x28
field public static final int KEYCODE_LANGUAGE_SWITCH = 204; // 0xcc
field public static final int KEYCODE_LAST_CHANNEL = 229; // 0xe5

注意事项:

防止冲突或者遗漏最好在QSSI12目录下搜索所有Generic.kl文件find -name ‘Generic.kl’

  • QSSI12/device/google/atv/Generic.kl
  • QSSI12/device/amlogic/yukawa/input/Generic.kl
  • QSSI12/frameworks/base/data/keyboards/Generic.kl
  • QSSI12/cts/tests/tests/view/res/raw/Generic.kl

最后编译产物out/target/product/qssi/system/usr/keylayout/Generic.kl

  1. 编译之前执行 最后执行指令更新下api,再触发编译
  2. make update-api
  3. /frameworks/base/api/current.txt
  4. (qssi11路径)QSSI12 frameworks/base/core/api/current.txt

3、调试可打开以下库文件的开关

3.1 \frameworks\native\libs\input

3.2 \frameworks\native\services\inputflinger

3.3 . adb shell dumpsys input 查看现有输入系统

  1. 4 adb shell getevent 可查看现有的输入事件

3.5 在/system/usr/keylayout中还有很多Vendor_xxxx_Product_xxxx.kl 之类的配置文件,但是我们没有配置对应的vend id等,所以一直使用默认的Generic.kl。

异常处理

1、 QSSI12/frameworks/native/libs/input/InputEventLabels.cpp 出现空格其他字

解决方案:去掉空格其他斜杠字符转义重新编译即可 用编译器修改最好不要用内部编辑器出现编码不一致问题(VSCode/NodePad++)

2、出现KeyCode Unknown 检查QSSI12/device/qcom/qssi/gpio-keys.kl中增加键盘扫描码对应的键盘码 是否添加,如果没有新增示例如下

3、十六进制转换成十进制的方法如下:

本文链接:
http://longzhiye.top/2025/08/24/2025-08-24/