通过第一次发射确定特征Notfication排放计数

时间:2017-11-29 14:34:56

标签: android rx-java android-ble rxandroidble

我目前正在为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链的首次发射来控制发射次数吗?

或者我的方法是否完全错误?

1 个答案:

答案 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)