Skip to content Skip to sidebar Skip to footer

How To Concatenate Two Observable Operations In A Linear Fashion (do First This Thing And After That One Finishes Do The Second Thing)?

Polidea has released a new handy library called RxAndroidBle which is very useful for dealing with a lot of issues when you're using vanilla Bluetooth APIs. Before explaining more

Solution 1:

To achieve what you want you can take several ways. One of them is:

final UUID serviceUuid = // your service UUIDfinal Map<UUID, byte[]> genericModel = new HashMap<>();
    final Observable<RxBleConnection> connectionObservable = // your connectionObservable

    connectionObservable
            .flatMap( // get the characteristics from the service you're interested in
                    connection -> connection
                            .discoverServices()
                            .flatMap(services -> services
                                    .getService(serviceUuid)
                                    .map(BluetoothGattService::getCharacteristics)
                            ),
                    Pair::new
            )
            .flatMap(connectionAndCharacteristics -> {
                final RxBleConnection connection = connectionAndCharacteristics.first;
                final List<BluetoothGattCharacteristic> characteristics = connectionAndCharacteristics.second;
                returnreadInitialValues(connection, characteristics)
                        .concatWith(setupNotifications(connection, characteristics));
            })
            .subscribe(
                    pair -> genericModel.put(pair.first.getUuid(), pair.second),
                    throwable -> { /* handle errors */}
            );

Where:

privateObservable<Pair<BluetoothGattCharacteristic, byte[]>> readInitialValues(RxBleConnection connection,
                                                                                List<BluetoothGattCharacteristic> characteristics) {
    returnObservable.from(characteristics) // deal with every characteristic separately
            .filter(characteristic -> (characteristic.getProperties() &BluetoothGattCharacteristic.PROPERTY_READ) !=0) // filter characteristics that have read property
            .flatMap(connection::readCharacteristic, // read characteristic
                    Pair::new); // merge characteristic with byte[] to keep track from which characteristic the bytes came
}

privateObservable<Pair<BluetoothGattCharacteristic, byte[]>> setupNotifications(RxBleConnection connection,
                                                                                List<BluetoothGattCharacteristic> characteristics) {
    returnObservable.from(characteristics) // deal with every characteristic separately
            .filter(characteristic -> (characteristic.getProperties() &BluetoothGattCharacteristic.PROPERTY_NOTIFY) !=0) // filter characteristics that have notify property
            .flatMap(characteristic -> connection
                            .setupNotification(characteristic) // setup notification for each
                            .flatMap(observable -> observable), // to get the raw bytes from notification
                    Pair::new); // merge characteristic with byte[] to keep track from which characteristic the bytes came
}

Alternatively to concatWith() you could inverse the order and use startWith().

Best Regards

Post a Comment for "How To Concatenate Two Observable Operations In A Linear Fashion (do First This Thing And After That One Finishes Do The Second Thing)?"