原生 Android BLE 实现本质上是同步的吗?

Posted

技术标签:

【中文标题】原生 Android BLE 实现本质上是同步的吗?【英文标题】:Is the native Android BLE implementation synchronous in nature? 【发布时间】:2013-08-03 10:11:09 【问题描述】:

我记得在"Guide and Hint"-doc 中阅读到Samsung BLE API (archived page):

三星 F/W 和堆栈最重要的概念之一是 它的同步性质。也就是说,如果我们调用例如, writeCharacteristic 用于特定特征,如果它返回 true,下一次调用任何BluetoothGattBluetoothGattServer 方法 应该在收到onCharacteristicRead 回调后完成。 这是因为堆栈设计为仅支持和处理一个 GATT 一次调用,例如,如果您调用 writeCharacteristicreadCharacteristic 很快就会有任何特性 在第一个之后,它被忽略了。

    这是否也适用于引入的 BLE 的本机实现 在 android 4.3 中? Samsung API 一次也只支持一个连接的 GATT 设备。 这在原生 API 中是否发生了变化?

【问题讨论】:

Google 的问题跟踪器上有一个与 API 的同步性质相关的线程:code.google.com/p/android/issues/detail?id=58381 我刚刚为所有写入实现了一个队列,到目前为止这似乎运行良好。 @Ash 根据 SAMSUNG 提供的文档,行为不限于写操作。是的,使用队列是解决该问题的常用方法。 “到目前为止运行良好”:很难测试和重现另一个命令取消的情况。当你的 BLE 代码变得更复杂时,你经常会遇到问题,因为你根据之前的调用做了更多的事情。我只在完成之前的一个(收到答案)之后或之前的一个未能在适当的时间完成之后进行下一个 BLE 操作。顺便说一句,你的 cmets 更适合作为这个问题的答案。 @Ash 你能分享你的实现吗? @Ewoks gist.github.com/SoulAuctioneer/ee4cb9bc0b3785bbdd51 【参考方案1】:

三星最近在我在问题中链接的同一页面上发布了“迁移”文档。在将新的原生 BLE API 与三星 BLE API 进行比较时,他们准确地回答了我的问题:

堆栈和 F/W 的同步特性没有受到影响。 也就是说,例如,如果我们调用 writeCharacteristic 来获取特定的 特征,如果返回true,则下一次调用任何BluetoothGattBluetoothGattServer 方法应在收到onCharacteristicRead 回调后执行。这是因为栈是设计的 一次只支持和处理一个 GATT 调用,并且如果,对于 例如,您在第一个之后不久调用任何characteristic 中的writeCharacteristicreadCharacteristic,它将被忽略。

【讨论】:

我很高兴找到了这个问题。谷歌并没有竭尽全力说明这一点。当读/写请求实际上被忽略时返回 true 非常令人困惑。 谁能确认 android.bluetooth.BluetoothGatt 是否只能处理一个待处理的 GATT 操作 PER DEVICEPER PROCESSPERIOD (即:跨所有进程)。我认为它是 PER DEVICE,但这个问题太复杂了,如果不是这样,我不会感到惊讶。如果限制只是每个设备,那么能够处理多个同时操作的操作系统/设备就是确凿证据证明这个问题纯粹是由于操作系统处理每个进程的 BluetoothAdapter 实例中的一些弱幼稚实现(我曾假设跨所有进程的单例)。 每个 BluetoothGatt 对象都有一个待处理的操作。 @Emil 我刚刚回滚了您对该问题的更改。请不要修改三星工程师的报价。如果您对其内容有疑问,请将其添加为评论。 嗯,这是一个明显的错字。您在写入请求后等待写入响应。写入请求后您无需等待读取响应...【参考方案2】:
    没有。大多数函数调用都是异步的。 我不知道。官方文档没有提到它,但也没有说它只支持一种设备。我相信这是可能的。查看这篇文章:http://blog.lemberg.co.uk/getting-bottom-android-bluetooth-low-energy-api#.UfvK6ZK-1cY

它说(我不知道它的来源是)多个外围设备可以连接到一个 Android Central 设备

【讨论】:

三星 ble API 在某种程度上也是异步的。您在回调中得到答案(顺便说一下,API 非常相似) 但是,如果您在短时间内触发 2 个请求,而第一个请求没有完全进行,第一个请求可能会被取消。所以问题是,如果原生 API 也有这种行为。 嗯好的,现在我明白了。我不知道本机 API 是否遵循这种行为。我想是这样。如果你触发 2 个 scanBLE,前一个会被取消,但我不确定。

以上是关于原生 Android BLE 实现本质上是同步的吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用android原生BLE蓝牙进行操作?

Android Fragments 基础知识:为啥?这在概念上是错误的吗?

我可以在 iOS 上模拟 BLE 设备并设置其名称吗? (反应原生)

如何在 Android 的原生视图之上覆盖 PhoneGap 的 CordovaWebView?

Android 系统性能优化

Tars环境搭建之路