安卓BLE:来自一个服务下的多个特征的通知



>PROBLEM

我正在尝试通过 BLE 从多个特征获取通知,我在互联网上看到了一些解决方案,我需要等到onDescriptorWrite()回调完成(我想我在这里做了什么?(,但我不能第二次为FILE_TX(代码在那里(通知做onDescriptorWrite()。所有这些都是在onServicesDiscovery()下执行的 - 当我建立 BLE 连接时.

我在这里做错了什么吗?

您一次只能有一个未完成的关贸总协定操作。在这种情况下,您需要执行两次 writeDescriptor 调用,然后再等待第一次调用完成。您必须等待 https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback.html#onDescriptorWrite(android.bluetooth.BluetoothGatt,android.bluetooth.BluetoothGattDescriptor,int(,直到您可以发送下一个。

这是我能找到的最佳答案,但是您如何判断onDescriptorWrite已经完成?

我尝试将Thread.sleep(500)放在两者之间以变通,但我也不工作。

在 onServicesDiscovery - gattCallback 下

for (gattCharacteristic in gattCharacteristics) {
uuid = gattCharacteristic.uuid
// // Log.d("GATT", "$uuid")
if (gattCharacteristic.uuid.equals(UUID_CHARACTERISTIC_READ_FILE_TX)) {
gatt.setCharacteristicNotification(gattCharacteristic, true)
val descriptorfile: BluetoothGattDescriptor = gattCharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID) ?: error("Required Client Characteristic Configuration not found")
descriptorfile.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
isSuccess = gatt.writeDescriptor(descriptorfile)
Log.d("tagfile", "FILE_TX Successful ? " + isSuccess)
gattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
Log.d("tagfile", "Found Transparent service File Tx characteristics")
}
else if (gattCharacteristic.uuid.equals(UUID_CHARACTERISTIC_TX)) {
gatt.setCharacteristicNotification(gattCharacteristic, true)
val descriptor: BluetoothGattDescriptor = gattCharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_UUID) ?: error("Required Client Characteristic Configuration not found")
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)
isSuccess = gatt.writeDescriptor(descriptor)
Log.d("tagfile", "TX Successful ? " + isSuccess)
gattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
Log.d("tagfile", "Found Transparent service Tx characteristics")
}
if (gattCharacteristic.uuid.equals(UUID_CHARACTERISTIC_RX)) {
gattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
Log.d("tagfile", "Found Transparent service Rx characteristics")
}
else if (gattCharacteristic.uuid.equals(UUID_CHARACTERISTIC_READ_FILE_RX)) {
gattCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
Log.d("tagfile", "Found Transparent service File Rx characteristics")
}
}

在 onDescriptorWrite - gattCallback 下

override fun onDescriptorWrite(
gatt: BluetoothGatt?,
descriptor: BluetoothGattDescriptor?,
status: Int
) {
Log.d("tagfile", "Status of gatt : " + status + "       GATT FAILURE : " + BluetoothGatt.GATT_FAILURE)
}

结果:

2020-01-24 09:41:51.359 8565-8587/com.example.ricco_ble D/tagfile: TX Successful ? true
2020-01-24 09:41:53.359 8565-8587/com.example.ricco_ble D/tagfile: Found Transparent service Tx characteristics
2020-01-24 09:41:53.360 8565-8587/com.example.ricco_ble D/tagfile: Found Transparent service Rx characteristics
2020-01-24 09:41:53.371 8565-8587/com.example.ricco_ble D/tagfile: FILE_TX Successful ? false
2020-01-24 09:41:53.371 8565-8587/com.example.ricco_ble D/tagfile: Found Transparent service File Tx characteristics
2020-01-24 09:41:53.372 8565-8587/com.example.ricco_ble D/tagfile: Found Transparent service File Rx characteristics
2020-01-24 09:41:53.424 8565-8587/com.example.ricco_ble D/tagfile: Status of gatt : 0       GATT FAILURE : 257

与其尝试自己构建系统,我建议使用Nordic SemiConductor的Android BLE库。我花了4个月的时间尝试自己做。此库允许您使用具有定义的回调的异步执行调用,而不必担心此类问题。

我发现在使用Android BLE堆栈时遵循两点很有用。

  1. 在任何 Gatt 回调中,只执行结果复制,并安排下一个任务要执行(执行(。以便可以尽快释放回调函数。
  2. 按顺序执行操作。在收到上一个操作的回调之前,不要执行下一个操作。

从上面的代码帖子中,您将在 serviceDiscovery 回调中嵌套编写描述符。此外,您在接收上一个回调之前编写下一个描述符。

为了获得更稳定/可预测的性能,您可以将代码重构为类似

BluetoothGattCallback(){
onServiceDiscovery(gatt){
MainHandler.post((gatt)->setFirstNotification(gatt)) //do the scheduling, not direct execution here.
}
onDescriptorWrite(gatt){
if(the first descriptor write success) {
MainHandler.post((gatt)->setSecondNotification(gatt)) //do the scheduling
} else if (the second descriptor write success) {
MainHandler.post((gatt)->otherLogic(gatt)) //do the scheduling
}
} 
}
fun setFirstNotification(gatt){
//your code to set descriptor value
}

fun setSecondNotification(gatt){
//your code to set descriptor value
}
fun otherLogic(gatt){
//your other code
}

这大致是如果你想直接使用 Android 堆栈构建你的通信应用程序,你会如何处理它的想法。

最新更新