Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 从同一个可观察对象(RxAndroidBle)观察多次_Kotlin_Rx Java2_Rxandroidble - Fatal编程技术网

Kotlin 从同一个可观察对象(RxAndroidBle)观察多次

Kotlin 从同一个可观察对象(RxAndroidBle)观察多次,kotlin,rx-java2,rxandroidble,Kotlin,Rx Java2,Rxandroidble,我正在使用RxJava2的库来读取一个BLE特性。我认为这个问题只是一个RxJava问题,但包括我正在使用的RxAndroidBle的细节,以防有用 我获取连接,然后使用它调用readCharacteristic(),它本身返回一个单键。在这一点上,我不想只得到一个ByteArray。我需要多次读取该特性,因为BLE设备设置为让我返回一个小文件,并且特性一次只能返回20个字节,因此我需要重复读取 是否可以修改此代码,以便下面的switchMap()返回一个可观察的数组,该数组将发出多个字节数组,

我正在使用RxJava2的库来读取一个BLE特性。我认为这个问题只是一个RxJava问题,但包括我正在使用的
RxAndroidBle
的细节,以防有用

我获取连接,然后使用它调用
readCharacteristic()
,它本身返回一个
单键。在这一点上,我不想只得到一个
ByteArray
。我需要多次读取该特性,因为BLE设备设置为让我返回一个小文件,并且特性一次只能返回20个字节,因此我需要重复读取

是否可以修改此代码,以便下面的
switchMap()
返回一个可观察的
数组,该数组将发出多个
字节数组,而不仅仅是单个字节数组

我是RxJava新手

val connection: Observable<RxBleConnection> = selectedDevice.record.bleDevice.establishConnection(false, Timeout(30, TimeUnit.SECONDS))
return connection
  .subscribeOn(Schedulers.io())
  .switchMap {
    // I want to get an Observable that can read multiple times here.
    it.readCharacteristic(serverCertCharacteristicUUID).toObservable()
  }
  .doOnNext {
    Timber.e("Got Certificate bytes")
  }
  .map {
    String(it as ByteArray)
  }
  .doOnNext {
    Timber.e("Got certificate: $it")
  }
  .singleOrError()
val连接:Observable=selectedDevice.record.bleDevice.establishConnection(false,超时(30,TimeUnit.SECONDS))
回路连接
.subscribeOn(Schedulers.io())
.开关图{
//我想得到一个可以在这里多次读取的可观测数据。
it.readCharacteristic(serverCertCharacteristicUUID).toObservable()
}
doOnNext先生{
Timber.e(“获得证书字节”)
}
.地图{
字符串(它作为ByteArray)
}
doOnNext先生{
Timber.e(“获得证书:$it”)
}
.singleOrError()

您可以使用通知缓冲数据

device.establishConnection(false)
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(characteristicUuid))
.flatMap(notificationObservable -> notificationObservable) // <-- Notification has been set up, now observe value changes.
.subscribe(
    bytes -> {
        // Given characteristic has been changes, here is the value.
    },
    throwable -> {
        // Handle an error here.
    }
);
设备。建立连接(错误)
.flatMap(rxBleConnection->rxBleConnection.setupNotification(characteristicUuid))
.flatMap(notificationObservable->notificationObservable)//{
//给定特性已发生变化,以下是值。
},
可丢弃->{
//在这里处理错误。
}
);

您可以使用通知缓冲数据

device.establishConnection(false)
.flatMap(rxBleConnection -> rxBleConnection.setupNotification(characteristicUuid))
.flatMap(notificationObservable -> notificationObservable) // <-- Notification has been set up, now observe value changes.
.subscribe(
    bytes -> {
        // Given characteristic has been changes, here is the value.
    },
    throwable -> {
        // Handle an error here.
    }
);
设备。建立连接(错误)
.flatMap(rxBleConnection->rxBleConnection.setupNotification(characteristicUuid))
.flatMap(notificationObservable->notificationObservable)//{
//给定特性已发生变化,以下是值。
},
可丢弃->{
//在这里处理错误。
}
);

要重复多次读取直到发出特定值,需要更改此部分:

// I want to get an Observable that can read multiple times here.
it.readCharacteristic(serverCertCharacteristicUUID).toObservable()
比如说:

//这将重复执行,直到'checkRepeatIf'返回false为止
可观察的{
val successValue=AtomicReference()
connection.readCharacteristic(serverCertCharacteristicUUID)
.doOnSuccess{successValue.lazySet(it)}
.repeatWhen{completes->completes.takeWhile{checkRepeatIf(successValue.get())}
}

要重复多次读取直到发出特定值,需要更改此部分:

// I want to get an Observable that can read multiple times here.
it.readCharacteristic(serverCertCharacteristicUUID).toObservable()
比如说:

//这将重复执行,直到'checkRepeatIf'返回false为止
可观察的{
val successValue=AtomicReference()
connection.readCharacteristic(serverCertCharacteristicUUID)
.doOnSuccess{successValue.lazySet(it)}
.repeatWhen{completes->completes.takeWhile{checkRepeatIf(successValue.get())}
}

我通过发送一个信号来停止
可观察的连接和蓝牙特性上的读取,从而使该功能正常工作。需要注意的是,您需要在
repeat()
之后调用
toObservable()
,否则这不起作用,尽管我不知道确切原因

override fun readMultipartCharacteristic(macAddress: String): Single<String> {
  val CERTIFICATE_TERMINATOR = 0x30.toByte()

  val device = bluetoothService.getBleDevice(macAddress)
  if (connectionObservable == null || !device.connectionState.equals(RxBleConnection.RxBleConnectionState.CONNECTED)) {
    connectionObservable = device.establishConnection(false, Timeout(30, TimeUnit.SECONDS))
  }

  val stop: PublishSubject<Unit> = PublishSubject.create()
  return connectionObservable!!
      .subscribeOn(Schedulers.io())
      .takeUntil(stop)
      .switchMap {
        it.readCharacteristic(UUID("my-uuid"))
            .repeat()
            .toObservable()
            .takeUntil(stop)
      }
      .collectInto(ByteArrayOutputStream(), { buffer, byteArray ->
        // Watch for the signal of the end of the stream
        if (byteArray.size == 1 && byteArray.get(0).equals(CERTIFICATE_TERMINATOR)) {
          stop.onComplete()
        } else {
          buffer.write(byteArray)
        }
      })
      .map {
        String(it.toByteArray())
      }
}
override-fun-readMultipartCharacteristic(macAddress:String):单个{
val证书_终止符=0x30.toByte()
val device=bluetoothService.getBleDevice(macAddress)
if(connectionObservable==null | |!device.connectionState.equals(rxbeconnection.rxbeconnectionstate.CONNECTED)){
connectionObservable=设备。建立连接(错误,超时(30,时间单位。秒))
}
val stop:PublishSubject=PublishSubject.create()
返回可观察的连接!!
.subscribeOn(Schedulers.io())
.takeUntil(停止)
.开关图{
readCharacteristic(UUID(“我的UUID”))
.重复
.TooObservable()文件
.takeUntil(停止)
}
.collectInto(ByteArrayOutputStream(),{buffer,byteArray->
//观察水流结束的信号
if(byteArray.size==1&&byteArray.get(0.equals)(证书\终止符)){
stop.onComplete()
}否则{
buffer.write(字节数组)
}
})
.地图{
字符串(it.toByteArray())
}
}

我通过发送一个信号来停止
可观察的连接和蓝牙特性上的读取,从而使该功能正常工作。需要注意的是,您需要在
repeat()
之后调用
toObservable()
,否则这不起作用,尽管我不知道确切原因

override fun readMultipartCharacteristic(macAddress: String): Single<String> {
  val CERTIFICATE_TERMINATOR = 0x30.toByte()

  val device = bluetoothService.getBleDevice(macAddress)
  if (connectionObservable == null || !device.connectionState.equals(RxBleConnection.RxBleConnectionState.CONNECTED)) {
    connectionObservable = device.establishConnection(false, Timeout(30, TimeUnit.SECONDS))
  }

  val stop: PublishSubject<Unit> = PublishSubject.create()
  return connectionObservable!!
      .subscribeOn(Schedulers.io())
      .takeUntil(stop)
      .switchMap {
        it.readCharacteristic(UUID("my-uuid"))
            .repeat()
            .toObservable()
            .takeUntil(stop)
      }
      .collectInto(ByteArrayOutputStream(), { buffer, byteArray ->
        // Watch for the signal of the end of the stream
        if (byteArray.size == 1 && byteArray.get(0).equals(CERTIFICATE_TERMINATOR)) {
          stop.onComplete()
        } else {
          buffer.write(byteArray)
        }
      })
      .map {
        String(it.toByteArray())
      }
}
override-fun-readMultipartCharacteristic(macAddress:String):单个{
val证书_终止符=0x30.toByte()
val device=bluetoothService.getBleDevice(macAddress)
if(connectionObservable==null | |!device.connectionState.equals(rxbeconnection.rxbeconnectionstate.CONNECTED)){
connectionObservable=设备。建立连接(错误,超时(30,时间单位。秒))
}
val stop:PublishSubject=PublishSubject.create()
返回可观察的连接!!
.subscribeOn(Schedulers.io())
.takeUntil(停止)
.开关图{
readCharacteristic(UUID(“我的UUID”))
.重复
.TooObservable()文件
.takeUntil(停止)
}
.collectInto(ByteArrayOutputStream(),{buffer,byteArray->
//观察水流结束的信号
if(byteArray.size==1&&byteArray.get(0.equals)(证书\终止符)){
stop.onComplete()
}否则{
buffer.write(字节数组)
}
})
.地图{
字符串(it.toByteArray())
}
}

当然有可能。问题是:1<代码>您知道需要将特征读取到g的次数吗