如何让 Android 5.0+ 上的蓝牙 HID 主机正常工作
How to get Bluetooth HID host on Android 5.0+ working
我有一个蓝牙 HID 设备,我需要在 Nexus 7 2013 平板电脑 运行 自定义构建中使用我的应用程序 运行 工作 android 5.0。所以:
@hide
不是约束
- 允许更改 AOSP
- 任何 Android 版本 5.0* - 5.1* 都可以
现在我的设备有一个键盘,并且发送和接受一些特定于供应商的 HID 报告。 工作,我的意思是发送和接收所有 HID 报告
根据我所做的AOSP源代码探索,似乎是:
HidService
服务为所有输入 HID 报告广播 BluetoothInputDevice.ACTION_REPORT
意图 [我的应用有一个 BroadcastReceiver
来接收 ACTION_REPORT
意图]
BluetoothInputDevice
通过 HidService
提供其他接口,如 setReport()
、sendData()
、connect()
等。
BluetoothInputDevice
使用HidService
提供HID设备接口。
HidService.java
是 com_android_bluetooth_hid.cpp
的 JNI 包装器
com_android_bluetooth_hid.cpp
,在 HidService
初始化时,会将其自己的回调注册到 Bluedroid
我已将日志添加到 AOSP 以跟踪调用,似乎以上所有内容都是正确的。
但是
com_android_bluetooth_hid.cpp
中的 get_report_callback()
永远不会被调用,因此,我的应用程序不会收到 ACTION_REPORT
意图。
如果我从我的应用程序发送虚拟 ACTION_REPORT
意图,那么我的 BroadcastReceiver
会收到这些意图。
我的 HID 设备已连接并正常工作,因为我确实在我的应用程序的编辑文本字段中看到收到的密钥。
有什么方法可以在我的应用程序中接收我设备的 HID 报告?通过意图还是通过任何其他方式?
如果我可以通过 Intents 接收,我是否遗漏了任何步骤?我基本上只有 BroadcastReceiver
和意图过滤器以及 BLUETOOTH
和 BLUETOOTH_ADMIN
接收 HID 报告的权限。
如需使用其他方法,请提出建议。
[更新 2]
我可能没有明确提及,但我使用的设备通过 GATT 实现了 HID,并且是 BLE 设备。
在较新的 Android 版本(7、8、9)上,我可以通过订阅 HID 报告通知、添加 BLUETOOTH_PRIVILEGGED 权限并安装为平台应用程序来接收 HID 报告。
这些版本不需要其他 Android 代码杂耍。我没有(也不会)用旧版本的 Android 进行测试,但这个解决方案可能已经在那里工作了。
[上一个答案]
BluetoothInputDevice 根本不工作。
我使用 C 代码中的 /dev/hidraw* 来访问蓝牙 hidraw 设备。
mac 地址未被 /dev/hidraw* 节点报告。
在 Android 5.x 中它们工作并且所有 set/send/recv 报告操作都在工作。未测试。
在 Android 6.x 上,只有 recv 操作在 /dev/hidraw 上运行。 set/send 不工作。未测试。
当我有更好的答案时,我会post更新。
更新
我修改了 bluedroid 并在其中添加了一个小型 unix-socket 服务器。 Bluedroid 将所有传入的 HID 报告传送到此服务器,并接受来自它的传出 HID 报告。我的应用程序通过未命名的套接字与该服务器通信。一切顺利。
我只需要正确设置套接字的权限 SELinux 就可以正常工作。
这适用于我可以测试的所有版本的 Bluedroid (4.4 - 6.0),但每个版本的 Bluedroid 都需要它自己的补丁版本。
我有一个蓝牙 HID 设备,我需要在 Nexus 7 2013 平板电脑 运行 自定义构建中使用我的应用程序 运行 工作 android 5.0。所以:
@hide
不是约束- 允许更改 AOSP
- 任何 Android 版本 5.0* - 5.1* 都可以
现在我的设备有一个键盘,并且发送和接受一些特定于供应商的 HID 报告。 工作,我的意思是发送和接收所有 HID 报告
根据我所做的AOSP源代码探索,似乎是:
HidService
服务为所有输入 HID 报告广播BluetoothInputDevice.ACTION_REPORT
意图 [我的应用有一个BroadcastReceiver
来接收ACTION_REPORT
意图]BluetoothInputDevice
通过HidService
提供其他接口,如setReport()
、sendData()
、connect()
等。BluetoothInputDevice
使用HidService
提供HID设备接口。HidService.java
是com_android_bluetooth_hid.cpp
的 JNI 包装器
com_android_bluetooth_hid.cpp
,在HidService
初始化时,会将其自己的回调注册到 Bluedroid
我已将日志添加到 AOSP 以跟踪调用,似乎以上所有内容都是正确的。
但是
com_android_bluetooth_hid.cpp
中的 get_report_callback()
永远不会被调用,因此,我的应用程序不会收到 ACTION_REPORT
意图。
如果我从我的应用程序发送虚拟 ACTION_REPORT
意图,那么我的 BroadcastReceiver
会收到这些意图。
我的 HID 设备已连接并正常工作,因为我确实在我的应用程序的编辑文本字段中看到收到的密钥。
有什么方法可以在我的应用程序中接收我设备的 HID 报告?通过意图还是通过任何其他方式?
如果我可以通过 Intents 接收,我是否遗漏了任何步骤?我基本上只有 BroadcastReceiver
和意图过滤器以及 BLUETOOTH
和 BLUETOOTH_ADMIN
接收 HID 报告的权限。
如需使用其他方法,请提出建议。
[更新 2]
我可能没有明确提及,但我使用的设备通过 GATT 实现了 HID,并且是 BLE 设备。
在较新的 Android 版本(7、8、9)上,我可以通过订阅 HID 报告通知、添加 BLUETOOTH_PRIVILEGGED 权限并安装为平台应用程序来接收 HID 报告。
这些版本不需要其他 Android 代码杂耍。我没有(也不会)用旧版本的 Android 进行测试,但这个解决方案可能已经在那里工作了。
[上一个答案]
BluetoothInputDevice 根本不工作。
我使用 C 代码中的 /dev/hidraw* 来访问蓝牙 hidraw 设备。
mac 地址未被 /dev/hidraw* 节点报告。
在 Android 5.x 中它们工作并且所有 set/send/recv 报告操作都在工作。未测试。
在 Android 6.x 上,只有 recv 操作在 /dev/hidraw 上运行。 set/send 不工作。未测试。
当我有更好的答案时,我会post更新。
更新
我修改了 bluedroid 并在其中添加了一个小型 unix-socket 服务器。 Bluedroid 将所有传入的 HID 报告传送到此服务器,并接受来自它的传出 HID 报告。我的应用程序通过未命名的套接字与该服务器通信。一切顺利。
我只需要正确设置套接字的权限 SELinux 就可以正常工作。
这适用于我可以测试的所有版本的 Bluedroid (4.4 - 6.0),但每个版本的 Bluedroid 都需要它自己的补丁版本。