通过空中发送数据并在完成后使用 RxAndroidBLE 结束操作

Sending data over the air and after completion end the operation using RxAndroidBLE

我正在尝试使用 RxAndroidBle 库将块的 128 字节发送到 BLE 控制器。从手机向BLE控制器发送数据的流程如下

  1. 连接 BLE 控制器
  2. 开始OTA(发送1)
  3. 发送(数据块的)CRC
  4. 发送数据块
  5. 等待2秒
  6. 重复步骤 3
  7. 结束 OTA(发送 2)

这里是代码截图

.flatMap(rxBleConnection -> prepareWriting())
.flatMapIterable(otaMetaData -> otaMetaData)
.zipWith(Observable.interval(2, TimeUnit.SECONDS), (item, interval) -> item)
.doOnNext(metaData -> {
    otaMetaData = metaData;
})
.map(otaMetaData -> {
    return mRxBleConnection.writeCharacteristic(OTA_CHECKSUM, otaMetaData.getCrcBlock()).toObservable();
})

.doOnNext(otaMetaData -> {
    Log.e(TAG, "Writing CRC " + Arrays.toString(BLEUtils.toHex(otaMetaData.getCrcBlock())));


})
.map(bytes -> {
    return mRxBleConnection.writeCharacteristic(OTA_DATA, otaMetaData.getDataBlock()).toObservable();
})
.doOnNext(otaMetaData -> {
    Log.e(TAG, "Writing Data " + Arrays.toString(BLEUtils.toHex(otaMetaData.getDataBlock())));

})
.flatMap(bytes -> mRxBleConnection.writeCharacteristic(OTA_CONTROL,OTA_DATA_END).toObservable())

问题出在发送 END OTA 时,因为 flatMapIterable returns 20 个项目,.flatMap(bytes -> mRxBleConnection.writeCharacteristic(OTA_CONTROL,OTA_DATA_END) 被调用了 20 次。

因此,我不确定在处理完所有 20 个项目后如何发送 OTA_DATA_END 命令。此外,欢迎任何改进现有代码的建议。

您可以将 flatMapIterable()toList() 一起使用。尝试在 OTA_DATA_END 命令之前添加 toList() 运算符,例如:

.toList() // wait for all commands to complete
.flatMap(bytes -> mRxBleConnection.writeCharacteristic(OTA_CONTROL,OTA_DATA_END).toObservable())

编辑

最好分开步骤,例如

.flatMap(rxBleConnection -> prepareWriting())
.flatMap(otaMetaData -> Observable.fromIterable(otaMetaData)
        .zipWith(Observable.interval(2, TimeUnit.SECONDS), (metaData, interval) -> metaData)
        .flatMap(metaData -> {
            return mRxBleConnection.writeCharacteristic(OTA_CHECKSUM, metaData.getCrcBlock())
                    .toObservable();
        }, (metaData, bytes) -> metaData) /* result selector */
        .flatMap(metaData -> {
            return mRxBleConnection.writeCharacteristic(OTA_DATA, metaData.getDataBlock())
                    .toObservable();
        }, (metaData, bytes) -> metaData)
        .toList()
        .toObservable()
)
.flatMap(otaMetaData -> {
    return mRxBleConnection.writeCharacteristic(OTA_CONTROL, OTA_DATA_END)
            .toObservable();
})