Using RxAndroidBle, how do I subscribe to responses from writing to a characteristic?

前端 未结 2 1951
无人共我
无人共我 2020-12-20 08:05

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 notificatio

相关标签:
2条回答
  • 2020-12-20 08:50

    For those readers not using a Java version that supports lambdas, here's my implementation of @s_noopy's answer.

    connectionObservable
        .flatMap(new Func1<RxBleConnection, Observable<Observable<byte[]>>>() {
                @Override
                public Observable<Observable<byte[]>> call(RxBleConnection connection) {
                    return connection.setupNotification(AP_SCAN_DATA);
                }             
            }, new Func2<RxBleConnection, Observable<byte[]>, Observable<byte[]>>() {
                @Override
                public Observable<byte[]> call(RxBleConnection connection, Observable<byte[]> apScanDataNotificationObservable) {
                    return Observable.combineLatest(
                        connection.writeCharacteristic(AP_SCAN_DATA, CharacteristicValue.RESET.asBytes()),
                        apScanDataNotificationObservable.first(),
                        new Func2<byte[], byte[], byte[]>() {
                            @Override
                            public byte[] call(byte[] writtenBytes, byte[] responseBytes) {
                                        return responseBytes;
                                    }
                                }
                            );
                        }
                    }
                ).flatMap(new Func1<Observable<byte[]>, Observable<byte[]>>() {
                    @Override
                    public Observable<byte[]> call(Observable<byte[]> observable) {
                        return observable;
                    }
                })
                .first()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<byte[]>() {
                    @Override
                    public void call(byte[] bytes) {
                        Log.i(TAG, "notification response...." + HexString.bytesToHex(bytes));
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        logError(throwable);
                    }
                });
    
    0 讨论(0)
  • 2020-12-20 09:04

    There is already a topic in which you may find some insight -> RxAndroidBle keeping a persistant connection + Write/Notification handling

    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 */ }
                );
    

    FYI - you should handle errors in every .subscribe() unless you're 100% sure that the Observable does not emit errors.

    0 讨论(0)
提交回复
热议问题