问题描述
我要连接的BLE设备在其GATT特征之一上发出字节,以响应对该特征的写入.客户端应该在该特征上启用通知,并解释该特征上的更改字节. (我控制的行为是为附近的无线网络打开扫描服务,然后监听服务输出.)
The BLE device that I'm connecting to emits bytes on one of its GATT characteristics in response to writes to the characteristic. Clients are supposed to enable notifications on that characteristic, and to interpret change bytes on the characteristic. (The behavior I'm controlling is turning on a scanning service for nearby wireless networks, then listening to the service output.)
我正在使用RxAndroidBle,并遵循示例.我有一个活动的连接,可观察.我要观察的特征有一个称为AP_SCAN_DATA
的UUID.它应该发出0xFE
作为对收到书面0xFF
的响应.
I'm using RxAndroidBle and following the examples. I have an active connection Observable. The characteristic I want to observe has a UUID called AP_SCAN_DATA
. It's supposed to emit 0xFE
in response to receiving a written 0xFF
.
如何调用setupNotification
并在其上设置一个Observer来捕获发出的byte[]
s,然后将一个值写入特征,以便我可以捕获响应?
How do I call setupNotification
and set up an Observer on it to catch emitted byte[]
s, then write a value to the characteristic, so that I can catch the response?
到目前为止我最大的努力:
My best effort so far:
connectionObservable.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<RxBleConnection>() {
@Override
public void onCompleted() { // ignore...
}
@Override
public void onError(Throwable e) { // ignore...
}
@Override
public void onNext(final RxBleConnection connection) {
Observable.just(connection)
.flatMap(new Func1<RxBleConnection, Observable<Observable<byte[]>>>() {
@Override
public Observable<Observable<byte[]>> call(RxBleConnection connection) {
return connection.setupNotification(AP_SCAN_DATA);
}
})
.doOnNext(new Action1<Observable<byte[]>>() {
@Override
public void call(Observable<byte[]> observable) {
Log.i(TAG, "notification has been set up");
// This code logs on DEBUG that a write was made, but no response ever arrives
connection.writeCharacteristic(AP_SCAN_DATA, CharacteristicValue.RESET.asBytes())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
}
})
.flatMap(new Func1<Observable<byte[]>, Observable<byte[]>>() {
@Override
public Observable<byte[]> call(Observable<byte[]> observable) {
return observable;
}
})
.doOnNext(new Action1<byte[]>() {
@Override
public void call(byte[] bytes) {
Log.i(TAG, "want to read response bytes here, but I don't... " + HexString.bytesToHex(bytes));
}
})
.subscribe();
}
});
推荐答案
There is already a topic in which you may find some insight -> RxAndroidBle keeping a persistant connection + Write/Notification handling
这是仅使用一个.subscribe()
即可达到相同结果的方法.
This is how you could achieve the same result while using only a single .subscribe()
.
connectionObservable
.flatMap( // when the connection is available...
rxBleConnection -> rxBleConnection.setupNotification(AP_SCAN_DATA), // ... setup the notification...
(rxBleConnection, apScanDataNotificationObservable) -> Observable.combineLatest( // ... when the notification is setup...
rxBleConnection.writeCharacteristic(AP_SCAN_DATA, writeValue), // ... write the characteristic...
apScanDataNotificationObservable.first(), // ... and observe for the first notification on the AP_SCAN_DATA
(writtenBytes, responseBytes) -> responseBytes // ... when both will appear return just the response bytes...
)
)
.flatMap(observable -> observable) // ... flatMap the result as it is Observable<byte[]>...
.first() // ... and finish after first response is received to cleanup notifications
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
responseBytes -> { /* consume the response here */ },
throwable -> { /* handle exception */ }
);
仅供参考-除非您100%确保Observable
不会发出错误,否则您应该处理每个.subscribe()
中的错误.
FYI - you should handle errors in every .subscribe()
unless you're 100% sure that the Observable
does not emit errors.
这篇关于使用RxAndroidBle,我如何订阅从写入特征开始的响应?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!