我正在尝试通过BLE从多个功能中获取通知,我在互联网上看到了一些解决方案,需要等待onDescriptorWrite()
回调完成(我认为我在这里做了什么? ),但我无法第二次执行onDescriptorWrite()
来通知FILE_TX(在此处编码)。当我建立BLE连接时,所有这些操作都在onServicesDiscovery()
下执行。
我在这里做错什么了吗?
一次只能执行一次出色的gatt操作。在这种情况下,您要先执行两次writeDescriptor调用,然后再等待第一个完成。您必须等待https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback.html#onDescriptorWrite(android.bluetooth.BluetoothGatt,android.bluetooth.BluetoothGattDescriptor,int),才能发送下一个。
这是我能找到的最佳答案,但是您怎么能知道onDescriptorWrite已经完成?
我尝试将Thread.sleep(500)
放在两者之间以进行解决,但我也没有用。
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")
}
}
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
答案 0 :(得分:1)
我建议您使用Nordic SemiConductor的Android BLE Library来代替自己构建系统。我花了四个月的时间来尝试自己做。该库使您可以使用带有已定义的回调的异步执行调用,而不必担心此类问题。
答案 1 :(得分:1)
我发现在使用Android BLE堆栈时遵循两点很有用。
在上面的代码中,您正在将编写描述符嵌套在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堆栈构建通信应用程序,将如何处理它。