我的应用程序工作正常,直到 Android 5.0.2 不允许第三方应用程序通过蓝牙低功耗连接到 HID 设备。
myGatt.setCharacteristicNotification(gattChar, true);
06-01 17:39:35.356: W/BluetoothGatt(21599):
java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission:Neither
user 10157 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
BLUETOOTH_PRIVILEGED 权限不适用于第三方应用。它仅适用于系统或制造商应用程序。
Android 注释的最新更改: 对 HID-over-GATT 强制执行 BLUETOOTH_PRIVILEGED 权限 https://android.googlesource.com/platform/packages/apps/Bluetooth/+/02bebee
Code snippet:
private static final UUID[] HID_UUIDS = {
UUID.fromString("00002A4A-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4B-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4C-0000-1000-8000-00805F9B34FB"),
UUID.fromString("00002A4D-0000-1000-8000-00805F9B34FB") };
if (isHidUuid(charUuid)) enforcePrivilegedPermission();
我的问题:有没有办法覆盖 HID_UUIDS 或强制执行PrivilegedPermission?我可以使用反射来绕过它吗?
Android 每次发布新版本时,都会破坏以前的代码。
谢谢!
最佳答案
这个问题很老了,但仍然值得回答。 HID(和 FIDO https://fidoalliance.org/ )服务受到保护,并且确实需要系统权限 source 。只有使用系统 key 签名的应用程序才能使用此服务,即仅限蓝牙设置。这是为了确保第 3 方应用程序无法监听无线键盘上键入的按键,因为所有通知和指示都会传输到所有 BluetoothGatt 对象。如果没有这种保护,您将能够连接到 HID 设备(您仍然可以),使用 gatt.setCharacteristicNotification(.., true) 启用通知,并在每次键入按键时接收更新。有了一些关于报告特征的知识,您就可以获取所有按键和鼠标位置,包括密码等。所以这不是一个中断,而是一个错误修复。在 KitKat 上您仍然可以这样做。
唯一的解决方案是编译您自己的 AOSP Android 版本并使用相同的 key 对您的应用程序进行签名。否则保护就没用了。
顺便说一句,从 Android 8 或更早版本开始,您不会收到 SecurityException。该调用就像其他调用一样返回 true,并且您永远不会收到任何回调。 这可能已在此处更改:https://android.googlesource.com/platform/packages/apps/Bluetooth/+/32dc7a6b919375aede777f3c821fa316d85449ae%5E%21/#F2
关于Android 5.0.2 及以上版本不允许通过蓝牙 LE 访问 HID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30579580/