diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java
index 8b780dd7c..e655de30d 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DiscoveryActivity.java
@@ -20,6 +20,7 @@ package nodomain.freeyourgadget.gadgetbridge.activities;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
+import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
@@ -30,6 +31,7 @@ import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
@@ -123,7 +125,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
}
case BluetoothDevice.ACTION_BOND_STATE_CHANGED: {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- if (device != null && device.getAddress().equals(bondingAddress)) {
+ if (device != null && bondingDevice != null && device.getAddress().equals(bondingDevice.getMacAddress())) {
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
if (bondState == BluetoothDevice.BOND_BONDED) {
handleDeviceBonded();
@@ -134,11 +136,57 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
}
};
- private void handleDeviceBonded() {
- GB.toast(DiscoveryActivity.this, "Successfully bonded with: " + bondingAddress, Toast.LENGTH_SHORT, GB.INFO);
+ private void connectAndFinish(GBDevice device) {
+ GB.toast(DiscoveryActivity.this, getString(R.string.discovery_trying_to_connect_to, device.getName()), Toast.LENGTH_SHORT, GB.INFO);
+ GBApplication.deviceService().connect(device);
finish();
}
+ private void createBond(final GBDeviceCandidate deviceCandidate, int bondingStyle) {
+ if (bondingStyle == DeviceCoordinator.BONDING_STYLE_NONE) {
+ return;
+ }
+ if (bondingStyle == DeviceCoordinator.BONDING_STYLE_ASK) {
+ new AlertDialog.Builder(this)
+ .setCancelable(true)
+ .setTitle(DiscoveryActivity.this.getString(R.string.discovery_pair_title, deviceCandidate.getName()))
+ .setMessage(DiscoveryActivity.this.getString(R.string.discovery_pair_question))
+ .setPositiveButton(DiscoveryActivity.this.getString(R.string.discovery_yes_pair), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ doCreatePair(deviceCandidate);
+ }
+ })
+ .setNegativeButton(R.string.discovery_dont_pair, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate);
+ connectAndFinish(device);
+ }
+ })
+ .show();
+ } else {
+ doCreatePair(deviceCandidate);
+ }
+ }
+
+ private void doCreatePair(GBDeviceCandidate deviceCandidate) {
+ GB.toast(DiscoveryActivity.this, getString(R.string.discovery_attempting_to_pair, deviceCandidate.getName()), Toast.LENGTH_SHORT, GB.INFO);
+ if (deviceCandidate.getDevice().createBond()) {
+ // async, wait for bonding event to finish this activity
+ LOG.info("Bonding in progress...");
+ bondingDevice = deviceCandidate;
+ } else {
+ GB.toast(DiscoveryActivity.this, getString(R.string.discovery_bonding_failed_immediately, deviceCandidate.getName()), Toast.LENGTH_SHORT, GB.ERROR);
+ }
+ }
+
+ private void handleDeviceBonded() {
+ GB.toast(DiscoveryActivity.this, getString(R.string.discovery_successfully_bonded, bondingDevice.getName()), Toast.LENGTH_SHORT, GB.INFO);
+ GBDevice device = DeviceHelper.getInstance().toSupportedDevice(bondingDevice);
+ connectAndFinish(device);
+ }
+
private final BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
@@ -203,7 +251,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
private DeviceCandidateAdapter cadidateListAdapter;
private Button startButton;
private Scanning isScanning = Scanning.SCANNING_OFF;
- private String bondingAddress;
+ private GBDeviceCandidate bondingDevice;
private enum Scanning {
SCANNING_BT,
@@ -358,7 +406,7 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
}
} else {
discoveryFinished();
- Toast.makeText(this, "Enable Bluetooth to discover devices.", Toast.LENGTH_LONG).show();
+ GB.toast(DiscoveryActivity.this, getString(R.string.discovery_enable_bluetooth), Toast.LENGTH_SHORT, GB.ERROR);
}
}
@@ -535,19 +583,24 @@ public class DiscoveryActivity extends GBActivity implements AdapterView.OnItemC
intent.putExtra(DeviceCoordinator.EXTRA_DEVICE_CANDIDATE, deviceCandidate);
startActivity(intent);
} else {
+ GBDevice device = DeviceHelper.getInstance().toSupportedDevice(deviceCandidate);
+ int bondingStyle = coordinator.getBondingStyle(deviceCandidate);
+ if (bondingStyle == DeviceCoordinator.BONDING_STYLE_NONE) {
+ LOG.info("No bonding needed, according to coordinator, so connecting right away");
+ connectAndFinish(device);
+ return;
+ }
+
try {
BluetoothDevice btDevice = adapter.getRemoteDevice(deviceCandidate.getMacAddress());
switch (btDevice.getBondState()) {
case BluetoothDevice.BOND_NONE: {
- if (btDevice.createBond()) {
- // async, wait for bonding event to finish this activity
- bondingAddress = btDevice.getAddress();
- }
+ createBond(deviceCandidate, bondingStyle);
break;
}
case BluetoothDevice.BOND_BONDING:
// async, wait for bonding event to finish this activity
- bondingAddress = btDevice.getAddress();
+ bondingDevice = deviceCandidate;
break;
case BluetoothDevice.BOND_BONDED:
handleDeviceBonded();
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java
index 07abf001d..055156a43 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/AbstractDeviceCoordinator.java
@@ -119,4 +119,9 @@ public abstract class AbstractDeviceCoordinator implements DeviceCoordinator {
}
return false;
}
+
+ @Override
+ public int getBondingStyle(GBDeviceCandidate deviceCandidate) {
+ return BONDING_STYLE_ASK;
+ }
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java
index 66ebdddf6..9b74d3f7c 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java
@@ -47,6 +47,21 @@ import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
*/
public interface DeviceCoordinator {
String EXTRA_DEVICE_CANDIDATE = "nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate.EXTRA_DEVICE_CANDIDATE";
+ /**
+ * Do not attempt to bond after discovery.
+ */
+ int BONDING_STYLE_NONE = 0;
+ /**
+ * Bond after discovery.
+ * This is not recommended, as there are mobile devices on which bonding does not work.
+ * Prefer to use #BONDING_STYLE_ASK instead.
+ */
+ int BONDING_STYLE_BOND = 1;
+ /**
+ * Let the user decide whether to bond or not after discovery.
+ * Prefer this over #BONDING_STYLE_BOND
+ */
+ int BONDING_STYLE_ASK = 2;
/**
* Checks whether this coordinator handles the given candidate.
@@ -207,4 +222,10 @@ public interface DeviceCoordinator {
* @return
*/
Class extends Activity> getAppsManagementActivity();
+
+ /**
+ * Returns how/if the given device should be bonded before connecting to it.
+ * @param deviceCandidate
+ */
+ int getBondingStyle(GBDeviceCandidate deviceCandidate);
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4b6a5d23a..2361af924 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -412,4 +412,13 @@
Text notifications
= 1.0.1.28 and Mili_pro.ft* installed.]]>
off
+ Attempting to pair with %1$s
+ Bonding with %1$s failed immediately.
+ Trying to connect to: %1$s
+ Enable Bluetooth to discover devices.
+ Successfully bonded with %1$s.
+ Pair with %1$s?
+ Select Pair to pair your devices. If this fails, try again without pairing.
+ Pair
+ Don\'t Pair