Android 13以下设备中BluetoothGattCallback的onCharacteristicChanged无法触发
Android 11上BluetoothGattCallback的onCharacteristicChanged无法触发,Android 13正常
我尝试通过BLE设备接收数据,仅在Android 13上正常工作,Android 11设备中BluetoothGattCallback的onCharacteristicChanged方法无法触发。
配置代码
@SuppressLint("MissingPermission") override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { bluetoothGatt.requestMtu(517) } override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) { val characteristic = findCharacteristics() enableNotification(characteristic) } fun ByteArray.toHexString(): String = joinToString(separator = "", prefix = "") { String.format("%02X", it) } override fun onCharacteristicChanged( gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray ) { Log.d("CHAR", value.toHexString()) }
权限检查逻辑
private fun checkPermissions() { when { Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { requestPermissions.launch( arrayOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT ) ) } Build.VERSION.SDK_INT < Build.VERSION_CODES.S -> { requestPermissions.launch( arrayOf( Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, ) ) } } } private val requestPermissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions -> permissions.forEach { (key, value) -> when (key) { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION -> { if (!value) { ActivityCompat.requestPermissions( requireActivity(), arrayOf( Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION ), 1 ) } } Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT -> { if (!value) { ActivityCompat.requestPermissions( requireActivity(), arrayOf( Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT ), 1 ) } } } } }
Android 11上的运行日志
D/BluetoothGatt: onConnectionUpdated() - Device=7C:9E:BD:07:3D:82 interval=6 latency=0 timeout=500 status=0 D/BluetoothGatt: onSearchComplete() = Device=7C:9E:BD:07:3D:82 Status=0 D/BluetoothGatt: configureMTU() - device: 7C:9E:BD:07:3D:82 mtu: 517 D/BluetoothGatt: onConfigureMTU() - Device=7C:9E:BD:07:3D:82 mtu=517 status=0 D/BluetoothGatt: setCharacteristicNotification() - uuid: 00001103-0000-1000-8000-00805f9b34fb enable: true
排查与解决方向
补全权限声明:Android 11除了位置权限,需在Manifest中添加正常权限:
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />同时确保设备位置服务处于开启状态,Android 11中BLE通知依赖位置服务,仅授予权限但关闭位置会导致接收异常。
完善通知配置:仅调用
setCharacteristicNotification不够,必须配置客户端特征描述符(CCCD),检查enableNotification实现:@SuppressLint("MissingPermission") fun enableNotification(characteristic: BluetoothGattCharacteristic) { bluetoothGatt.setCharacteristicNotification(characteristic, true) val cccdUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") val descriptor = characteristic.getDescriptor(cccdUuid) ?: return descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE bluetoothGatt.writeDescriptor(descriptor) }可通过
onDescriptorWrite回调确认描述符写入是否成功。验证特征有效性:在
onMtuChanged中打印characteristic的UUID,确认findCharacteristics()确实找到了目标特征,同时检查该特征是否具备PROPERTY_NOTIFY或PROPERTY_INDICATE属性。处理系统缓存异常:重启设备蓝牙,或清除应用的蓝牙缓存,部分Android 11设备存在蓝牙服务缓存问题导致通知失效。
内容的提问来源于stack exchange,提问作者Helvio Siqueira
相关产品推荐
相关产品推荐

