RxAndroidBle:如果客户端处于可观察状态,如何执行读写操作?

时间:2017-12-18 13:42:22

标签: rx-java rxandroidble

建立连接时,我使用.asObservable()属性保持连接。

bleDevice = rxBleDevice;
rxBleDevice.establishConnection(false)
        .flatMap(RxBleConnection::discoverServices)
        **.asObservable()**
        .subscribe(rxBleDeviceServices -> swapScanResult(rxBleDeviceServices));

当我尝试读取值时建立连接后显示

  

已连接到设备

 bleDevice.establishConnection(false)
        .flatMap(rxBleConnection -> Observable.combineLatest(
                    rxBleConnection.readCharacteristic(gattCharacteristicList.get(6).getUuid()),
                    rxBleConnection.readCharacteristic(gattCharacteristicList.get(7).getUuid()),
                    ReadValuesOnConnection::new
        ))
        .subscribe(
                readValuesOnConnection -> Log.i("UUid 6 Value: ", readValuesOnConnection.value_1+""),
                throwable -> Log.e("Error", throwable.getMessage())
        );

日志:

I/Bluetooth Enable: True
I/RxBle#QueueOperation: Scan operation is requested to start.
I/Scan Results:: 6Q:6C:05:8E:F5:5B
I/Scan Results:: 6P:6A:05:8E:F8:2X
I/RxBle#CancellableSubscription: Scan operation is requested to stop.
W/zygote64: Suspending all threads took: 5.645ms
I/Characteristics List size:: 33
E/Error: Already connected to device with MAC address 6Q:6C:05:8E:F5:5B

我查看了示例项目,但没有找到任何解决方案。

1 个答案:

答案 0 :(得分:1)

client is in observable state你是什么意思? .asObservable()不是属性,而是一个函数 - 在此特定情况下 - 由于.flatMap()的结果已经Observable而没有任何变化。

Already connected to device with MAC address来自BleAlreadyConnectedException,表示当已经打开一个连接时,会尝试建立新连接。

您可能想要的是将两个独立的流组合成一个既可以执行这两个流程又可以同时执行这两个流程的流程:swapScanResult和读取特征。你可以这样做:

subscription = rxBleDevice.establishConnection(false) // first we want to establish the connection
  .flatMap( // once the connection is established
    RxBleConnection::discoverServices, // we want to explicitly discover the services
    (rxBleConnection, rxBleDeviceServices) -> { // when both the connection and services are available
      swapScanResult(rxBleDeviceServices); // we swap scan result?
      return Observable.combineLatest( // and start reading characteristics
        rxBleConnection.readCharacteristic(gattCharacteristicList.get(6).getUuid(),
        rxBleConnection.readCharacteristic(gattCharacteristicList.get(7).getUuid(),
        ReadValuesOnConnection::new // when both characteristics are read we combine the result
      );
    }
  )
  .flatMap(observable -> observable) // we need to flatMap the result as we returned an Observable from the first flatMap
  .take(1) // after the read has completed we unsubscribe from the upstream to make the connection close
  .subscribe( // we consume the result
    readValuesOnConnection -> Log.i("UUid 6 Value: ", readValuesOnConnection.value_1+""),
    throwable -> Log.e("Error", throwable.getMessage())
  );

此外,此流程使用一些副作用,使其具有潜在的非确定性。您调用方法swapScanResult(RxBleDeviceServices),在其他地方使用gattCharacteristicList.get(int).getUuid()并将其反馈给流程。

通过更改上述方法并访问特征列表(存储为属性),可以使代码更容易理解。它就像将它改成一个可以有如下签名的纯函数一样简单:

static Pair<UUID, UUID> getUuidsOfCharacteristicsToRead(RxBleDeviceServices services);