Android物理按键功能更改

这两天有个需求,需要将Android手机上的音量 +/- 按键更改为以前功能机的上/下按键。一头雾水的我开始百度如何更改Android手机的物理按键功能。经过一番查询和实际演练终于完成了需求,下面将该过程进行总结。
(PS: 由于我只是做android应用相关的,对驱动层的知识懂的不多,这里仅仅是记录一下我解决问题的方法,如果要深究Android的按键流程,还是要参考其他资料。)

首先,我们需要搞清楚的是,用户点击了一个按钮后究竟发生了什么。这就不得不说一下Android的INPUT子系统了。其精简流程图如下:
Android物理按键功能更改_第1张图片
根据流程图,从下往上看,首先是Linux内核层上报按键码,我在这里引用简书作者天空汁橙在《Android物理按键输入事件(一)》中所写来描述Linux内核层的操作:
① linux内核通过扫码,将硬件上按键按下电压变换为数字电压并映射到数组下标;
② 通过数组关系转化将按键映射到内核中预定义的键值;
③ 最终linux内核上报给上层的就是这个整型值。
其中,这些上报的值反映在kernel/uapi/linux/input.h中。

//input.h部分代码... .../* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */#define KEY_RIGHTALT 100#define KEY_LINEFEED 101#define KEY_HOME 102#define KEY_UP 103/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */#define KEY_PAGEUP 104#define KEY_LEFT 105#define KEY_RIGHT 106#define KEY_END 107/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */#define KEY_DOWN 108#define KEY_PAGEDOWN 109#define KEY_INSERT 110#define KEY_DELETE 111/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */#define KEY_MACRO 112#define KEY_MUTE 113#define KEY_VOLUMEDOWN 114#define KEY_VOLUMEUP 115/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */#define KEY_POWER 116#define KEY_KPEQUAL 117#define KEY_KPPLUSMINUS 118#define KEY_PAUSE 119... ...

那么,这些linux内核上报按键值后又会发生什么?这里就需要提到kl文件了。Android kl文件是标准linux与android的键值映射文件,kl文件可以有很多个,有关kl文件的介绍,可以参考:
https://blog.csdn.net/mcgrady_tracy/article/details/47358689

我们可以通过以下命令查看手机所使用的kl文件有哪些:

> cat /proc/bus/input/devices

输入命令后,会出现下图这样的输出:
Android物理按键功能更改_第2张图片
从图中我们可以确定终端目前所使用的kl文件(有些kl文件找不到)。我找到了“Name=”comip_gpio_keys””的kl文件,将其打开,我们可以查看到类似以下内容:

key 113   MUTEkey 115   VOLUME_UPkey 114   VOLUME_DOWNkey 163   MEDIA_NEXTkey 164   MEDIA_PLAY_PAUSEkey 165   MEDIA_PREVIOUSkey 226   HEADSETHOOKkey 158   BACKkey 28    DPAD_CENTERkey 231   CALLkey 107   ENDCALLkey 103   DPAD_UPkey 108   DPAD_DOWNkey 105   DPAD_LEFTkey 106   DPAD_RIGHTkey 59    F1key 60    F2

kl文件中,key后面的数字就是kernel上报的按键码,后面的字符标签就是该按键码对应的android中的按键标签,我们可以看到上面“103”对应的是物理按键中的“上”,“108”对应物理按键中的“下”。当用户按下按键后,kernel会上报对应按键的按键码,例如我们按下音量+键,kernel就会上报按键码115,然后上层根据正确的kl文件中的对应关系,将按键对应到上层的VOLUME_UP标签上来。

那这些按键标签是哪里来的呢?
其实,这些标签也都对应一个按键码,与kernel上报的按键码不同,按键标签所对应的按键码就是我们在上层代码逻辑中使用的按键码。我们可以在frameworks/native/include/input/InputEventLabels.h中看到:这里通过宏定义将标签字符与上层按键码对应起来,其中上层按键码又是通过frameworks/native/include/android/Keycodes.h中枚举的。我们在上层所使用的按键码就是这个枚举类型中所列出的整型值。

//InputEventLabels.h部分代码#include <input/Input.h>#include <android/keycodes.h>#define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }… …struct InputEventLabel {    const char *literal;    int value;};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(SOFT_RIGHT),    DEFINE_KEYCODE(HOME),    DEFINE_KEYCODE(BACK),    DEFINE_KEYCODE(CALL),    … …    DEFINE_KEYCODE(POUND),    DEFINE_KEYCODE(DPAD_UP),    DEFINE_KEYCODE(DPAD_DOWN),    DEFINE_KEYCODE(DPAD_LEFT),    DEFINE_KEYCODE(DPAD_RIGHT),    DEFINE_KEYCODE(DPAD_CENTER),    DEFINE_KEYCODE(VOLUME_UP),    DEFINE_KEYCODE(VOLUME_DOWN),    DEFINE_KEYCODE(POWER),    DEFINE_KEYCODE(CAMERA),    DEFINE_KEYCODE(CLEAR),    … …    { NULL, 0 }};
//Keycodes.h部分代码enum {    AKEYCODE_UNKNOWN         = 0,    AKEYCODE_SOFT_LEFT       = 1,    AKEYCODE_SOFT_RIGHT      = 2,    AKEYCODE_HOME            = 3,    AKEYCODE_BACK            = 4,    AKEYCODE_CALL            = 5,    … …    AKEYCODE_POUND           = 18,    AKEYCODE_DPAD_UP         = 19,    AKEYCODE_DPAD_DOWN       = 20,    AKEYCODE_DPAD_LEFT       = 21,    AKEYCODE_DPAD_RIGHT      = 22,    AKEYCODE_DPAD_CENTER     = 23,    AKEYCODE_VOLUME_UP       = 24,    AKEYCODE_VOLUME_DOWN     = 25,    AKEYCODE_POWER           = 26,    AKEYCODE_CAMERA          = 27,    AKEYCODE_CLEAR           = 28,    … …    // 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.};

这样就将物理按键、kernel、上层之间的映射关系确定了,点击某个物理按键,上层就知道哪个按键被点击了。

如果我要将音量+/-按键变为上/下按键,只需要把对应kl文件中,104和105对应的VOLUME_UP和VOLUME_DOWN更改为DPAD_UP和DPAD_DOWN即可。整编后将系统烧到手机,重新开机就可以了。

更多相关文章

  1. android webview处理h5打开本地文件浏览器的功能
  2. android系统文件的权限
  3. Android通知MediaScanner扫描指定的文件
  4. android中XML文件系列(一)—Drawable中的XML
  5. android XMLPullParser读取xml文件
  6. Android压缩文件(压缩目录)
  7. android 从文件制定位置读取数据
  8. Android 文件缓存方法

随机推荐

  1. android 遍历assets下的文件
  2. FrameLayout使用
  3. [android]_[handler的简单使用]
  4. android kernel最新下载地址
  5. zz :Android测试之Monkey
  6. Android(安卓)数据存储与IO (二)
  7. Unity和Android交互
  8. Android开发之Shape和Selector、Layer-li
  9. React Native基础之Image
  10. Android的数据存储方式