我目前正在为Bluetooth
设备实施协议,我正在使用RxAndroidBle
库(版本1.4.3)。
我必须通过写入特征来请求设备中的数据,然后通过特征通知收听响应。
要结合2个操作(写作和聆听),我使用的代码来自:see the following in the logs
connectionObservable
.flatMap( // when the connection is available...
rxBleConnection -> rxBleConnection.setupNotification(AP_SCAN_DATA), // ... setup the notification...
(rxBleConnection, apScanDataNotificationObservable) -> Observable.combineLatest( // ... when the notification is setup...
rxBleConnection.writeCharacteristic(AP_SCAN_DATA, writeValue), // ... write the characteristic...
apScanDataNotificationObservable.first(), // ... and observe for the first notification on the AP_SCAN_DATA
(writtenBytes, responseBytes) -> responseBytes // ... when both will appear return just the response bytes...
)
)
.flatMap(observable -> observable)
这种方法对我有用,唯一的问题是代码只给出了前20个字节(由于apScanDataNotificationObservable.first()
)。
不幸的是,我不知道我收到的包裹的大小。我只能从前20个字节的标题中提取信息。似乎RxJava
缓冲区函数都需要事先知道大小。
有没有办法让上述代码干净利落地作为Rx链的一部分?
换句话说,我可以根据Rx链的首次发射来控制发射次数吗?
或者我的方法是否完全错误?
答案 0 :(得分:0)
有可能达到你想要的效果。
最简单的方法是将 <properties>
<log4j2.version>
2.10.0
</log4j2.version>
</properties>
换成:
Observable.combineLatest(...)
其中Observable.merge(
rxBleConnection.writeCharacteristic(AP_SCAN_DATA, writeValue).ignoreElements(), // send the request but ignore the returned value
apScanDataNotificationObservable.takeUntil(newResponseEndWatcher()) // take the response notifications until the response end watcher says so
);
需要包含用于确定所接收的值是否都是预期值的逻辑。它看起来像这样:
newResponseEndWatcher()
请记住private Func1<byte[], Boolean> newResponseEndWatcher() {
return new Func1<byte[], Boolean>() {
private static final int NOT_INITIALIZED = -1;
private int totalLength = NOT_INITIALIZED;
private int receivedLength = NOT_INITIALIZED;
@Override
public Boolean call(byte[] bytes) {
if (isNotInitialized(totalLength)) { // if it is the first received value
// parse totalLength from the header
}
// update receivedLength
return receivedLength >= totalLength;
}
private boolean isNotInitialized(int value) {
return value == NOT_INITIALIZED;
}
};
}
结果Func1
是有状态的。如果将newResponseEndWatcher()
结果存储到变量中,那么下一个订阅可能会过早结束。
要缓解此问题,可以使用apScanDataNotificationObservable.takeUntil(newResponseEndWatcher())
函数,每次订阅时都会调用Observable.using()
,然后创建新的newResponseEndWatcher()
:
apScanDataNotificationObservable.takeUntil(newResponseEndWatcher)