通俗易通讲解Android蓝牙键值适配
作者:peak?wang 发布时间:2022-06-19 07:50:34
以下图中TV VOD两个按键为例,文章中所涉及到的文件只写文件名,因每个方案的路径各不相同,请自行全局搜索文件。
1.获取按键的扫描码
android设备串口或adb shell下执行getevent -l
(小写的L),然后按下按键(以VOD键为例),打印结果如下:
getevent显示结果中的三个有效信息:
1)000c006b 前四位000c为键值类型(详情请跳到2与阅读hid.h),后四位为蓝牙键值;
2)KEY_BLUE 如果在linux_key.h中有此按键的定义,此处就会显示,如果linux_key.h中没有对此键的定义就会显示KEY_UNKNOWN.
3)/dev/input/event4: 设备节点,可以通过
dumpsys input
命令查看此节点使用KeyLayoutFile
(即映射键值的.kl的文件)
console:/ # getevent -l
add device 1: /dev/input/event4
name: "语音助手"
could not get driver version for /dev/input/mouse2, Not a typewriter
add device 2: /dev/input/event3
name: "Hi Keypad"
could not get driver version for /dev/input/mouse1, Not a typewriter
add device 3: /dev/input/event1
name: "Hi mouse"
could not get driver version for /dev/input/mice, Not a typewriter
add device 4: /dev/input/event0
name: "Hi keyboard"
could not get driver version for /dev/input/mouse0, Not a typewriter
add device 5: /dev/input/event2
name: "qwerty"
/dev/input/event4: EV_MSC MSC_SCAN 000c006b
/dev/input/event4: EV_KEY KEY_BLUE DOWN
/dev/input/event4: EV_SYN SYN_REPORT 00000000
/dev/input/event4: EV_MSC MSC_SCAN 000c006b
/dev/input/event4: EV_KEY KEY_BLUE UP
/dev/input/event4: EV_SYN SYN_REPORT 00000000
2.hid-input.c
从getevent -l时已知VOD按键为000c006b,前四位详细定义可以参考kernel下的hid.h,此处只列举几个:
#define HID_UP_KEYBOARD 0x00070000
#define HID_UP_LED 0x00080000
#define HID_UP_BUTTON 0x00090000
#define HID_UP_ORDINAL 0x000a0000
#define HID_UP_TELEPHONY 0x000b0000
#define HID_UP_CONSUMER 0x000c0000
在hid-input.c中有个函数hidinput_configure_usage,会根据不同的hid执行不同的代码,为0007(HID_UP_KEYBOARD)时会处理hid_keyboard[256]的数组,把扫描码转换为10进制后就是该数组的下标,数组下标的数组元素就是linux键值,我的键值前面是000c所以跳过前面说的,case走的是HID_UP_CONSUMER,此case下已有对0x6b的处理,意思就是此键在linux中代表的是KEY_BLUE。
static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
struct hid_usage *usage)
{
/**省略**/
switch (usage->hid & HID_USAGE_PAGE) {
case HID_UP_UNDEFINED:
goto ignore;
/**省略**/
/**省略**/
case HID_UP_KEYBOARD:
set_bit(EV_REP, input->evbit);
if ((usage->hid & HID_USAGE) < 256) {
if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
} else
map_key(KEY_UNKNOWN);
break;
case HID_UP_CONSUMER:/* USB HUT v1.12, pages 75-84 */
switch (usage->hid & HID_USAGE) {
case 0x06a: map_key_clear(KEY_GREEN);break;
case 0x06b: map_key_clear(KEY_BLUE);break;
case 0x06c: map_key_clear(KEY_YELLOW);break;
case 0x06d: map_key_clear(KEY_ZOOM);break;
/**省略**/
/**省略**/
}
那KEY_BLUE的键值是多少呢?
{"KEY_BLUE", 0x191},
我们来查阅linux_key.h,搜索KEY_BLUE,我的sdk中KEY_BLUE的值为0x191,转换为十进制值为401。
3.KeyLayoutFile --> .kl
getevent -l时已知设备节点为/dev/input/event4,那我们执行下dumpsys input,结果如下:
5: 语音助手
Classes: 0x8000012b
Path: /dev/input/event4
Enabled: true
Descriptor: e0cab5a5e7db45d100777208b12fb1c21978adca
Location:
ControllerNumber: 0
UniqueId: 18:11:18:24:33:18
Identifier: bus=0x0005, vendor=0x2b54, product=0x1600, version=0x0101
KeyLayoutFile: /vendor/usr/keylayout/Vendor_2b54_Product_1600.kl
KeyCharacterMapFile: /vendor/usr/keychars/Generic.kcm
ConfigurationFile:
HaveKeyboardLayoutOverlay: false
结果中可以看出我的蓝牙遥控器的vendor=2b54,product=1600,所以系统优先加载的我自己加到ROM中的kl(.kl命名规则与加载优先级请自行百度),有的可能找不到,会加载Generic.kl等文件,请根据KeyLayoutFile:后的路径的文件修改映射关系,如果为默认的Generic.kl时,建议不要修改此文件,可以根据vendor与product规则自己新建一个文件。
那我们打开指向的这个kl文件,内容如下:
#key 222 "KEY_RED"
# key 400 "KEY_YELLOW"
key 401 PROG_GREEN
key 402 CHANNEL_UP
key 403 CHANNEL_DOWN
kl文件格式简单解析(详解与其它使用方法自行搜索):
key 可以理解成固定格式
222/401等数字对应的就是linux的键值
PROG_GREEN 这里对应的就是Android层的键值(此字符串要与InputEventLabels.h中的保持一致,否则会报Expected key code label异常,然后就加载其它默认的kl文件了,5.0以前是KeycodeLabels.h或KeyCodeLabels.h)
既然都理清楚了,那处理按键岂不是很简单了?
已知前面linux_key.h中查询VOD的linux键值为401,如果你想让此按键生效,把前面的#号去掉重启设备,使其映射关系生效即可,如果你想改变键值的功能,可以直接在此kl中把401对应的android层的KEY_BLUE改为你想要的键就可以了。(当然也可以修改linux的键值,但不提倡这么做.)
总结:
1.通过getevent -l获取键值设备节点;
2.hid-input.c中添加或修改你的键值;
3.通过设备节点找到对应的kl文件;
4.添加或修改映射关系;
以上所述是小编给大家介绍的Android蓝牙键值适配网站的支持!
来源:https://blog.csdn.net/qq3965470/article/details/121651538


猜你喜欢
- Spring中添加计时器的时候根据业务需求可能会需要动态处理触发时间;import org.slf4j.Logger; import org
- Redisson分布式锁之前的基于注解的锁有一种锁是基本redis的分布式锁,锁的实现我是基于redisson组件提供的RLock,这篇来看
- dynamic关键字和动态语言运行时(DLR)是.Net 4.0中新增的功能。什么是"动态"?编程语言有时可以划分为静态
- 传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Sockets
- 一、SpringBoot整合FastJson1.1、引入FastJson依赖包maven项目:<dependency> &nbs
- 生成excel并导出到对应位置package tech.BurtonPratice; import org.apache.poi.hssf.
- 这几天在项目里面发现我使用@Transactional注解事务之后,抛了异常居然不回滚。后来终于找到了原因。如果你也出现了这种情况,可以从下
- 使用INI配置文件,简单便捷。该辅助工具类为C#操作INI文件的辅助类,源码在某位师傅的基础上完善的来,因为忘记最初的来源了,因此不能提及引
- 题目一(有关传值调用与非法访问)请问运行Test 函数会有什么样的结果?答 :程序运行会崩溃 ! 且存在内存泄漏 ;原因:1.str传给p的
- 一、定义责任链模式(Chain of Responsibility Pattern):避免将一个请求的发送者与接受者耦合在一起,让多个对象都
- GUI全程是Graphical User Interface,即图形用户界面。顾名思义,GUI就是可以让用户直接操作的图形化界面,包括窗口、
- 本文实例讲述了Java编程实现获取当前代码行行号的方法。分享给大家供大家参考,具体如下:最近的项目中,为了实现自定义的log类,能够输出具体
- 本文实例讲述了Android编程实现将应用强制装到手机内存的方法。分享给大家供大家参考,具体如下:在Froyo(android 2.2,AP
- 投篮小游戏规则,点击投篮目标点,就会有一个球沿着相关抛物线,然后,判断是否进入篮子里,其实就是一个矩形,直接是按照碰撞检测来的,碰到就算进去
- 自己折腾了好久,记录一下。service端: 1:创建类Dog,需要实现Parcelable接口;2:aidl下创建 Dog.aidl,里面
- EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。ehcach
- 前言一般在写业务接口的过程中,很有可能需要实现可以动态组合各种查询条件的接口。如果我们根据一种查询条件组合一个方法的做法来写,那么将会有大量
- 一、简介1.1 Log4.net优点几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后,就不太可能再利用专门的调试工
- 整合Spring Data JPAJPA (Java Persistence API)和 Spring Data 是两个范畴的概念。Hibe
- 前言在开始介绍socket前先补充补充基础知识,在此基础上理解网络通信才会顺理成章,当然有基础的可以跳过去了。都是废话,进入正题。TCP/I