From 41dde9a9c2dc2bf7bb96e88cd42bd64a8e5b3c2f Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Wed, 6 Jan 2016 00:14:24 +0100 Subject: [PATCH] Programmatically perform a bonding (i.e. bluetooth-level pairing). Previously the pairing appeared to happen automagically, but this doesn't work (anymore). So now we first pair on the bluetooth-level, then application level. --- .../devices/miband/MiBandPairingActivity.java | 73 ++++++++++++++++++- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java index e5109e51..c33a1909 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java @@ -1,15 +1,18 @@ package nodomain.freeyourgadget.gadgetbridge.devices.miband; import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; -import android.util.Log; import android.widget.TextView; import android.widget.Toast; @@ -29,9 +32,12 @@ public class MiBandPairingActivity extends Activity { private static final int REQ_CODE_USER_SETTINGS = 52; private static final String STATE_MIBAND_ADDRESS = "mibandMacAddress"; + private static final long DELAY_AFTER_BONDING = 1000; // 1s private TextView message; private boolean isPairing; private String macAddress; + private String bondingMacAddress; + private final BroadcastReceiver mPairingReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -45,6 +51,29 @@ public class MiBandPairingActivity extends Activity { } }; + private final BroadcastReceiver mBondingReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + if (bondingMacAddress != null && bondingMacAddress.equals(device.getAddress())) { + int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); + if (bondState == BluetoothDevice.BOND_BONDED) { + LOG.info("Bonded with " + device.getAddress()); + bondingMacAddress = null; + Looper mainLooper = Looper.getMainLooper(); + new Handler(mainLooper).postDelayed(new Runnable() { + @Override + public void run() { + performPair(); + } + }, DELAY_AFTER_BONDING); + } + } + } + } + }; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -99,7 +128,13 @@ public class MiBandPairingActivity extends Activity { @Override protected void onDestroy() { - LocalBroadcastManager.getInstance(this).unregisterReceiver(mPairingReceiver); + try { + // just to be sure, remove the receivers -- might actually be already unregistered + LocalBroadcastManager.getInstance(this).unregisterReceiver(mPairingReceiver); + unregisterReceiver(mBondingReceiver); + } catch (IllegalArgumentException ex) { + // already unregistered, ignore + } if (isPairing) { stopPairing(); } @@ -109,15 +144,24 @@ public class MiBandPairingActivity extends Activity { private void startPairing() { isPairing = true; message.setText(getString(R.string.miband_pairing, macAddress)); + IntentFilter filter = new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED); LocalBroadcastManager.getInstance(this).registerReceiver(mPairingReceiver, filter); + filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED); + registerReceiver(mBondingReceiver, filter); - GBApplication.deviceService().connect(macAddress, true); + BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(macAddress); + if (device != null) { + performBluetoothPair(device); + } else { + GB.toast(this, "No such Bluetooth Device: " + macAddress, Toast.LENGTH_LONG, GB.ERROR); + } } private void pairingFinished(boolean pairedSuccessfully) { isPairing = false; LocalBroadcastManager.getInstance(this).unregisterReceiver(mPairingReceiver); + unregisterReceiver(mBondingReceiver); if (pairedSuccessfully) { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -133,4 +177,27 @@ public class MiBandPairingActivity extends Activity { // TODO isPairing = false; } + + protected void performBluetoothPair(BluetoothDevice device) { + int bondState = device.getBondState(); + if (bondState == BluetoothDevice.BOND_BONDED) { + LOG.info("Already bonded: " + device.getAddress()); + performPair(); + return; + } + + bondingMacAddress = device.getAddress(); + if (bondState == BluetoothDevice.BOND_BONDING) { + LOG.info("Bonding in progress: " + device.getAddress()); + return; + } + + if (!device.createBond()) { + GB.toast(this, "Unable to pair with " + device.getAddress(), Toast.LENGTH_LONG, GB.ERROR); + } + } + + private void performPair() { + GBApplication.deviceService().connect(macAddress, true); + } }