Android下添加新的自定义键值和按键处理流程
首先分析下Android下怎么添加新的自定义键值。在Android的原生系统中键值默认情况下是92个,从0-91;一般情况下,这些键值是够用的,但是如果想扩充的话,还是需要添加新的键值的,那么如何将一个新的键值从驱动的设置映射到上层,使应用可以对我们自定义的键值进行相应的处理呢?
在介绍Android怎么添加新的键值以前先介绍下Android下INPUT子系统FLOW的流程,下面就是精简的流程图示意图:
1.添加按键及其映射
1)如果系统有新的按键需要添加,是怎么添加并上报到系统上层去的呢(这里的上层主要指的是Android应用层),首先要确定的是我们的遥控设备是通过/dev/input目录下那个event调用那个kl文件,这里可以通过如下命令超看cat /proc/bus/input/devices,下面是在Window终端下的打印信息
- getevent -p得到以下数据信息
3)命令查看如下 通过getevent查看驱动调节的按键值是否上传ok。adb shell getevent 驱动上报O按键键值 如下图所示 0259是16进制数 对应10进制601 1,0: 是指按下和弹起的动作。
Kernel修改
- LINUX/android/kernel/msm-4.19/include/uapi/linux/input-event-codes.h 增加二个宏定义
- old mode 100644
- new mode 100755
- index 8876c98..7afdee6
- --- kernel/msm-4.19/include/uapi/linux/input-event-codes.h
- +++/kernel/msm-4.19/include/uapi/linux/input-event-codes.h
- @@ -337,6 +337,11 @@
- #define KEY_MICMUTE 248 /* Mute / unmute the microphone */
- +#define KEY_EM_O 601
- +//add end
- +
- /* Code 255 is reserved for special needs of AT keyboard driver */
- #define BTN_MISC 0x100
2、在qssi11/LINUX/android/vendor/qcom/proprietary/devicetree-4.19/qcom/kona-pinctrl.dtsi 中增加相关内容[key]: 添加方向键(上、下、左、右)、X/O 键、确认键、主页键、菜单键
- 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
4、在QSSI12/frameworks/base/data/keyboards/Generic.kl中增加X/O按键 如下所示
- 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路径中增加内容如下
- --- 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对应上面定制的字符串
QSSI12/frameworks/native/libs/input/InputEventLabels.cpp
- @@ -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按键映射
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驱动向上层抛出的键值。
- --- 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值
- --- 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日志开关 如下代码所示
- --- 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("ZM", "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("ZM", "interceptKeyBeforeQueueing KeyEvent="+event.toString());
- }
Log.d("ZM", "interceptKeyBeforeQueueing KeyEvent="+event.toString())
Log.d("ZM", "interceptKeyBeforeDispatching KeyEvent="+event.toString())
11、编译之前执行 最后执行指令更新下api,再触发编译
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
- 编译之前执行 最后执行指令更新下api,再触发编译
- make update-api
- /frameworks/base/api/current.txt
- (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 查看现有输入系统
3. 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、其他相关参考文章
Android 10 添加一个新物理按键_gpio-keys.kl_卖报的小行家007的博客-CSDN博客
记一次查看KeyEvent.keyCodeToString方法源码 - 简书 (jianshu.com)