Android蓝牙增加自定义按键

本文介绍了在Android 6.0系统中,针对经典蓝牙模块(BT)且使用AVRCP协议的设备,如何通过修改系统源码实现蓝牙手柄自定义按键功能。主要涉及两个步骤:一是修改`btif_rc.c`文件,增加透传特定AT指令;二是修改`Avrcp.java`,处理自定义按键事件并发送。这种方式为蓝牙设备提供了更灵活的按键支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android蓝牙增加自定义按键


公司设备需要增加蓝牙手柄,直接使用可以连接但按键事件没反应,一番研究发现得增加自定义的按键。

说明:
Android版本:6.0
蓝牙-设备协议:AVRCP
蓝牙模块:经典蓝牙模块(BT)

方式1

1.修改\system\bt\btif\src\btif_rc.c
/***************************************************************************

  • Function handle_rc_passthrough_cmd
    • Argument: tBTA_AV_RC rc_id remote control command ID
  •             tBTA_AV_STATE key_state status of key press
    
    • Description: Remote control command handler

***************************************************************************/
void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
{

//此处增加需要透传的AT指令
if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND || p_remote_cmd->rc_id == BTA_AV_RC_F1…) {
HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
return;
}

}

2.修改\packages\apps\Bluetooth\src\com\android\bluetooth\avrcp\Avrcp.java

private void handlePassthroughCmd(int id, int keyState) {
switch (id) {
case BluetoothAvrcp.PASSTHROUGH_ID_REWIND:
rewind(keyState);
break;
case BluetoothAvrcp.PASSTHROUGH_ID_FAST_FOR:
fastForward(keyState);
break;
}
//增加将刚刚透传的按键发送出去的逻辑
}

方式2

1.修改\system\bt\btif\src\btif_rc.c
static const struct {
const char *name;
uint8_t avrcp;
uint16_t mapped_id;
uint8_t release_quirk;
} key_map[] = {
{ “PLAY”, AVRC_ID_PLAY, KEY_PLAYCD, 1 },
{ “STOP”, AVRC_ID_STOP, KEY_STOPCD, 0 },
{ “PAUSE”, AVRC_ID_PAUSE, KEY_PAUSECD, 1 },
{ “FORWARD”, AVRC_ID_FORWARD, KEY_NEXTSONG, 0 },
{ “BACKWARD”, AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
{ “REWIND”, AVRC_ID_REWIND, KEY_REWIND, 0 },
{ “FAST FORWARD”, AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
//增加自定义按键
{ “F1”, AVRC_ID_F1, KEY_F1, 0 },
{ NULL, 0, 0, 0 }
};
未完!

<think>我们正在讨论的是在Android 14 TV Box上适配蓝牙遥控器按键。根据之前的讨论,我们知道适配的关键在于修改键值映射文件(kl文件)。在Android 14上,基本步骤应该类似,但需要注意一些路径和细节的变化。 步骤概述: 1. 获取蓝牙遥控器的按键扫描码(scancode)。 2. 创建或修改对应的kl文件,将扫描码映射到Android键码。 3. 验证映射并调试。 4. 永久生效(编译进固件或放入系统分区)。 详细步骤: ### 1. 获取按键扫描码 使用`adb shell getevent -l`命令来监听按键事件。连接蓝牙遥控器,然后按需要适配的按键,观察输出。 例如,按下音量减键,可能会看到类似这样的输出: ``` /dev/input/event3: EV_KEY KEY_VOLUMEDOWN DOWN /dev/input/event3: EV_KEY KEY_VOLUMEDOWN UP ``` 但有时候,蓝牙遥控器可能不会直接显示Android键码,而是显示扫描码(scancode),比如: ``` /dev/input/event3: EV_KEY KEY_0X0072 DOWN ``` 这里的`0X0072`就是扫描码(十六进制)。我们需要将其转换为十进制(0x0072 -> 114)用于kl文件。 ### 2. 创建或修改kl文件 在Android系统中,kl文件通常位于`/vendor/usr/keylayout/`或`/system/usr/keylayout/`。在Android 14上,推荐使用`/vendor/usr/keylayout/`。 首先,我们需要确定蓝牙遥控器的设备标识(VID和PID)。可以通过以下命令查看输入设备: ```shell adb shell getevent -p ``` 在输出中找到蓝牙遥控器的设备信息,例如: ``` add device 6: /dev/input/event3 bus: 0005 vendor: 0001 product: 0001 version: 0001 name: "Bluetooth Remote" ``` 这里,vendor是`0001`,product是`0001`。那么,对应的kl文件名通常是`Vendor_0001_Product_0001.kl`,或者简化为`Vendor_0001.kl`(如果该厂商的多个产品使用相同的映射)。 然后,我们创建或修改这个kl文件。例如,如果我们要将扫描码114(十六进制0x72)映射为`VOLUME_DOWN`,则在kl文件中添加: ``` key 114 VOLUME_DOWN ``` 操作步骤(通过ADB): ```shell adb root adb remount # 如果remount失败,可能需要先重启adbd为root,或者系统本身未开放remount # 如果无法remount,则需要在有root权限的情况下push文件 adb pull /vendor/usr/keylayout/Vendor_0001.kl . # 备份 # 修改该文件,添加映射 adb push Vendor_0001.kl /vendor/usr/keylayout/ adb reboot # 重启生效 ``` 注意:如果该文件不存在,可以直接创建。 ### 3. 验证与调试 - 重启后,使用`adb shell dumpsys input`命令查看输入设备的配置,确认你的kl文件是否被加载。 - 使用`adb shell getevent -l`再次测试按键,观察事件是否被正确转换。 如果按键没有反应,检查: - kl文件路径和文件名是否正确(大小写敏感)? - 扫描码转换是否正确(十六进制转十进制)? - 是否有多个kl文件匹配了同一个设备?系统会按优先级选择一个(通常更具体的文件名优先级更高,如`Vendor_XXXX_Product_XXXX.kl`优先于`Vendor_XXXX.kl`)。 ### 4. 永久生效 如果只是临时修改,通过adb push即可。但如果是产品固件,需要将kl文件编译进系统镜像。 在AOSP源码中,可以将kl文件放在设备对应的目录下,例如:`device/<manufacturer>/<device>/keylayouts/`,然后在device.mk中将其复制到目标目录: ```makefile PRODUCT_COPY_FILES += \ device/<manufacturer>/<device>/keylayouts/Vendor_0001.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/Vendor_0001.kl ``` ### 关于Android 14的注意事项 - Android 14可能对输入设备的权限有更严格的要求,确保kl文件的权限正确(通常为644)。 - 如果使用SELinux,可能需要调整策略,确保系统服务可以读取该kl文件。但一般情况下,kl文件在`/vendor`分区,默认策略应该允许访问。 ### 多媒体按键的适配 对于多媒体按键(如播放/暂停),Android键码为`MEDIA_PLAY_PAUSE`。同样,获取扫描码后映射即可。例如: ``` key 165 MEDIA_PLAY_PAUSE ``` ### 常见问题 - **问题1:如何通过ADB命令实时监控蓝牙遥控器的按键事件?** 使用`adb shell getevent -l`命令。 - **问题2:kl文件和kcm文件的区别?** kl文件(Key Layout)将扫描码映射到Android键码,而kcm文件(Key Character Map)则用于将键码和修饰键状态(如Shift)映射到字符(用于键盘输入)。遥控器通常只需要kl文件。 - **问题3:蓝牙遥控器的VID/PID查看及与kl文件关联?** 通过`adb shell getevent -p`查看输入设备的vendor和product ID。kl文件名通常为`Vendor_<vid>.kl`或`Vendor_<vid>_Product_<pid>.kl`。 - **问题4:kl文件修改后不生效?** 检查文件名、路径、权限,以及是否被其他kl文件覆盖。重启设备。 - **问题5:多媒体按键映射?** 在kl文件中使用对应的Android多媒体键码,如`MEDIA_PLAY_PAUSE`,`MEDIA_NEXT`等。 ### 引用说明 在Android系统中,按键映射的过程是:物理键值 -> Linux标准键值(通过kl文件) -> Android标准键值(在系统中使用)[^1]。因此,正确配置kl文件是关键。 [^1]: 参考了rk3568 Android11/12适配蓝牙遥控器的基本步骤,尽管平台不同,但原理相同。</think>### Android 14 TV Box蓝牙遥控器按键适配指南 在Android 14系统中适配蓝牙遥控器按键,需重点关注**键值映射文件**和**输入设备识别**。以下是完整步骤: --- #### 1. **获取按键原始扫描码** 使用ADB抓取蓝牙遥控器原始事件: ```shell adb shell getevent -l ``` 按下待适配按键(如音量键),观察输出: ``` /dev/input/event5: EV_KEY KEY_0X72 DOWN # 扫描码0x72(十六进制) ``` **关键转换**:将十六进制扫描码转为十进制(0x72 → 114)用于映射文件[^1]。 --- #### 2. **创建键值映射文件(.kl文件)** 在Android 14中,kl文件路径为: ```shell /vendor/usr/keylayout/ # 主路径 /system_ext/usr/keylayout/ # 备选路径 ``` **操作步骤**: ```shell # 进入adb shell adb shell su mount -o remount,rw /vendor # 创建映射文件(文件名格式:Vendor_VID.kl) echo 'key 114 VOLUME_DOWN' > /vendor/usr/keylayout/Vendor_0074.kl chmod 644 /vendor/usr/keylayout/Vendor_0074.kl sync reboot ``` **映射规则示例**: ```plaintext key 115 VOLUME_UP key 116 POWER # 电源键 key 102 HOME # 主页键 key 28 ENTER # 确认键 key 158 BACK # 返回键 key 229 MEDIA_PLAY_PAUSE # 播放/暂停 ``` --- #### 3. **识别蓝牙遥控器VID/PID** 通过输入设备信息关联kl文件: ```shell adb shell dumpsys input ``` 查找输出中的蓝牙遥控器信息: ``` Device 5: Bluetooth Remote Identifier: vid=0001 pid=0001 ``` 此时系统会自动加载`Vendor_0001.kl`文件(VID=0001)[^1]。 --- #### 4. **调试与验证** - **实时监控按键事件**: ```shell adb shell getevent -l # 查看原始扫描码 adb shell input keyevent # 查看Android键码 ``` - **检查文件加载**: ```shell adb logcat | grep "KeyLayout" # 成功加载提示:Loaded key layout from /vendor/usr/keylayout/Vendor_0074.kl ``` --- #### 5. **永久生效方案** **A. 编译进固件**(需源码环境): 1. 将kl文件放入AOSP路径: ``` device/amlogic/<project>/keylayouts/Vendor_0074.kl ``` 2. 在`device.mk`中添加: ```makefile PRODUCT_COPY_FILES += \ device/amlogic/<project>/keylayouts/Vendor_0074.kl:$(TARGET_COPY_OUT_VENDOR)/usr/keylayout/Vendor_0074.kl ``` **B. 系统分区集成**(无源码): ```shell # 将kl文件打包进vendor分区 mkdir -p vendor/usr/keylayout/ cp Vendor_0074.kl vendor/usr/keylayout/ make snod # 重建system.img ``` --- #### 6. **特殊按键处理** | 按键类型 | Android键码 | 解决方案 | |----------------|-----------------------|------------------------------| | 语音键 | `VOICE_ASSIST` | 添加`key XX VOICE_ASSIST` | | 自定义功能键 | `F1`-`F12` | 映射为`key XX FUNCTION` | | 长按/短按区分 | 需修改框架层`KeyEvent` | 建议通过`InputReader`定制 | > **Android 14变化**:多媒体键需在`AndroidManifest.xml`声明`<action android:name="android.intent.action.MEDIA_BUTTON"/>`才能响应[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值