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

Har*_*ber 3 android bluetooth bluetooth-lowenergy gatt bluetooth-gatt

我们正在研究两个 Android 应用程序之间的蓝牙低功耗通信。一种是外围设备/服务器,一种是中央设备/客户端。如果数据发生变化,服务器将向客户端发送指示。然而,我们没有找到一种方法来确保数据确实在客户端得到了确认。我们如何知道客户端是否收到并确认了数据以便在服务器端做出相应的反应?

根据 Android 文档,BleutoothGattServer 有回调 onNotificationSent。 https://developer.android.com/reference/android/bluetooth/BluetoothGattServerCallback#onNotificationSent(android.bluetooth.BluetoothDevice,%20int)

然而,通过调试和做一些测试,似乎这个方法实际上只是在发送通知时被调用。无法保证该消息实际上已收到或确认。

以下是我们如何设置 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);
Run Code Online (Sandbox Code Playgroud)

然后我们通过调用此通知客户

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);
            }
        });
Run Code Online (Sandbox Code Playgroud)

*请暂时忽略此处的 for 循环

这将导致 onNotificationSent 被调用,但无助于了解它是否已被确认。

如果您需要其他代码部分,请告诉我。

谢谢大家,很多问候

You*_*eed 5

不幸的是,在 Android 上,确认是在幕后发送/接收的,即没有任何机制可以在您的应用程序中使用它。请查看以下链接:-

在 Android BLE 中处理指示而不是通知

如果您确实想要某种应用程序层机制来证明已收到数据,您可以在服务器端实现另一个(附加)特征。当中心端接收到数据时,它可以简单地写入该特征来证明它具有。这样做的缺点是使您的应用程序更加复杂,但可以说更可靠。原因是您从应用程序层手动发送确认,确保一切都按预期工作,而从基带层自动发送 ACK 并不能证明一切都 100% 成功工作(例如,数据没有'不能从基带到应用程序,或者您的应用程序崩溃了,等等)。

我希望这有帮助。