Android BLE BluetoothGatt.writeDescriptor()有时返回false

时间:2017-11-03 13:46:27

标签: android bluetooth-lowenergy

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

我没有在文档中找到任何关于此功能的限制说明。但是堆栈溢出上的ppl说我需要在尝试编写另一个描述符之前等待BluetoothGattCallback.onDescriptorWrite()

这是一个回复说BLE is busy与writeDescriptor()并不能做其他写。

以下是another thread,说你不能再调用writeCharacteristic()。

我的问题是

  • 这是真的吗?
  • 是否真的缺少一些用于序列化BLE请求的内部android API缓冲区,每个开发人员都必须自己做?
  • 对于不同的功能是否属实?例如,当我致电writeDescriptor()时,我知道在收到writeDescriptor()之前我无法再次拨打onDescriptorWrite()。但是,当我想拨打onDescriptorWrite()时,我是否必须等待writeCharacteristic()
  • 此外,如果存在功能间依赖性,那么还有哪些功能具有此限制(即:readCharacteristic()readDescriptor()requestMtu() ...)?
  • 另外还有BluetoothGattServer和BluetoothGatt之间的相互依赖性。例如,当我致电BluetoothGattServer.notifyCharacteristicChanged()时,我是否应该等BluetoothGattServerCallback.onNotificationSent才能拨打BluetoothGatt.writeDescriptor()BluetoothGatt.writeCharacteristic()? (BTW对谷歌文档onNotificationSent()的称赞可以通过运气得到正确记录.Doc说:
  

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

  • 最后提出所有这些问题 - 我觉得Android BLE API的记录不足。或者我错了,并且在某处记录了允许调用序列的方法?如果是,请指点我这样的文件?如果不是有一些渠道,我们可以打开谷歌的问题,并要求他们添加到文档的东西?我的意思是它可能不是很多文本 - 像onNotificationSent()这样的函数是正确记录的。他们只需要将这句话复制到其他功能。

1 个答案:

答案 0 :(得分:8)

文档缺乏信息。但是,您可以阅读源代码以查找规则,其中(当前)如下:

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

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

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

关于更新文档,您总是可以尝试在https://issuetracker.google.com处提交问题(但我感觉没人会读到),或者,因为Android是开源的,所以向{{3}发送拉取请求}更新生成文档的Javadoc。