连接BLE HID时触发java.lang.SecurityException:需BLUETOOTH PRIVILEGED权限
问题解决思路
问题根源
你当前代码遍历了所有BLE服务的所有特征并尝试开启通知,但其中包含了系统专属的HID特征——这类特征仅允许拥有BLUETOOTH PRIVILEGED权限的系统应用操作,第三方应用触发就会抛出权限异常。
修正方案
不要对所有特征开启通知,只针对HID服务中你实际需要的特征(比如输入报告特征)进行操作:
- 先定位HID服务,其标准UUID为
00001812-0000-1000-8000-00805f9b34fb - 在HID服务下筛选出目标特征(比如输入报告特征的标准UUID为
00002a4c-0000-1000-8000-00805f9b34fb) - 仅对这些目标特征调用
setCharacteristicNotification
修改后代码示例
@Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { // HID服务标准UUID String hidServiceUuid = "00001812-0000-1000-8000-00805f9b34fb"; // HID输入报告特征标准UUID String inputReportCharUuid = "00002a4c-0000-1000-8000-00805f9b34fb"; BluetoothGattService hidService = gatt.getService(UUID.fromString(hidServiceUuid)); if (hidService != null) { BluetoothGattCharacteristic inputReportChar = hidService.getCharacteristic(UUID.fromString(inputReportCharUuid)); if (inputReportChar != null) { try { // 仅对输入报告特征开启通知 gatt.setCharacteristicNotification(inputReportChar, true); // 同时需要设置描述符来启用通知(这一步很多人会漏) BluetoothGattDescriptor descriptor = inputReportChar.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")); if (descriptor != null) { descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(descriptor); } } catch (Exception e) { Log.d(TAG, "EXCEPTION: " + e); } } } } else { Log.w(TAG, "onServicesDisceived received: " + status); } }
额外注意点
- Android 12及以上版本,除了在Manifest中声明权限,还需要动态申请
BLUETOOTH_CONNECT和BLUETOOTH_SCAN权限(位置权限根据扫描需求决定是否需要) - 开启特征通知时,必须同时写入对应的描述符(
00002902-0000-1000-8000-00805f9b34fb),否则通知不会生效
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

