如何适配Android API 33更新含BluetoothLeService的蓝牙应用
适配Android API 33+的BLE连接解决方案
1. 权限更新(核心改动)
API 33+对蓝牙权限做了拆分,必须完成Manifest声明和运行时申请:
- 在
AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- 若需扫描未广播名称的BLE设备,仍需定位权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="32" />
- 运行时主动请求
BLUETOOTH_SCAN和BLUETOOTH_CONNECT权限,API 33+中这两个权限虽属正常权限组,但仍需显式申请。
2. 修复BluetoothLeService的服务/特征获取逻辑
原示例代码在API 33+下可能因权限或GATT行为变更,导致服务/特征获取失败。修改onServicesDiscovered方法:
@Override public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { // 精准获取目标服务 BluetoothGattService targetService = gatt.getService(UUID.fromString("你的BLE服务UUID")); if (targetService != null) { // 获取TX/RX特征 BluetoothGattCharacteristic txChar = targetService.getCharacteristic(UUID.fromString("你的TX特征UUID")); BluetoothGattCharacteristic rxChar = targetService.getCharacteristic(UUID.fromString("你的RX特征UUID")); if (txChar != null && rxChar != null) { // 开启特征通知 setCharacteristicNotification(rxChar, true); Log.d(TAG, "Connected -> characteristicTX = " + txChar); Log.d(TAG, "Connected -> characteristicRX = " + rxChar); } else { Log.e(TAG, "TX/RX特征获取失败"); } } else { Log.e(TAG, "目标GATT服务未找到"); } } else { Log.w(TAG, "服务发现失败,状态码:" + status); } }
- 必须明确指定服务和特征的UUID,避免遍历出错;添加空值判断,快速定位获取失败原因。
3. 调整GATT连接时序
API 33+对BLE连接时序要求更严格,确保以下流程:
- 所有权限申请完成后,再调用
connectGatt - 必须在
onConnectionStateChange回调确认连接成功(status=GATT_SUCCESS)后,再调用discoverServices - 所有GATT操作需绑定同一线程(建议用Handler绑定主线程),避免跨线程操作导致的异常
4. 调试补充
在API 34设备上添加日志,输出所有已发现的服务和特征,确认目标服务是否存在:
// 在onServicesDiscovered中添加 for (BluetoothGattService service : gatt.getServices()) { Log.d(TAG, "已发现服务:" + service.getUuid()); for (BluetoothGattCharacteristic chara : service.getCharacteristics()) { Log.d(TAG, " 特征:" + chara.getUuid()); } }
- 检查BLE设备的广播数据是否正常,若设备需配对,需确保配对流程正常触发。
内容的提问来源于stack exchange,提问作者A. Dal Borgo
相关产品推荐
相关产品推荐

