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

时间:2019-02-08 09:32:26

标签: 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);

然后我们通过调用此通知

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);
            }
        });

*请忽略此处的循环

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

让我知道您是否需要其他代码部分。

已经谢谢大家,许多问候

1 个答案:

答案 0 :(得分:2)

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

Handling indications instead of notifications in Android BLE

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

我希望这会有所帮助。