Kotlin实现BLE设备读写功能的问题求助(附Swift参考)
问题解决:BLE无响应写入与通知数据读取
1. 过时setValue方法的替代方案
Android 中BluetoothGattCharacteristic.setValue(byte[])方法过时后,可使用带偏移和长度的重载方法替代,针对完整字节流的写入写法如下:
writeCharacteristic?.setValue(value, 0, value.size)
如果是特定格式的数据(如整型、浮点型),可使用对应格式的重载方法(比如setValue(int value, int format, int offset)),但自定义字节流场景用上述写法即可满足需求。
2. 修正读写逻辑中的关键问题
(1)无响应写入的特征匹配错误
当前用PROPERTY_WRITE判断写入特征,但无响应写入对应的属性是PROPERTY_WRITE_NO_RESPONSE。部分设备会将带响应写入和无响应写入分为不同特征,不修正会导致写入失败。调整服务发现中的判断逻辑:
// 匹配无响应写入特征 if (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE != 0) { writeCharacteristic = characteristic Log.v("Bluetooth: Services discovered", "No-response Write characteristic ${characteristic.uuid}") } // 如需支持带响应写入,保留原有判断 if (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_WRITE != 0) { // 可单独存储带响应写入特征 }
(2)通知通道未完成完整配置
仅调用setCharacteristicNotification(characteristic, true)无法真正开启通知,必须写入客户端特征配置描述符(CCCD)。在服务发现中找到通知特征后,补充以下代码:
if (characteristic.properties and BluetoothGattCharacteristic.PROPERTY_NOTIFY != 0) { notifyCharacteristic = characteristic Log.v("Bluetooth: Services discovered", "Notify characteristic $notifyCharacteristic") // 开启通知开关 gatt?.setCharacteristicNotification(characteristic, true) // 获取CCCD描述符并写入启用通知的值 val descriptor = characteristic.getDescriptor( UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") ) descriptor?.value = BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE gatt?.writeDescriptor(descriptor) }
(3)通知回调未读取数据
onCharacteristicChanged回调中需从特征中提取实际数据,修正如下:
override fun onCharacteristicChanged( gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic? ) { super.onCharacteristicChanged(gatt, characteristic) val receivedData = characteristic?.value receivedData?.let { Log.i("Notification", "Received data: ${it.contentToString()}") // 在此处理接收到的字节数据 } }
(4)写入流程的正确性检查
确保写入流程满足以下条件:
- 写入特征已正确获取(非null)
- 已设置
writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE - 可新增
onCharacteristicWrite回调确认写入发起状态:
override fun onCharacteristicWrite( gatt: BluetoothGatt?, characteristic: BluetoothGattCharacteristic?, status: Int ) { super.onCharacteristicWrite(gatt, characteristic, status) if (status == BluetoothGatt.GATT_SUCCESS) { Log.v("ble write", "Write initiated successfully") } else { Log.e("ble write", "Write failed with status: $status") } }
3. 完整写入函数修正
fun write() { val value = byteArrayOf( 0x02.toByte(), 0x03.toByte(), 0x24.toByte(), 0x65.toByte(), 0x01.toByte(), 0xBE.toByte(), 0xF8.toByte(), 0x03.toByte() ) writeCharacteristic?.let { char -> char.setValue(value, 0, value.size) char.writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE gatt?.writeCharacteristic(char) Log.v("ble write", "Initiated no-response write to ${char.uuid}") } ?: run { Log.e("ble write", "Write characteristic not found") } }
内容的提问来源于stack exchange,提问作者Swifty
相关产品推荐
相关产品推荐

