问题描述
我正在尝试编写BLE Android应用.我发现有时候我打电话时 BluetoothGatt.writeDescriptor()它返回false.
I'm trying to write BLE Android app. I found that sometimes when I call BluetoothGatt.writeDescriptor() it returns false.
我在文档中没有发现任何限制此功能的记录.但是栈上的ppl表示我需要等待 BluetoothGattCallback.onDescriptorWrite(),然后再尝试编写另一个描述符.
I have not found in documentation any note of limitation to this function. But ppl on stack overflow says that I need to wait for BluetoothGattCallback.onDescriptorWrite() before I try to write another descriptor.
这里有一封回复说, BLE正在使用writeDescriptor()忙,并且无法执行其他写操作.
Here is one reply saying that BLE is busy with writeDescriptor() and can not do other write.
这是另一个线程,表示您不能调用两次writeCharacteristic().
Here is another thread saying that you can not call twice writeCharacteristic().
我的问题是
- 真的是真的吗?
- 是否真的缺少用于序列化BLE请求的内部android API缓冲区,并且每个开发人员都必须自己完成?
- 不同功能是否正确?例如,当我呼叫
writeDescriptor()
时,我知道在收到onDescriptorWrite()
之前无法再次呼叫writeDescriptor()
.但是,要呼叫writeCharacteristic()
时是否必须等待onDescriptorWrite()
? - 如果还存在函数间依赖关系,那么还有哪些函数具有此限制(即:
readCharacteristic()
,readDescriptor()
,requestMtu()
...)? - 此外,BluetoothGattServer和BluetoothGatt之间存在相互依赖性.因此,例如,当我呼叫
BluetoothGattServer.notifyCharacteristicChanged()
时,我应该等待BluetoothGattServerCallback.onNotificationSent
,然后才能呼叫BluetoothGatt.writeDescriptor()
或BluetoothGatt.writeCharacteristic()
? (顺便说一句,对Google文档onNotificationSent()
的称赞是幸运的,有据可查.Doc说:
- is it really true?
- is there really missing some internal android API buffer for serializing BLE requests and every developer has to do it on it's own?
- Is it true for different functions? For example when I call
writeDescriptor()
I understand I can not call second timewriteDescriptor()
before I receiveonDescriptorWrite()
. But do I have to wait foronDescriptorWrite()
when I want to callwriteCharacteristic()
? - Also if there is inter-function dependency then what else function have this limitation (namely:
readCharacteristic()
,readDescriptor()
,requestMtu()
...)? - And additionally is there interdependency between BluetoothGattServer and BluetoothGatt. So for example when I call
BluetoothGattServer.notifyCharacteristicChanged()
shall I wait forBluetoothGattServerCallback.onNotificationSent
before I can callBluetoothGatt.writeDescriptor()
orBluetoothGatt.writeCharacteristic()
? (BTW praise for google documentationonNotificationSent()
is by luck documented properly. Doc says:
- 几乎所有这些问题-我觉得Android BLE API的文档不足.还是我错了,在某处记录了允许使用什么方法调用序列?如果可以,请给我指出这些文件吗?如果没有,我们可以通过一些渠道向Google公开问题,并要求他们在文档中添加一些内容?我的意思是文字可能不多-正确记录了
onNotificationSent()
之类的某些功能.他们只需要将此句子复制到其他功能即可. - Lastly having all this questions - I feel that Android BLE API is under-documented. Or am I wrong and there is documented somewhere what are allowed methods calling sequences? If yes can you please point me to such documentation? If not is there some channel we can open issue with google and ask them to add to documentation something? I mean it may not be much text - some function like
onNotificationSent()
is arleady properly documented. They just need to copy this sentence to other functions.
推荐答案
文档缺少信息.但是,您可以阅读源代码以找出规则,这些规则(当前)如下:
The documentation lacks information. However you can read the source code to find out the rules, which (currently) are the following:
对于每个BluetoothGatt
对象,一次只能有一个未完成的请求,包括requestMtu
,readCharacteristic
,writeCharacteristic
,readDescriptor
,writeDescriptor
和executeReliableWrite
.因此,如果发出读取请求,则在发出写入请求之前需要等待读取响应.他们实施了代码,如果 BluetoothGatt.java ,他们忘记为requestMtu
执行此操作,因此如果您同时有多个请求,而requestMtu
是其中之一,则您会更快地收到随机错误.或更高版本(在发布本文时为最新版本).
For each BluetoothGatt
object, you can only have one outstanding request at a time, including requestMtu
, readCharacteristic
, writeCharacteristic
, readDescriptor
, writeDescriptor
and executeReliableWrite
. So if you issue a read request you need to wait for the read response before you issue a write request. While they implemented the code that returns false if there is an ongoing operation in BluetoothGatt.java, they forgot to do this for requestMtu
, so if you have multiple requests at a time where requestMtu
is one of them, you will get random errors sooner or later (in the latest versions at the time of this post).
是的,每个开发人员都必须手动序列化请求.请注意,蓝牙堆栈实际上有一个请求队列,但每个客户端仅限于一个请求(即BluetoothGatt对象).因此,如果同一部手机上的两个应用程序同时与同一台设备通话,您将永远不会遇到忙碌"错误.唯一的例外是,如果您使用无响应写"功能,则其当前数据流实现存在很多问题(请参见 https://issuetracker.google.com/issues/37121017 ,而Google似乎忽略了它.)
So yes, every developer has to manually serialize the requests. Note that the Bluetooth stack actually has a queue of requests, but it is limited to only one request per client (i.e. BluetoothGatt object). So if two apps on the same phone talk to the same device simultaneously you will never get "busy" errors. The only exception is if you use Write Without Response for which the current data flow implementation is quite buggy (see https://issuetracker.google.com/issues/37121017 which Google seems to have ignored).
由于服务器和客户端角色是分开的,因此您可以在编写特征时同时发送通知.
You can send notifications at the same time as you write a characteristic, since the server and client roles are separated.
关于更新文档,您总是可以尝试在 https://issuetracker.google.com (但我感觉没有人读过),或者,由于Android是开源的,因此向 https发送拉取请求://android-review.googlesource.com/会更新用于生成文档的Javadoc.
Regarding updating the documentation, you can always try to file an issue at https://issuetracker.google.com (but I get the feeling nobody reads that), or, since Android is open source, send a pull request to https://android-review.googlesource.com/ which updates the Javadoc from which the documentation is generated.
这篇关于Android BLE BluetoothGatt.writeDescriptor()有时返回false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!