问题描述
我是Android BLE的新手,所以我的问题在某种程度上可能是不正确的或天真的。如果是这种情况,请向我解释我的错误,并告诉我管理此方案的正确方法。
I'm new in Android BLE so my question may be uncorrect or naive in some way. If this is the case please explain me where I'm wrong and kindly show me the correct way to manage this scenario.
方案如下:我的Android应用程序与之通信BLE设备使用BLE特性发送命令并从设备获取答案。
Scenario is the following: my Android app communicates with a BLE device sending commands and getting answers from device using BLE characteristics.
序列是:
- 设备唤醒应用程序(调用
onConnectionStateChange
方法) - 我的应用程序在特征中写入命令(I调用
writeCharacteristic
将命令放在值
参数中)。 - 设备将命令的答案发送回我的应用程序(
onCharacteristicChanged
方法被触发且值
参数包含答案)
- Device wakes up the app (the
onConnectionStateChange
method is called) - My app writes a command in a characteristic (I call
writeCharacteristic
putting the command invalue
parameter). - Device sends back the answer to command to my app (the
onCharacteristicChanged
method is triggered andvalue
parameter contains the answer)
唤醒应用程序后,设备不执行任何操作,直到命令为止通过 writeCharacteristic
发送。该设备接受不同的命令。
After waking up the app, the device doesn't do anything until a command is sent via writeCharacteristic
. The device accepts different commands.
到目前为止一切都很好,但最近我开发了第二个不同的应用程序来与同一设备通信。
All good so far, but recently I developed a second different app to communicate with same device.
当我在同一个Android手机上运行这两个应用程序时,一个应用程序会向设备发送命令,并且两个应用程序都会收到响应!当然,没有发送命令的应用程序收到意外的答案并进入意外状态。
When I run both apps on same Android phone, one app sends a command to the device and the response is received by both apps! Of course the app that didn't sent the command receives an unexpected answer and goes to an unexpected status.
好的,知道问题我可以修改我的两个应用程序来处理这种情况,但问题是:当同一设备中的两个应用程序与同一个BLE设备通信时,这种行为是否正常?
Ok, knowing the problem I can modify both my apps to handle this situation, but the question is: Is this behavior normal when two apps in same device communicate with same BLE device?
应用程序是否有办法建立通信使用BLE设备的频道,以避免将特定命令的答案发送到除发送请求的应用程序之外的任何其他应用程序?
Is there a way for an app to establish a communication channel with a BLE device to avoid sending answer to specific commands to any other app except the one that sent the request?
我的猜测是 writeCharacteristic
和 onNotificationChanged
不是这种通信的正确功能,但在这种情况下哪些是替代方案?
My guess is that writeCharacteristic
and onNotificationChanged
aren't the right functions for such kind of communication, but in this case which are the alternatives?
推荐答案
如果两个应用程序都具有到同一设备的GATT连接,则蓝牙标准本身不会定义多个应用程序的行为。在标准中只有一个GATT客户端。
The Bluetooth standard itself doesn't define anything how multiple apps would behave if both have a GATT connection to the same device. In the standard there is just one "GATT client".
现在,iOS和Android都朝着可能看起来不直观的方式迈出了一步。多个应用程序可以通过同一个GATT客户端连接到设备,而不是一次只允许一个应用程序进行通信。 OS多路复用来自/到应用的通信。行为是对读取和写入请求的响应只能由发出请求的应用程序查看。所以如果你只读readCharacteristic应用程序将获得onCharacteristicRead回调。然而,通知将被发送到onCharacteristicChanged回调的两个应用程序,因为将通知仅发送给一个是没有任何意义的。
Now both iOS and Android have taken one step further in a way that might seem unintuitive. Instead of only allowing one app at a time to communicate, multiple apps can be connected over the same GATT client to a device. The OS "multiplexes" the communication from/to the apps. The behaviour is that responses to read and write requests can only be seen by the app that made the request. So if you do readCharacteristic only that app will get the onCharacteristicRead callback. Notifications however will be delivered to both apps to the onCharacteristicChanged callback, since it wouldn't make any sense to send the notification to only one.
当你说对写入请求的响应是通知,这在GATT术语方面是不正确的。每个规范(或错误)对写请求的响应始终为空。如果您的外围设备发出通知,那么在您的情况下根据您自己的逻辑可能是答案,但它不是响应或与GATT规范的写请求相关的任何方式。这就是为什么Android不能(也不应该)只向一台设备发送通知的原因。
When you say that the "response" to a write request is the notification, that's not correct in terms of GATT terminology. The response to a write request is always empty per specification (or an error). If your peripheral emits a notification, then in your case that might be the "answer" according to your own logic, but it's not a response or any way related to your write request per the GATT specification. That's why Android can't (and shouldn't) send the notification to only one device.
我建议您只是忽略您不期望的通知。如果要将答案与写入请求相关联,则可以更改协议以在两个数据包中包含事务ID,以便匹配它们。
I suggest that you simply ignore notifications you are not expecting. If you want to associate an "answer" to a write request, you can change your protocol to include a transaction id in both packets so they can be matched.
当我在上面写app,我的意思是BluetoothGatt对象。您可以使用同一个应用程序中的同一个远程设备调用connectGatt两次,其行为与从两个不同应用程序连接时的行为相同。
When I write "app" above, I really mean BluetoothGatt objects. You can call connectGatt twice with the same remote device in the same app, which will behave the same as if you connected from two different apps.
这篇关于BLE设备与同一设备上的不同Android应用程序之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!