Google Pixel与三星Galaxy设备BLE通知分片接收异常咨询
BLE通知异常:Google Pixel与三星Galaxy设备丢失分片响应第一部分
在Google Pixel和三星Galaxy系列设备上遇到BLE通知异常:当接收长度超过MTU的响应时,数据会被拆分为两部分,但上述设备仅能收到第二部分。
通信流程如下:
- 调用
discoverServices()完成服务发现 - 将MTU设置为512
- 通过指定
BluetoothGattCharacteristic发送初始消息 - 预期接收被拆分的JSON响应,但在Google Pixel和三星Galaxy设备上,
onCharacteristicChanged方法仅被调用一次(其他测试设备会调用两次)
该问题在Android 14中被发现,升级至Android 15后仍未解决,恳请排查原因。
补充信息
- Android版本:Android 14、Android 15
- 受影响设备:Google Pixel 6A、Galaxy Tab S8
相关代码
// STEP 1 - Connect to the BluetoothDevice fun connect(device: BluetoothDevice, context: Context) { try { device.connectGatt(context, false, callback) } catch (e: SecurityException) { Log.d("Error connecting to ${device.address}") } } private val callback = object : BluetoothGattCallback() { // STEP 2 - Request the services after a successful connection override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { try { val deviceAddress = gatt.device.address if (status == BluetoothGatt.GATT_SUCCESS) { if (newState == BluetoothProfile.STATE_CONNECTED) { Handler(Looper.getMainLooper()).post { gatt.discoverServices() } } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { disconnect() } } else { disconnect(status) } } catch (e: SecurityException) { Log.d("onConnectionStateChange: Error occurred $e") } } // STEP 3 - MTU request after a successful discoverServices() override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { try { with(gatt) { if (status == BluetoothGatt.GATT_SUCCESS) { requestMtu(512) } else { disconnect() } } } catch (e: SecurityException) { Log.d("onServicesDiscovered: Error occurred $e") } } // STEP 4 - Send message after setting the MTU properly override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) { if (status == BluetoothGatt.GATT_SUCCESS) { deviceBluetoothGatt!!.services?.firstOrNull { it.uuid == serviceUUID.uuid }?.let { service -> val characteristic = service.characteristics.first { it.uuid == readCharacteristicUUID } try { deviceBluetoothGatt!!.findCharacteristic(characteristic.uuid)?.let { _ -> val payload = when { characteristic.isIndicatable() -> BluetoothGattDescriptor.ENABLE_INDICATION_VALUE characteristic.isNotifiable() -> BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE else -> error("${characteristic.uuid} doesn't support notifications/indications") } characteristic.getDescriptor(configurationCharacteristicUUID)?.let { cccDescriptor -> if (!deviceBluetoothGatt!!.setCharacteristicNotification(characteristic, true)) { return } cccDescriptor.value = payload deviceBluetoothGatt!!.writeDescriptor(cccDescriptor) } ?: this@BLEManager.run { Log.e("${characteristic.uuid} doesn't contain the CCC descriptor!") } } ?: this@BLEManager.run { Log.e("Cannot find $characteristic.uuid! Failed to enable notifications.") } } catch (e: SecurityException) { Log.d("onMtuChanged: Error occurred: $e") } } } else { Log.d("onMtuChanged: Error occurred $e") disconnect() } } // STEP 5 - Receive the message on this callback in blocks override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) { with(characteristic) { decodeResponse(characteristic.value) } } override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) { with(descriptor) { when (status) { BluetoothGatt.GATT_SUCCESS -> { writeCharacteristic(GetinfoRequest().encode()) } BluetoothGatt.GATT_WRITE_NOT_PERMITTED -> { Log.d("Write not permitted for $uuid!") } else -> { Log.d("Descriptor write failed for $uuid, error: $status") } } } } }
内容的提问来源于stack exchange,提问作者Jose Maria
相关产品推荐
相关产品推荐

