【问题标题】:Android BLE BluetoothGatt.writeDescriptor() return sometimes falseAndroid BLE BluetoothGatt.writeDescriptor() 有时返回 false
【发布时间】:2017-11-03 13:46:27
【问题描述】:

我正在尝试编写 BLE Android 应用程序。我发现有时当我打电话时 BluetoothGatt.writeDescriptor() 它返回 false。

我在文档中没有发现任何对此功能的限制说明。但是 ppl on stack overflow 说我需要等待BluetoothGattCallback.onDescriptorWrite(),然后再尝试编写另一个描述符。

这里有一个回复说BLE is busy 使用 writeDescriptor() 并且不能进行其他写入。

这里是another thread 说你不能调用两次writeCharacteristic()。

我的问题是

  • 这是真的吗?
  • 是否真的缺少一些用于序列化 BLE 请求的内部 android API 缓冲区,并且每个开发人员都必须自己完成?
  • 是否适用于不同的功能?例如,当我拨打writeDescriptor() 时,我知道在收到onDescriptorWrite() 之前我不能第二次拨打writeDescriptor()。但是当我想拨打writeCharacteristic() 时,我必须等待onDescriptorWrite() 吗?
  • 另外,如果存在函数间依赖,那么还有哪些函数有此限制(即:readCharacteristic()readDescriptor()requestMtu()...)?
  • 此外,BluetoothGattServer 和 BluetoothGatt 之间存在相互依赖关系。例如,当我打电话给BluetoothGattServer.notifyCharacteristicChanged() 时,我应该等待BluetoothGattServerCallback.onNotificationSent,然后才能打电话给BluetoothGatt.writeDescriptor()BluetoothGatt.writeCharacteristic()? (顺便说一句,对谷歌文档onNotificationSent() 的赞美是幸运地记录正确。文档说:

当要发送多个通知时,应用程序必须等待 在发送附加信息之前接收此回调 通知。

  • 最后遇到所有这些问题 - 我觉得 Android BLE API 的文档不足。还是我错了,并且在某处记录了允许调用序列的方法?如果是的话,你能指点我这些文件吗?如果没有,我们可以通过谷歌打开问题并要求他们在文档中添加一些东西吗?我的意思是它可能没有太多的文字——像onNotificationSent() 这样的一些函数已经被正确记录了。他们只需要将这句话复制到其他函数中。

【问题讨论】:

    标签: android bluetooth-lowenergy


    【解决方案1】:

    文档缺少信息。但是,您可以阅读源代码以找出规则,(目前)如下:

    对于每个BluetoothGatt 对象,您一次只能有一个未完成的请求,包括requestMtureadCharacteristicwriteCharacteristicreadDescriptorwriteDescriptorexecuteReliableWrite。因此,如果您发出读取请求,则需要在发出写入请求之前等待读取响应。虽然他们实现了如果 BluetoothGatt.java 中存在正在进行的操作则返回 false 的代码,但他们忘记为 requestMtu 执行此操作,因此如果您同时有多个请求,而 requestMtu 是其中之一,您将得到迟早会出现随机错误(在本文发布时的最新版本中)。

    所以是的,每个开发人员都必须手动序列化请求。请注意,蓝牙堆栈实际上有一个请求队列,但仅限于每个客户端一个请求(即 BluetoothGatt 对象)。因此,如果同一部手机上的两个应用程序同时与同一台设备通话,您将永远不会出现“忙碌”错误。唯一的例外是,如果您使用无响应写入,当前的数据流实现存在相当多的错误(请参阅 Google 似乎已忽略的 https://issuetracker.google.com/issues/37121017)。

    您可以在编写特征的同时发送通知,因为服务器和客户端角色是分开的。

    关于更新文档,您可以随时尝试在 https://issuetracker.google.com 提交问题(但我感觉没人会阅读),或者,由于 Android 是开源的,因此向 https://android-review.googlesource.com/ 发送拉取请求以更新生成文档的 Javadoc。

    【讨论】:

    • 很好的解释!很难找到这个答案
    • 如何等待回复?
    • 等待调用对应的回调即可。例如,如果您调用writeCharacteristic,则需要在您的BluetoothGattCallback 中实现onCharacteristicWrite
    • 我也遇到了同样的问题,我发现这个维护队列的问题gist.github.com/SoulAuctioneer/ee4cb9bc0b3785bbdd51
    • 该代码似乎不是线程安全的,因此它可能会受到竞争条件的影响。请注意,onCharacteristicWrite 是从 Binder 线程调用的,通常不是您从中启动操作的线程。因此 txQueue 可能同时被两个线程使用。该代码还存在一个问题,即如果您连接到不同的蓝牙地址,则会泄漏之前的 BluetoothGatt 对象(作者忘记了它必须关闭)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 2019-05-06
    相关资源
    最近更新 更多