简体   繁体   English

如何知道 BLE 指示是否在 Android 中被确认

[英]How to know if BLE indicate was acknowledged in Android

We are working on a Bluetooth Low Energy communication between two Android apps.我们正在研究两个 Android 应用程序之间的蓝牙低功耗通信。 One is the peripheral/server one the central/client.一个是外围/服务器,一个是中央/客户端。 The server will send an indicate to the clients if the data has changed.如果数据已更改,服务器将向客户端发送一个指示。 However, we didn't find a way to make sure that the data was actually acknowledged on the client side.但是,我们没有找到一种方法来确保数据在客户端得到实际确认。 How can we figure out, if the client received and acknowledged the data in order to react accordingly on the server side to it?我们如何确定客户端是否收到并确认了数据,以便在服务器端做出相应的反应?

According to Android documentation there is the callback onNotificationSent for the BleutoothGattServer.根据 Android 文档,BleutoothGattServer 有回调 onNotificationSent。 https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback#onNotificationSent(android.bluetooth.BluetoothDevice,%20int) https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback#onNotificationSent(android.bluetooth.BluetoothDevice,%20int)

However by debugging and doing some tests it seems this method really is just called if the notification is sent.然而,通过调试和做一些测试,如果通知被发送,这个方法似乎真的被调用了。 There is no guarantee the message was actually received nor acknowledged.无法保证实际收到或确认消息。

So here is how we setup the characteristics for the GattServer所以这里是我们如何设置 GattServer 的特性

BluetoothGattService service = new BluetoothGattService(SERVICE_LOGIN_UUID,
                BluetoothGattService.SERVICE_TYPE_PRIMARY);

        // Write characteristic
        BluetoothGattCharacteristic writeCharacteristic = new BluetoothGattCharacteristic(CHARACTERISTIC_LOGIN_UUID,
                BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_READ| BluetoothGattCharacteristic.PROPERTY_INDICATE,
                // Somehow this is not necessary, the client can still enable notifications
//                        | BluetoothGattCharacteristic.PROPERTY_NOTIFY,
                BluetoothGattCharacteristic.PERMISSION_WRITE | BluetoothGattCharacteristic.PERMISSION_READ);

        service.addCharacteristic(writeCharacteristic);

        mGattServer.addService(service);

and then we notify the clients by calling this然后我们通过调用这个来通知客户

mHandler.post(() -> {
            BluetoothGattService service = mGattServer.getService(SERVICE_LOGIN_UUID);
            BluetoothGattCharacteristic characteristic = service.getCharacteristic(uuid);
            log("Notifying characteristic " + characteristic.getUuid().toString()
                    + ", new value: " + StringUtils.byteArrayInHexFormat(value));

            characteristic.setValue(value);
            boolean confirm = BluetoothUtils.requiresConfirmation(characteristic);
            for(BluetoothDevice device : mDevices) {
                mGattServer.notifyCharacteristicChanged(device, characteristic, confirm);
            }
        });

*PLEASE IGNORE THE FOR LOOP HERE FOR THE MOMENT *请暂时忽略这里的for循环

This will cause onNotificationSent to be called but doesn't help to know if it was acknowledged or not.这将导致 onNotificationSent 被调用,但无助于了解它是否被确认。

Let me know if you need other code parts.如果您需要其他代码部分,请告诉我。

Thank you all already, many greetings已经谢谢大家了,多多问候

Unfortunately on Android, the acknowledgement is sent/received behind the scenes, ie there is no mechanism where you can use this in your app.不幸的是,在 Android 上,确认是在幕后发送/接收的,即没有可以在您的应用程序中使用它的机制。 Please have a look at the following link:-请查看以下链接:-

Handling indications instead of notifications in Android BLE 在 Android BLE 中处理指示而不是通知

If you really want some app-layer mechanism to prove that the data was received, you can implement another (additional) characteristic on your server side.如果你真的想要一些应用层机制来证明数据被接收,你可以在你的服务器端实现另一个(额外的)特性。 When the data is received on the central side, it can simply write to that characteristic to prove that it has.当中心端收到数据时,它可以简单地写入该特征以证明它具有。 This has the disadvantage of making your app more complex but is arguably more reliable.这样做的缺点是使您的应用程序更复杂,但可以说更可靠。 The reason for this is that you are manually sending the acknowledgements from the app-layer, ensuring that everything has worked as expected, whereas automatically sending ACKs from the baseband layer is not proof that everything is 100% working successfully (eg the data didn't make it from the baseband to the app, or your app has crashed, etc).这样做的原因是您从应用层手动发送确认,确保一切都按预期工作,而从基带层自动发送 ACK 并不能证明一切都 100% 成功(例如数据没有) t 从基带到应用程序,或者您的应用程序崩溃等)。

I hope this helps.我希望这有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM