具有多种服务的 Android BLE Gatt 服务器 - onCharacteristicWriteRequest() 没有用于句柄的字符

Posted

技术标签:

【中文标题】具有多种服务的 Android BLE Gatt 服务器 - onCharacteristicWriteRequest() 没有用于句柄的字符【英文标题】:Android BLE Gatt Server with multiple services - onCharacteristicWriteRequest() no char for handle 【发布时间】:2019-07-02 14:48:53 【问题描述】:

我正在尝试构建具有多个自定义服务和多个特征的 BLE Gatt 服务器。

首先我使用了 Google 示例:https://github.com/androidthings/sample-bluetooth-le-gattserver/tree/master/kotlin

这很简单,而且效果很好。我修改了 UUID 以适应我的情况,我可以毫无问题地接收通知并写入字符。

这是我定义服务和字符的地方:

fun createTimeService(): BluetoothGattService 
        val service = BluetoothGattService(TIME_SERVICE,
                BluetoothGattService.SERVICE_TYPE_PRIMARY)

        // Current Time characteristic
        val currentTime = BluetoothGattCharacteristic(CURRENT_TIME,
                //Read-only characteristic, supports notifications
                BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PERMISSION_READ)
        val configDescriptor = BluetoothGattDescriptor(CLIENT_CONFIG,
                //Read/write descriptor
                BluetoothGattDescriptor.PERMISSION_READ or BluetoothGattDescriptor.PERMISSION_WRITE)
        currentTime.addDescriptor(configDescriptor)

        // Local Time Information characteristic
        val localTime = BluetoothGattCharacteristic(LOCAL_TIME_INFO,
                BluetoothGattCharacteristic.PROPERTY_WRITE,
                BluetoothGattCharacteristic.PERMISSION_WRITE)

        service.addCharacteristic(currentTime)
        service.addCharacteristic(localTime)

        return service
    

    fun createSerialService(): BluetoothGattService 
        val service = BluetoothGattService(serialPortServiceID,
                BluetoothGattService.SERVICE_TYPE_PRIMARY)

        val serialData = BluetoothGattCharacteristic(serialDataCharacteristicID,
        BluetoothGattCharacteristic.PROPERTY_WRITE,
        BluetoothGattCharacteristic.PERMISSION_WRITE)

        service.addCharacteristic(serialData)

        return service
    

在这里我将它们应用到我的服务器:

 private fun startServer() 
        bluetoothGattServer = bluetoothManager.openGattServer(this, gattServerCallback)

        bluetoothGattServer?.addService(TimeProfile.createTimeService())
                ?: Log.w(TAG, "Unable to create GATT server")

        bluetoothGattServer?.addService(TimeProfile.createSerialService())
                ?: Log.w(TAG, "Unable to create GATT server")

        // Initialize the local UI
        updateLocalUi(System.currentTimeMillis())
    

我希望在添加第二项服务后一切都会像以前一样工作。但是现在,如果我尝试编写/订阅任何特征(无论在哪个服务中),我都会收到:

W/BluetoothGattServer: onCharacteristicWriteRequest() no char for handle 42
W/BluetoothGattServer: onDescriptorWriteRequest() no desc for handle 43

【问题讨论】:

【参考方案1】:

我发现出了什么问题。显然,您不能像我一样一次添加所有服务。在确认第一个服务之前添加第二个服务会导致将服务设置为 null 的异常。

最后,我最初只添加了一项服务来解决这个问题。 然后在 BleGattServerCallback() 的 onServiceAdded() 回调中我一个接一个地启动。

【讨论】:

Android BLE API 在线程和排序方面是出了名的挑剔。我建议总是一次执行一个操作,这对于异步 API 来说有点困难。我经常定义一个像这样ExecutorService mWorker = Executors.newSingleThreadExecutor(); 的工作线程,然后像这样执行我的操作:mWorker.submit( /**gatt code here**/ )

以上是关于具有多种服务的 Android BLE Gatt 服务器 - onCharacteristicWriteRequest() 没有用于句柄的字符的主要内容,如果未能解决你的问题,请参考以下文章

Android BLE GATT 外设模式通知

如何在 android 中将特征写入 BLE GATT 服务器?

Android之Bluetooth通信-BLE(Gatt)客户端分析

BLE GATT 上传数据 - Android

我在 Android 应用程序(Java)和 ESP32 BLE 服务器之间的 Gatt 连接有问题

Android BLE - 连接到多个设备似乎失败并且两个连接的 GATT 响应相同?