使用库 RxAndroidBle 从 Android 设备读取多个特征
Read multiple characteristics from an Android device using library RxAndroidBle
我正在使用库 RxAndroidBle 来扫描设备,然后连接到一个特定设备并读取 4 个 GATT 特性。
我可以用这段代码读取一个特性(电池电量):
scanSubscription = rxBleClient.scanBleDevices(
new ScanSettings.Builder()
.build()
)
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(
scanResult -> {
if(scanResult.getBleDevice().getName() != null){
if(scanResult.getBleDevice().getName().equals("NODE 1")){
Log.e("BLE SCAN", "SUCCESS");
Log.e("BLE SCAN", scanResult.getBleDevice().getName());
Log.e("BLE SCAN", scanResult.getBleDevice().getMacAddress());
scanSubscription.unsubscribe();
RxBleDevice device = scanResult.getBleDevice();
subscription = device.establishConnection(false) // <-- autoConnect flag
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")))
.subscribe(
characteristicValue -> {
Log.e("Characteristic", characteristicValue[0]+"");
},
throwable -> {
Log.e("Error", throwable.getMessage());
}
);
}
}
}
)
.subscribe();
我可以读两本:
.flatMap(rxBleConnection -> Observable.combineLatest( // use the same connection and combine latest emissions
rxBleConnection.readCharacteristic(aUUID),
rxBleConnection.readCharacteristic(bUUID),
Pair::new
))
但我不明白如何使用 4 个特征来做到这一点。
谢谢
上面的例子很好,你只需要一些比 Pair
接受更多值的数据对象。例如:
class ReadResult {
final byte[] aValue;
final byte[] bValue;
final byte[] cValue;
final byte[] dValue;
ReadResult(byte[] aValue, byte[] bValue, byte[] cValue, byte[] dValue) {
this.aValue = aValue;
this.bValue = bValue;
this.cValue = cValue;
this.dValue = dValue;
}
}
然后示例可能如下所示:
disposable = rxBleClient.scanBleDevices(
new ScanSettings.Builder().build(),
new ScanFilter.Builder().setDeviceName("NODE 1").build() // one can set filtering by name here
)
.take(1) // take only the first result and then the upstream will get unsubscribed (scan will end)
.flatMap(scanResult -> scanResult.getBleDevice().establishConnection(false)) // connect to the first scanned device that matches the filter
.flatMapSingle(rxBleConnection -> Single.zip( // once connected read all needed values
rxBleConnection.readCharacteristic(aUUID),
rxBleConnection.readCharacteristic(bUUID),
rxBleConnection.readCharacteristic(cUUID),
rxBleConnection.readCharacteristic(dUUID),
ReadResult::new // merge them into a single result
))
.take(1) // once the result of all reads is available unsubscribe from the upstream (connection will end)
.subscribe(
readResult -> Log.d("Characteristics", /* print the readResult */),
throwable -> Log.e("Error", throwable.getMessage())
);
Original/Legacy基于RxJava1的RxAndroidBle解决方案:
subscription = rxBleClient.scanBleDevices(
new ScanSettings.Builder().build(),
new ScanFilter.Builder().setDeviceName("NODE 1").build() // one can set filtering by name here
)
.take(1) // take only the first result and then the upstream will get unsubscribed (scan will end)
.flatMap(scanResult -> scanResult.getBleDevice().establishConnection(false)) // connect to the first scanned device that matches the filter
.flatMap(rxBleConnection -> Observable.combineLatest( // once connected read all needed values
rxBleConnection.readCharacteristic(aUUID),
rxBleConnection.readCharacteristic(bUUID),
rxBleConnection.readCharacteristic(cUUID),
rxBleConnection.readCharacteristic(dUUID),
ReadResult::new // merge them into a single result
))
.take(1) // once the result of all reads is available unsubscribe from the upstream (connection will end)
.subscribe(
readResult -> Log.d("Characteristics", /* print the readResult */),
throwable -> Log.e("Error", throwable.getMessage())
);
我正在使用库 RxAndroidBle 来扫描设备,然后连接到一个特定设备并读取 4 个 GATT 特性。
我可以用这段代码读取一个特性(电池电量):
scanSubscription = rxBleClient.scanBleDevices(
new ScanSettings.Builder()
.build()
)
.observeOn(AndroidSchedulers.mainThread())
.doOnNext(
scanResult -> {
if(scanResult.getBleDevice().getName() != null){
if(scanResult.getBleDevice().getName().equals("NODE 1")){
Log.e("BLE SCAN", "SUCCESS");
Log.e("BLE SCAN", scanResult.getBleDevice().getName());
Log.e("BLE SCAN", scanResult.getBleDevice().getMacAddress());
scanSubscription.unsubscribe();
RxBleDevice device = scanResult.getBleDevice();
subscription = device.establishConnection(false) // <-- autoConnect flag
.flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb")))
.subscribe(
characteristicValue -> {
Log.e("Characteristic", characteristicValue[0]+"");
},
throwable -> {
Log.e("Error", throwable.getMessage());
}
);
}
}
}
)
.subscribe();
我可以读两本:
.flatMap(rxBleConnection -> Observable.combineLatest( // use the same connection and combine latest emissions
rxBleConnection.readCharacteristic(aUUID),
rxBleConnection.readCharacteristic(bUUID),
Pair::new
))
但我不明白如何使用 4 个特征来做到这一点。
谢谢
上面的例子很好,你只需要一些比 Pair
接受更多值的数据对象。例如:
class ReadResult {
final byte[] aValue;
final byte[] bValue;
final byte[] cValue;
final byte[] dValue;
ReadResult(byte[] aValue, byte[] bValue, byte[] cValue, byte[] dValue) {
this.aValue = aValue;
this.bValue = bValue;
this.cValue = cValue;
this.dValue = dValue;
}
}
然后示例可能如下所示:
disposable = rxBleClient.scanBleDevices(
new ScanSettings.Builder().build(),
new ScanFilter.Builder().setDeviceName("NODE 1").build() // one can set filtering by name here
)
.take(1) // take only the first result and then the upstream will get unsubscribed (scan will end)
.flatMap(scanResult -> scanResult.getBleDevice().establishConnection(false)) // connect to the first scanned device that matches the filter
.flatMapSingle(rxBleConnection -> Single.zip( // once connected read all needed values
rxBleConnection.readCharacteristic(aUUID),
rxBleConnection.readCharacteristic(bUUID),
rxBleConnection.readCharacteristic(cUUID),
rxBleConnection.readCharacteristic(dUUID),
ReadResult::new // merge them into a single result
))
.take(1) // once the result of all reads is available unsubscribe from the upstream (connection will end)
.subscribe(
readResult -> Log.d("Characteristics", /* print the readResult */),
throwable -> Log.e("Error", throwable.getMessage())
);
Original/Legacy基于RxJava1的RxAndroidBle解决方案:
subscription = rxBleClient.scanBleDevices(
new ScanSettings.Builder().build(),
new ScanFilter.Builder().setDeviceName("NODE 1").build() // one can set filtering by name here
)
.take(1) // take only the first result and then the upstream will get unsubscribed (scan will end)
.flatMap(scanResult -> scanResult.getBleDevice().establishConnection(false)) // connect to the first scanned device that matches the filter
.flatMap(rxBleConnection -> Observable.combineLatest( // once connected read all needed values
rxBleConnection.readCharacteristic(aUUID),
rxBleConnection.readCharacteristic(bUUID),
rxBleConnection.readCharacteristic(cUUID),
rxBleConnection.readCharacteristic(dUUID),
ReadResult::new // merge them into a single result
))
.take(1) // once the result of all reads is available unsubscribe from the upstream (connection will end)
.subscribe(
readResult -> Log.d("Characteristics", /* print the readResult */),
throwable -> Log.e("Error", throwable.getMessage())
);