RxAndroidBle等待客户响应

时间:2018-05-25 10:30:42

标签: bluetooth-lowenergy rx-java2 rxandroidble

我正在将纯Android BLE库转换为使用RxAndroidBle,我有点陷入困境。

库当前打开连接,读取特征,并检查它是否已加密。如果是,它继续阅读下面几个特征。但是,如果它未加密,则会向客户端发出回调,告诉他们传入加密密钥(客户端负责生成此密钥或从服务器获取密钥)。传入密钥后,库会将其写入设备,然后继续加密设备。

在RxAndroidBle中,我正在建立连接,读取特征,然后关闭连接。然后,如果它已加密,则再次建立连接并读取其他特征。如果没有,则触发回调,然后在客户端回复后建立连接。

public void connect() {
    connectionDisposable = bleDevice.establishConnection(false)
            .flatMapSingle(rxBleConnection -> rxBleConnection.readCharacteristic(ENCRYPT_CHARACTERISTIC_UUID))
            .subscribe(bytes -> {
                if(isEncrypted(bytes))
                    encryptedConnect();
                else
                    listener.onKeyNeeded();
            }, this::onError);
}

public void setKey(byte[] key) {
    unencryptedConnect();
}

private void encryptedConnect() {
    connectionDisposable = bleDevice.establishConnection(false)
            .flatMapSingle(rxBleConnection -> Single.zip(
                    rxBleConnection.readCharacteristic(A_CHARACTERISTIC_UUID),
                    rxBleConnection.readCharacteristic(B_CHARACTERISTIC_UUID),
                    rxBleConnection.readCharacteristic(C_CHARACTERISTIC_UUID),
                    DataModel::new))
            .subscribe(this::processData, this::onError);
}

private void unencryptedConnect() {
    connectionDisposable = bleDevice.establishConnection(false)
            .flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(ENCRYPT_CHARACTERISTIC_UUID)
                .flatMapSingle(bytes -> Single.zip(
                        rxBleConnection.readCharacteristic(A_CHARACTERISTIC_UUID),
                        rxBleConnection.readCharacteristic(B_CHARACTERISTIC_UUID),
                        rxBleConnection.readCharacteristic(C_CHARACTERISTIC_UUID),
                        DataModel::new))
            )
            .subscribe(this::processData, this::onError);
} 

我对RxJava完全不熟悉,但这种连接和重新连接的方法似乎错过了反应设计的全部要点。是否有人能够指出我正确的方向如何正确利用Rx这个用例。即,如何在一个流中等待不同的observable发出(客户端对回调的回复),以及如何根据上游结果更改流的路由(根据加密状态更改下一个操作)。理想情况下,无需更改客户端代码,因为库已部署在少数第三方应用程序中。

感谢。

1 个答案:

答案 0 :(得分:0)

首先,我没有通过处置where来查看您关闭任何连接的位置。连接将一直持续,直到您执行此操作或设备断开连接。

您可能可以通过将第一个连接保存在connectionDisposable类型的变量中来实现。在RxBleConnection之前,插入.flatMapSingle()。然后使用.doOnNext( connection -> savedConnection = connection )进行后续操作,而不是建立新操作。

完成后不要忘记处理。应该也可以使savedConnection为空,以避免尝试使用死连接。