5

我是 Android BLE 的新手,所以我的问题在某种程度上可能不正确或幼稚。如果是这种情况,请向我解释我错在哪里,并请告诉我管理这种情况的正确方法。

场景如下:我的 Android 应用程序与 BLE 设备通信,发送命令并使用 BLE 特性从设备获取答案。

顺序是:

  • 设备唤醒应用(onConnectionStateChange方法被调用)
  • 我的应用程序在特征中写入命令(我writeCharacteristic称将命令放入value参数中)。
  • 设备将命令的答案发送回我的应用程序(该onCharacteristicChanged方法被触发并且value参数包含答案)

唤醒应用程序后,设备不会执行任何操作,直到通过writeCharacteristic. 设备接受不同的命令。

到目前为止一切都很好,但最近我开发了第二个不同的应用程序来与同一设备通信。

当我在同一部 Android 手机上运行这两个应用程序时,一个应用程序向设备发送命令,两个应用程序都会收到响应!当然,未发送命令的应用程序会收到意外的答案并进入意外状态。

好的,知道问题我可以修改我的两个应用程序来处理这种情况,但问题是:当同一设备中的两个应用程序与同一 BLE 设备通信时,这种行为是否正常?

有没有办法让应用程序与 BLE 设备建立通信通道,以避免向除发送请求的应用程序之外的任何其他应用程序发送特定命令的响应?

我的猜测是,这writeCharacteristic不是onNotificationChanged这种通信的正确功能,但在这种情况下,哪些是替代方案?

4

1 回答 1

9

蓝牙标准本身并没有定义如果多个应用程序都通过 GATT 连接到同一设备时的行为方式。在标准中只有一个“GATT 客户端”。

现在,iOS 和 Android 都以一种看似不直观的方式向前迈进了一步。多个应用程序可以通过同一个 GATT 客户端连接到一个设备,而不是一次只允许一个应用程序进行通信。操作系统“多路复用”来自/到应用程序的通信。行为是对读取和写入请求的响应只能由发出请求的应用程序看到。因此,如果您执行 readCharacteristic,则只有该应用程序将获得 onCharacteristicRead 回调。然而,通知将通过 onCharacteristicChanged 回调传递给两个应用程序,因为只将通知发送给一个应用程序没有任何意义。

当您说对写入请求的“响应”是通知时,就 GATT 术语而言,这是不正确的。根据规范(或错误),对写入请求的响应始终为空。如果您的外围设备发出通知,那么在您的情况下,根据您自己的逻辑,这可能是“答案”,但它不是响应或与 GATT 规范中的写入请求相关的任何方式。这就是为什么 Android 不能(也不应该)将通知仅发送到一台设备的原因。

我建议您直接忽略您不期望的通知。如果您想将“答案”与写入请求相关联,您可以更改协议以在两个数据包中包含事务 ID,以便它们可以匹配。

当我在上面写“app”时,我的意思是 BluetoothGatt 对象。您可以在同一个应用程序中使用同一远程设备调用 connectGatt 两次,其行为与您从两个不同的应用程序连接时的行为相同。

于 2018-05-03T21:38:07.767 回答