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