Android端BLE设备断开GATT服务器后才接收数据的问题求助
BLE GATT写入成功但设备仅在断开连接时响应的问题
我尝试通过GATT服务器向BLE设备发送命令字符串,GattCallback显示写入成功,但设备无任何响应;只有退出应用(断开GATT连接)时,BLE设备才会收到数据。以下是相关代码,求解决:
GattCallback代码
private val gattCallback: BluetoothGattCallback = object : BluetoothGattCallback() { override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) { super.onConnectionStateChange(gatt, status, newState) if( status == BluetoothGatt.GATT_FAILURE ) { disconnect() return } else if( status != BluetoothGatt.GATT_SUCCESS ) { disconnect() return } if( newState == BluetoothProfile.STATE_CONNECTED ) { Log.d(TAG, "Connected to the GATT server") gatt.discoverServices() } else if ( newState == BluetoothProfile.STATE_DISCONNECTED ) { disconnect() } } override fun onServicesDiscovered(gatt: BluetoothGatt?, status: Int) { super.onServicesDiscovered(gatt, status) if (status != BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "Device service discovery failed, status: $status") return } Log.d(TAG, "Services discovery is successful") isStatuschanged = "connected" val respCharacteristic = gatt?.let { BluetoothUtils.findResponseCharacteristic(it) } if( respCharacteristic == null ) { Log.e(TAG, "Unable to find cmd characteristic") disconnect() return } gatt.setCharacteristicNotification(respCharacteristic, true) val descriptor: BluetoothGattDescriptor = respCharacteristic.getDescriptor( UUID.fromString(CLIENT_CHARACTERISTIC_CONFIG) ) descriptor.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE gatt.writeDescriptor(descriptor) } override fun onCharacteristicChanged( gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic ) { super.onCharacteristicChanged(gatt, characteristic) readCharacteristic(characteristic) } override fun onCharacteristicWrite( gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int ) { super.onCharacteristicWrite(gatt, characteristic, status) if (status == BluetoothGatt.GATT_SUCCESS) { Log.d(TAG, "Characteristic written successfully") } else { Log.e(TAG, "Characteristic write unsuccessful, status: $status") disconnect() } } override fun onCharacteristicRead( gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic, status: Int ) { super.onCharacteristicRead(gatt, characteristic, status) if (status == BluetoothGatt.GATT_SUCCESS) { Log.d(TAG, "Characteristic read successfully") readCharacteristic(characteristic) } else { Log.e(TAG, "Characteristic read unsuccessful, status: $status") } } }
写入函数代码
fun write(message: String) { val cmdCharacteristic = BluetoothUtils.findCommandCharacteristic(bluetoothGatt!!) if (cmdCharacteristic == null) { Log.e(TAG, "Unable to find cmd characteristic") disconnect() return } cmdCharacteristic?.value = message.toByteArray() val success: Boolean = bluetoothGatt!!.writeCharacteristic(cmdCharacteristic) if (!success) { Log.d("jay", "failed to write command") } Log.d("jay", "write succesful") }
断开连接函数代码
fun disconnect() { Log.d("jay", "disconnect: bluetoothGatt is null? ${bluetoothGatt == null}") bluetoothDeviceAddress = null bluetoothGatt?.disconnect() isStatuschanged = "disconnected" bluetoothGatt = null }
问题原因及解决方法
这种现象通常是因为BLE特性的写入类型配置错误,或者Android端没有正确触发设备端的数据提交,以下是具体解决步骤:
1. 显式设置特性写入类型
确保命令特性的写入类型设置为BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT或WRITE_TYPE_NO_RESPONSE,避免依赖断开连接时的延迟提交。修改写入函数:
fun write(message: String) { val cmdCharacteristic = BluetoothUtils.findCommandCharacteristic(bluetoothGatt!!) if (cmdCharacteristic == null) { Log.e(TAG, "Unable to find cmd characteristic") disconnect() return } // 显式指定写入类型 cmdCharacteristic.writeType = BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT cmdCharacteristic.value = message.toByteArray() val success: Boolean = bluetoothGatt!!.writeCharacteristic(cmdCharacteristic) if (!success) { Log.d("jay", "failed to send write command request") } }
2. 等待写入回调确认后再操作
Android的BLE写入是异步的,writeCharacteristic返回true仅表示请求已发送,不代表设备已接收。需要在onCharacteristicWrite回调确认成功后,再发起后续操作,避免请求堆积。
3. 检查设备端特性权限
确认BLE设备的命令特性已开启PROPERTY_WRITE或PROPERTY_WRITE_NO_RESPONSE属性权限,无对应权限会导致数据无法被设备正确接收。
4. 避免GATT操作并发
BLE GATT操作是串行的,不能同时发起多个写入/读取请求。如果有批量写入需求,需等待前一个操作的回调完成后再发起下一个。
内容的提问来源于stack exchange,提问作者AndroidDeveloperJJ
相关产品推荐
相关产品推荐

