分享好友 最新动态首页 最新动态分类 切换频道
Android input键值从底层到应用层映射流程与修改方法
2024-12-27 03:21

Android输入事件的源头是位于/dev/input/下的设备节点,而输入系统的终点是由WMS管理的某个窗口。最初的输入事件为内核生成的原始事件,而最终交付给窗口的则是KeyEvent或MotionEvent对象。因此Android输入系统的主要工作是读取设备节点中的原始事件,将其加工封装,然后派发给一个特定的窗口以及窗口中的控件。这个过程由InputManagerService(以下简称IMS)系统服务为核心的多个参与者共同完成。

(1)键扫描码

ScanCode是由linux的Input驱动框架定义的整数类型,可参考input.h头文件,即getevent得到的键值。

 

(2) 键盘布局文件(*.kl)

将input event报的键值转换成具体键盘对应的按键供android上层使用,时通过键盘布局文件(*.kl)完成转换的。放在/system/usr/keylayout/下面

而qwert.kl中定义如下

 

其中ScanCode 是驱动报的值(即驱动input.h中定义的键值

(3) 添加kl文件

abcxxxx.kl(文件名须与input 的device设备的name一致

[199为 驱动定义的scanCode ,CAMERA 为Android中 KEYCODES[]定义按键对应的keylabel字符]

1)kl文件须与键盘输入的input的devic的名称一致,否则EventHub在加载设备时因找不到对应的kl而加载默认的qwert.kl,导致键值转换错误

2)kl中的scanCode和android中定义的keylabel字符必须对应,否则会转换错误。keyMapper在转换时是根据scanCode,来确定对应的按键字符,再根据此字符在KEYCODES中的位置来确定对应android中的键值

(4) kl文件添加到system

将kl文件(通常)放在/device/mtk/XXX/(XXX为项目名称)

添加AndroidBoard.mk

 

在/device/mtk/common/base.mk添加

 
 

①IR硬件扫描码在驱动里面被映射为 include/uapi/linux/input.h 里面定义的某个键值,但这个键值只在linux系统(内核)中使用。
 ②Android通过源码目录下的 device/xxx/xxx.kl(keylayout) 文件完成linux键值到Android系统要使用的键值映射。

​ 以HID设备为例,首先内核中的键值转换在drivers/hid/hid-input.c 中进行映射,键值通道也有多种类型,例如:keyboard、consumer 等等

//keyboard通道键值则是在如下数组添加修改

 

//consumer通道键值则是在如下添加修改

 

​ 通过 map_key_clear 宏将原始键值(usage->hid & HID_USAGE)转换成内核的定义,映射函数的具体实现可看内核源码

​ 以上键值的定义在 include/uapi/linux/input-event-codes.h (内核代码,较新版本定义整合进了input.h,对应到Android系统层的头文件则是 bionic/libc/kernel/uapi/linux/input-event-codes.h

 

可通过 getevent 指令查看上报的键值,键值为十六进制显示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U7UstaUe-1597307827051)(assets/821933-20180816205242760-1243866432.png)]

 
 

​ 如上我的设备名是:“Smart Remote” , VID PID信息是:Vendor=0030 Product=001D ,则对应 /system/usr/keylayout/Vendor_0030_Product_001D.kl,如果该目录下没有对应VID PID的.kl则默认使用 Generic.kl,根据系统差异可能另外有 /data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl ,此外还有键值对应字符的转换表:/system/usr/keychars/Generic.kcm 。

​ 所以上面通过getevent获得的原始键值是0x44(十进制:68),然后由 hid-input.c 可知 hid_keyboard[68]=87 而 input.h 中定义是 #define KEY_F11 87,所以Android系统层获取到内核转换后的键值为<87>,然后通过加载Generic.kl解析<87>的含义是"F11"(一般都是和内核头文件定义相匹配,也可以自己修改使其映射成其他含义):

 

键值从底层上报到上层的流程简图如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kUMPvATC-1597307827054)(assets/821933-20180816202424670-516556732.png)]

图2:键值上报流程

从上图可以看到,framework层通过.kl文件将获取的键值转换成实际按键含义后,又会通过KeycodeLabel转换成相应的keycode,具体文件在:frameworks ativeincludeinputKeycodeLabels.h(android 4.4.4源码)

 

​ 然后app可以通过如下方法获得对应键按下时的keyCode值,即“F11”对应获得的keyCode即为上面自定义的<546>

 
 

1、Kernel层

include/uapi/linux/input.h 中添加: #define KEY_LXL 123
     drivers/hid/hid-input.c 中添加: case 0x188: map_key_clear(KEY_LXL); break; //其中0x188是HID设备上报的原始键值

2、Android系统层

(1)定义按键对应的key label**

在KEYCODES[]数组的最后添加按键的key label,即:

 

位置:

Android 4.4 以前版本 frameworks/base/include/ui/KeycodeLabels.h 的KEYCODES[]数组中添加{ “LXL”, 666 },

Android 4.4 在framework/native/include/input/KeyCodelabels.h

Android5.0 以后在framework/native/include/input/InputEventLabels.h

(2)定义keyCode

A: native 定义(keycodes.h

 

1)位置:frameworks/base/include/android/keycodes.h

2)此处keycode的定义的值即是 上面key label定义在KEYCODES数组中的位置(index,否则会映射错误

B JAVA定义(KeyEvent.java定义键值

 

修改LAST_KEYCODE

 

  1. 位置:frameworks/base/core/java/android/view/KeyEvent.java

  2. 此处的key code必须与native定义的一致

C :资源文件(attrs.xml)添加keycode

  1. 位置:frameworksbasecore es esvaluesattrs.xml

影响到API则需要调用 make update-api 然后就可以使用了

​ 经过如上的步骤就将Linux驱动向上层抛出的"123"键值和Android系统中的KEYCODE_LXL <666>对应起来了,然后可以在Android的framework层的键值处理函数中,捕获按键事件,并进行相应自定义处理,具体在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 的**interceptKeyBeforeQueueing()**函数中实现。

dumpsys input

这个命令可以查看到输入设备映射到了哪一个kl文件 kl文件映射

getevent getevent -ltr

这个命令可以查看到输入的具体键值时多少,输出的是16进制。

input keyevent

模拟键值输入,input keyevent android键值 例如

 

注意这里的android 键值就是前面KeyEvent.java 里面对应的键值

cat /proc/bus/input/devices

查看设备信息,详见上文
},**

Android 4.4 在framework/native/include/input/KeyCodelabels.h

Android5.0 以后在framework/native/include/input/InputEventLabels.h

(2)定义keyCode

A: native 定义(keycodes.h

 

1)位置:frameworks/base/include/android/keycodes.h

2)此处keycode的定义的值即是 上面key label定义在KEYCODES数组中的位置(index,否则会映射错误

B JAVA定义(KeyEvent.java定义键值

 

修改LAST_KEYCODE

 

  1. 位置:frameworks/base/core/java/android/view/KeyEvent.java

  2. 此处的key code必须与native定义的一致

C :资源文件(attrs.xml)添加keycode

  1. 位置:frameworksbasecore es esvaluesattrs.xml

影响到API则需要调用 make update-api 然后就可以使用了

​ 经过如上的步骤就将Linux驱动向上层抛出的"123"键值和Android系统中的KEYCODE_LXL <666>对应起来了,然后可以在Android的framework层的键值处理函数中,捕获按键事件,并进行相应自定义处理,具体在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 的**interceptKeyBeforeQueueing()**函数中实现。

dumpsys input

这个命令可以查看到输入设备映射到了哪一个kl文件 kl文件映射

getevent getevent -ltr

这个命令可以查看到输入的具体键值时多少,输出的是16进制。

input keyevent

模拟键值输入,input keyevent android键值 例如

 

注意这里的android 键值就是前面KeyEvent.java 里面对应的键值

cat /proc/bus/input/devices

最新文章
零到一开发全流程学习:新手入门指南
本文详细介绍了零到一开发全流程学习,涵盖从开发环境搭建ӌ
河北排名靠前的短视频直播电商培训机构2024-12-12 13:53:06 访问:47次
美迪实力:1、自立研发国内外电商平台几十个电商课程从电商运营店长班、电商实战班、直播带货爆搜班、电商美工设计师、电商摄影短视频班、跨境电商运营班、新媒体运营班8个方向的电商课程进行实战培养,培养学员从运营/设计助理、运营/设计
方案策划
精选方案策划集合八篇  为有力保证事情或工作开展的水平质量,通常会被要求事先制定方案,方案是从目的、要求、方式、方法、进度等都部署具体、周密,并有很强可操作性的计划。制定方案需要注意哪些问题呢?下面是小编精心整理的方案策划
这车到底值不值?Mustang车型怎么选
新车基于福特打造,整体外观造型延续了野马家族经典的设计语言,但也加入了不少彰显科技感的设计。新车前脸搭载封闭式格栅设计,并在中间嵌有品牌logo,前脸的造型看上去十分霸气。而前脸两侧的内部灯组采用了熏黑处理,点亮后具有不错的视
啄木鸟满天星系列:探索自然之美的完美选择与魅力产品
九幺短视频旧版本承载了许多用户的回忆与精彩瞬间。虽然功能与界面相对简单,但独特的滤镜与特效使得用户仍然钟爱这一版本。怀旧的魅力加上易操作的设计,让它在特定人群中保持着热度。9 1抖音短视频安装是许多用户追求新体验的起点。作为
济南SEO负面优化揭秘,揭秘网站排名的致命危机
济南SEO负面优化,是一种性极强的不正当手段,它通过损害网站声誉和结构,严重影响网站排名。这种非法操作不仅损害了网站本身的利益,还了互联网生态平衡,必须予以严厉打击。随着互联网的快速发展,搜索引擎优化(SEO)已成为企业提升网站
阿尔法·罗密欧Giulia朱丽叶该怎么选 能跑能装
对于实用主义者而言,汽车油耗低是一件好事,毕竟油费可是日常用车成本里的大头。不少网友留言想看 ,今天它来了。让我们一起来看看它的表现吧。首先从外观来看,Giulia朱丽叶车头设计显得十分凶悍 ,看上去非常犀利。前车灯非常符合消费者
建站资源策划:强化数据安全与隐私保护策略
  在建站资源策划中,数据安全与隐私保护无疑是至关重要的考虑因素。随着互联网的飞速发展,网络安全问题日益凸显,数据泄露、黑客攻击等事件时有发生,给企业和用户带来了巨大的损失。因此,在建站资源策划阶段,就必须充分考虑到数据安
类似捉宠物的手机游戏推荐 类似捉宠物的手机游戏推荐女生
本文目录有什么带宠物的手机游戏。有没有类似于QQ宠物那样的小游戏求能让宠物合体的好玩的手机游戏,多来几个,谢谢大家了1、1,类似于手机宠物的游戏有很多的。例如:宠物妖怪、宠物城堡、宠物联盟等等2、2,可以到电脑管家官网下载一个电脑
相关文章
推荐文章
发表评论
0评