Search code examples
androidbluetooth-lowenergyrxandroidble

BxAndroidBle cannot read device, status=22


I am having troubles with reading a Ble device and using the RxAndroidBle library.

I keep getting this error:

BleGattException{status=22, bleGattOperation=BleGattOperation{description='CONNECTION_STATE'}}

Can anyone look at my code and see what I might be doing wrong:

subscription = rxBleDevice.establishConnection(context, true)
            .subscribe(rxBleConnection -> {
                rxBleConnection.readCharacteristic(UUID.fromString(UUID_LOG_COUNT)).doOnNext(Action1 -> Logger.d(Helper_Utils.reverseHex(HexString.bytesToHex(Action1))));
            }, throwable -> {
                Logger.d("Error", throwable.getMessage());
            });

If you need more info, I will try to provide it.

EDIT

I have used 2 different phones: OnePlus Two Android 6.0.1 Moto G Play Android 6.0.1

I have tried multiple times switching wifi and bluetooth on and off. I have never been able to get a reading with this example.


Solution

  • status = 22 is a problem related to Android OS disconnecting your peripheral. There is not much you can do from the code to prevent it.

    As for not reading the characteristic value — it is because you are not subscribing to it. The best approach in RxJava programming (or reactive programming in general) is to prepare a flow with only a single subscribe because then you minimise the amount of state.

    You could do like this:

    Subscription s = rxBleDevice.establishConnection(true) // establish the connection
      .flatMap(rxBleConnection -> rxBleConnection.readCharacteristic(UUID.fromString(UUID_LOG_COUNT))) // when the connection is established start reading the characteristic
      .take(1) // after the first value unsubscribe from the upstream to close the connection
      .subscribe( // subscribe to read values
        characteristicValue -> Logger.d(Helper_Utils.reverseHex(HexString.bytesToHex(characteristicValue))), // do your thing with the read value here
        throwable -> Logger.d("Error", throwable.getMessage()) // log / show possible error here
      );
    

    Remember that the result of .subscribe() is a Subscription which you can cancel by calling Subscription.unsubscribe() which will disconnect the peripheral.

    My code is referencing the new API that was introduced by RxAndroidBle 1.2.0 which was released yesterday.