我正在将纯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发出(客户端对回调的回复),以及如何根据上游结果更改流的路由(根据加密状态更改下一个操作)。理想情况下,无需更改客户端代码,因为库已部署在少数第三方应用程序中。
感谢。
答案 0 :(得分:0)
首先,我没有通过处置where
来查看您关闭任何连接的位置。连接将一直持续,直到您执行此操作或设备断开连接。
您可能可以通过将第一个连接保存在connectionDisposable
类型的变量中来实现。在RxBleConnection
之前,插入.flatMapSingle()
。然后使用.doOnNext( connection -> savedConnection = connection )
进行后续操作,而不是建立新操作。
完成后不要忘记处理。应该也可以使savedConnection
为空,以避免尝试使用死连接。