Skip to content

Instantly share code, notes, and snippets.

@craigzour
Created May 10, 2018 13:54
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craigzour/edf7f3bd8bef4b162887b4244e27dc1f to your computer and use it in GitHub Desktop.
Save craigzour/edf7f3bd8bef4b162887b4244e27dc1f to your computer and use it in GitHub Desktop.
Here is a way of implementing pairing/bonding with RxAndroidBle
package hello.world
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.BroadcastReceiver
import com.polidea.rxandroidble2.RxBleDevice
import io.reactivex.Completable
import io.reactivex.disposables.Disposables
/**
* Created by clement on 2017-08-24.
*/
class PairingFailedException : RuntimeException()
internal object PairingManager {
/**
* @throws PairingFailedException
*/
// TODO: try to understand why the popup is being displayed in the notification center (sometimes) ???!!!
fun pairWithDevice(context: Context, rxBleDevice: RxBleDevice): Completable {
return Completable.create { completion ->
when (rxBleDevice.bluetoothDevice.bondState) {
BluetoothDevice.BOND_BONDED -> completion.onComplete()
else -> {
val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val deviceBeingPaired = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
if (deviceBeingPaired.address == rxBleDevice.bluetoothDevice.address) {
val state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE)
when (state) {
BluetoothDevice.BOND_BONDED -> completion.onComplete()
BluetoothDevice.BOND_NONE -> completion.tryOnError(PairingFailedException())
}
}
}
}
completion.setDisposable(Disposables.fromAction { context.unregisterReceiver(receiver) })
context.registerReceiver(receiver, IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED))
val createBondResult = rxBleDevice.bluetoothDevice.createBond()
if (createBondResult == false) {
completion.tryOnError(PairingFailedException())
}
}
}
}
}
}
And Then
return PairingManager
.pairWithDevice(this.context, rxBleDevice)
.andThen(connectToBleDevice)
@RobLewis
Copy link

Would it be possible to post a Java version?

@NitroG42
Copy link

NitroG42 commented Jun 21, 2018

For the notification, I think you can call abortBroadcast() at the end of your onReceive method. It will prevent it to be displayed (if that's what you want)

@tspoke
Copy link

tspoke commented Aug 14, 2018

@RobLewis

Java version (with lambda)

    public static class PairingFailedException extends RuntimeException {
    }

    
    public static Completable pairWithDevice(final Context context, final RxBleDevice rxBleDevice) {
        return Completable.create(completion -> {
            if (rxBleDevice.getBluetoothDevice().getBondState() == BluetoothDevice.BOND_BONDED) {
                completion.onComplete();
                return;
            }

            final BroadcastReceiver receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(final Context context, final Intent intent) {
                    final BluetoothDevice deviceBeingPaired = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                    if (deviceBeingPaired.getAddress().equals(rxBleDevice.getBluetoothDevice().getAddress())) {
                        final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);

                        if (state == BluetoothDevice.BOND_BONDED) {
                            completion.onComplete();
                            abortBroadcast();
                        } else if (state == BluetoothDevice.BOND_NONE) {
                            completion.tryOnError(new PairingFailedException());
                            abortBroadcast();
                        }
                    }
                }
            };

            completion.setDisposable(Disposables.fromAction(() -> context.unregisterReceiver(receiver)));
            context.registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED));
            
            final boolean createBondResult = rxBleDevice.getBluetoothDevice().createBond();
            if (!createBondResult) {
                completion.tryOnError(new PairingFailedException());
            }
        });
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment