Android BLE:一项服务下来自多个特征的通知

时间:2020-01-23 23:02:17

标签: android kotlin bluetooth bluetooth-lowenergy esp32

问题

我正在尝试通过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)放在两者之间以进行解决,但我也没有用。

在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

2 个答案:

答案 0 :(得分:1)

我建议您使用Nordic SemiConductor的Android BLE Library来代替自己构建系统。我花了四个月的时间来尝试自己做。该库使您可以使用带有已定义的回调的异步执行调用,而不必担心此类问题。

答案 1 :(得分:1)

我发现在使用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堆栈构建通信应用程序,将如何处理它。