1

I have been using RxAndroidBLE 2 only recently and I am looking for a solution where I can enable notification on a characteristic without having to call discoverServices(). In my case the call takes a lot of time (5-10sec). It is ensured that the characteristic exists. I have found several solutions on Internet. However, discoverServices() was called implicitly in each case. My implementation so far looks like...

private void onConnectionReceived(RxBleConnection rxBleConnection) {

        rxBleConnection.discoverServices()
                .flatMap(rxBleDeviceServices -> {
                    return rxBleDeviceServices.getCharacteristic(MY_UUID_RX);
                })
                .flatMapObservable(bluetoothGattCharacteristic -> {
                    BluetoothGattDescriptor cccDescriptor = bluetoothGattCharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIGURATION_UUID);
                    Completable enableNotificationCompletable = rxBleConnection.writeDescriptor(cccDescriptor, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                    Completable disableNotificationCompletable = rxBleConnection.writeDescriptor(cccDescriptor, BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE).onErrorComplete();
                    return rxBleConnection.setupNotification(bluetoothGattCharacteristic, NotificationSetupMode.COMPAT)
                            .doOnNext(notificationObservable -> notificationHasBeenSetUp())
                            .flatMap(notificationObservable -> notificationObservable)
                            .mergeWith(enableNotificationCompletable)
                            .doOnDispose(disableNotificationCompletable::subscribe); // fire and forget
                })
                .observeOn(AndroidSchedulers.from(handlerThread.getLooper()))
                .subscribe(this::onNotificationReceived, this::onNotificationSetupFailure);
    }

Thanks for your support !

1 Answers1

0

When a device connects to a new peripheral it needs to perform a service discovery procedure to get attribute (e.g. characteristic) handles.

Even though a characteristic with a given UUID is ensured to be present the device needs to acquire its handle to perform low level BLE operations. Depending on your peripheral's configuration Android OS may cache discovered attribute handles to be reused on subsequent connections.

When performing a service discovery procedure Android OS is always using a full discovery — it iterates over all services / characteristics / descriptors — this takes longer if there are more attributes to discover. Time needed to perform the procedure may be decreased by reducing the amount of attributes on your peripheral.

(iOS on the other hand allows for discovering only a specific/minimal subset of attributes to speed up the process)

I hope this answers your question.

Dariusz Seweryn
  • 3,212
  • 2
  • 14
  • 21