1

As reported here, I have a legacy app that refuses to connect to one of the peripherals I'm trying to support (works OK with others). RxAndroidBle connects successfully too, and I'm thinking to use it just to establish the connection and hand it to the rest of the app. I need to get the BluetoothGatt object from the RxBleConnection; how can I do this?

Robert Lewis
  • 1,847
  • 2
  • 18
  • 43

2 Answers2

2

After careful study of the docs, I hope I have gotten this right. The extensive comments are for my own benefit but perhaps they will help others trying to understand this. Comments & corrections welcome.

public class GetGattOperation implements RxBleCustomOperation<BluetoothGatt> {

    private BluetoothGatt gatt;

    // How this may work:

    // You call rxBleConnection.queue( <instance of this class> )
    // It returns an Observable<T>--call it Observable A

    // The queue manager calls the .asObservable() method below,
    // which returns another Observable<T>--Observable B
    // It is placed in the queue for execution

    // When it's time to run this operation, ConnectionOperationQueue will
    // subscribe to Observable B (here, Observable.just( bluetoothGatt ))

    // Emissions from this Observable B (here, the bluetoothGatt) are forwarded to the Observable A returned by .queue()

    // Instances can be queued and received via a subscription to Observable A: 
    // rxBleConnection.queue( new GetGattOperation() ).subscribe( gatt -> {} );

    @Override
    public @NonNull Observable<BluetoothGatt> asObservable( BluetoothGatt bluetoothGatt,
                                                            RxBleGattCallback rxBleGattCallback,
                                                            Scheduler scheduler) throws Throwable {

        gatt = bluetoothGatt;
        return Observable.just( bluetoothGatt );  // return Observable B
    }


    public BluetoothGatt getGatt( ) {
        return gatt;
    }

}

The main program uses this like so (in the .establishConnection() operator chain):

.doOnNext( connection -> {
    rxBleConnection = connection;
    connection.queue( new GetGattOperation() )  // queue() returns Observable A
        .subscribe( gatt -> {  // receives events forwarded from Observable B
            Log.i( "Main", "BluetoothGatt received: " + gatt.toString() );
        } );
    } 
)
Robert Lewis
  • 1,847
  • 2
  • 18
  • 43
  • This is also available as a Gist: https://gist.github.com/RobLewis/fc20bde8ce71c7da2040d04b2ba3c156 – Robert Lewis Dec 07 '18 at 18:14
  • Hi @Robert Lewis I'm trying use `RxBleCustomOperation` to set native callback `rxBleGattCallback.setNativeCallback` but I don't understand well, could you give me an example please? – Moises Apaza Q Jul 26 '19 at 02:44
  • First of all, did you see the Javadoc for the `RxBleGattCallback` class? It recommends against using native callbacks except in performance-critical applications. – Robert Lewis Jul 27 '19 at 22:36
1

Currently the only option to obtain an instance of BluetoothGatt is to implement a RxBleCustomOperation interface and use it on the RxBleConnection.queue(RxBleCustomOperation)

public interface RxBleCustomOperation<T> {

  /**
   * (...)
   */
  @NonNull
  Observable<T> asObservable(BluetoothGatt bluetoothGatt,
                             RxBleGattCallback rxBleGattCallback,
                             Scheduler scheduler) throws Throwable;
}

Be mindful about the Javadoc on both the RxBleCustomOperation interface and on the RxBleConnection.queue(RxBleCustomOperation) function.

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