Skip to content

Commit 02e7efb

Browse files
authored
Merge pull request #575 from muscardinus/start-auto-connect-immediately
Start auto connect immediately
2 parents 061e98c + 85459c7 commit 02e7efb

File tree

2 files changed

+78
-18
lines changed

2 files changed

+78
-18
lines changed

ble/src/main/java/no/nordicsemi/android/ble/BleManagerHandler.java

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -689,48 +689,62 @@ private boolean internalConnect(@NonNull final BluetoothDevice device,
689689
// when retrying to create a connection.
690690
if (connectRequest == null)
691691
return false;
692+
692693
final boolean shouldAutoConnect = connectRequest.shouldAutoConnect();
693-
// We will receive Link Loss events only when the device is connected with autoConnect=true.
694-
userDisconnected = !shouldAutoConnect;
695-
// The first connection will always be done with autoConnect = false to make the connection quick.
696-
// If the shouldAutoConnect() method returned true, the manager will automatically try to
697-
// reconnect to this device on link loss.
694+
final boolean autoConnect;
698695
if (shouldAutoConnect) {
699-
initialConnection = true;
696+
// If shouldAutoConnectCreateDirectConnectionFirst() returns true, the first connection
697+
// will always be done with autoConnect = false to make the connection quick.
698+
// If the shouldAutoConnect() method returned true, the manager will automatically try
699+
// to reconnect to this device on link loss.
700+
initialConnection = connectRequest.shouldAutoConnectCreateDirectConnectionFirst();
701+
autoConnect = !initialConnection;
702+
} else {
703+
autoConnect = false;
700704
}
705+
// We will receive Link Loss events only when the device is connected with autoConnect=true.
706+
userDisconnected = !shouldAutoConnect;
707+
701708
bluetoothDevice = device;
702-
log(Log.VERBOSE, () -> connectRequest.isFirstAttempt() ? "Connecting..." : "Retrying...");
703-
connectionState = BluetoothGatt.STATE_CONNECTING;
704-
postCallback(c -> c.onDeviceConnecting(device));
705-
postConnectionStateChange(o -> o.onDeviceConnecting(device));
709+
if (!autoConnect) {
710+
log(Log.VERBOSE, () -> connectRequest.isFirstAttempt() ? "Connecting..." : "Retrying...");
711+
connectionState = BluetoothGatt.STATE_CONNECTING;
712+
postCallback(c -> c.onDeviceConnecting(device));
713+
postConnectionStateChange(o -> o.onDeviceConnecting(device));
714+
}
706715
connectionTime = SystemClock.elapsedRealtime();
707716
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
708717
// connectRequest will never be null here.
709718
final int preferredPhy = connectRequest.getPreferredPhy();
710719
log(Log.DEBUG, () ->
711-
"gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, "
720+
"gatt = device.connectGatt(autoConnect = " + autoConnect + ", TRANSPORT_LE, "
712721
+ ParserUtils.phyMaskToString(preferredPhy) + ")");
713722

714-
bluetoothGatt = device.connectGatt(context, false, gattCallback,
723+
bluetoothGatt = device.connectGatt(context, autoConnect, gattCallback,
715724
BluetoothDevice.TRANSPORT_LE, preferredPhy, handler);
716725
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
717726
// connectRequest will never be null here.
718727
final int preferredPhy = connectRequest.getPreferredPhy();
719728
log(Log.DEBUG, () ->
720-
"gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, "
729+
"gatt = device.connectGatt(autoConnect = " + autoConnect + ", TRANSPORT_LE, "
721730
+ ParserUtils.phyMaskToString(preferredPhy) + ")");
722731
// A variant of connectGatt with Handled can't be used here.
723732
// Check https://github.com/NordicSemiconductor/Android-BLE-Library/issues/54
724733
// This bug specifically occurs in SDK 26 and is fixed in SDK 27
725-
bluetoothGatt = device.connectGatt(context, false, gattCallback,
734+
bluetoothGatt = device.connectGatt(context, autoConnect, gattCallback,
726735
BluetoothDevice.TRANSPORT_LE, preferredPhy/*, handler*/);
727736
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
728-
log(Log.DEBUG, () -> "gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE)");
729-
bluetoothGatt = device.connectGatt(context, false, gattCallback,
737+
log(Log.DEBUG, () -> "gatt = device.connectGatt(autoConnect = " + autoConnect + ", TRANSPORT_LE)");
738+
bluetoothGatt = device.connectGatt(context, autoConnect, gattCallback,
730739
BluetoothDevice.TRANSPORT_LE);
731740
} else {
732-
log(Log.DEBUG, () -> "gatt = device.connectGatt(autoConnect = false)");
733-
bluetoothGatt = device.connectGatt(context, false, gattCallback);
741+
log(Log.DEBUG, () -> "gatt = device.connectGatt(autoConnect = " + autoConnect + ")");
742+
bluetoothGatt = device.connectGatt(context, autoConnect, gattCallback);
743+
}
744+
745+
if (autoConnect && this.connectRequest != null) {
746+
this.connectRequest.notifySuccess(device);
747+
this.connectRequest = null;
734748
}
735749
return true;
736750
}

ble/src/main/java/no/nordicsemi/android/ble/ConnectRequest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public class ConnectRequest extends TimeoutableRequest {
6060
@IntRange(from = 0)
6161
private int delay = 0;
6262
private boolean autoConnect = false;
63+
private boolean autoConnectCreateDirectConnectionFirst = true;
6364

6465
ConnectRequest(@NonNull final Type type, @NonNull final BluetoothDevice device) {
6566
super(type);
@@ -209,6 +210,47 @@ public ConnectRequest useAutoConnect(final boolean autoConnect) {
209210
return this;
210211
}
211212

213+
/**
214+
* Sets whether to connect to the remote device just once (autoConnect == false) or to add
215+
* the address to white list of devices that will be automatically connect as soon as they
216+
* become available (autoConnect == true). In the latter case, if Bluetooth adapter is enabled,
217+
* Android scans periodically for devices from the white list and, if an advertising packet
218+
* is received from such, it tries to connect to it.
219+
* When the connection is lost, the system will keep trying to reconnect to
220+
* it. If method is called with autoConnect set to true, and the connection to the device is
221+
* lost, the {@link BleManagerCallbacks#onLinkLossOccurred(BluetoothDevice)} callback is
222+
* called instead of {@link BleManagerCallbacks#onDeviceDisconnected(BluetoothDevice)}.
223+
* <p>
224+
* This feature works much better on newer Android phone models and may have issues on older
225+
* phones.
226+
* <p>
227+
* This method should only be used with bonded devices, as otherwise the device may change
228+
* it's address. It will however work also with non-bonded devices with private static address.
229+
* A connection attempt to a non-bonded device with private resolvable address will fail.
230+
* <p>
231+
* If createDirectConnectionFirst is set to true, the first connection to a device will always be
232+
* created with autoConnect flag to false
233+
* (see {@link BluetoothDevice#connectGatt(Context, boolean, BluetoothGattCallback)}). This is
234+
* to make it quick as the user most probably waits for a quick response. If autoConnect is
235+
* used (true), the following connections will be done using {@link BluetoothGatt#connect()},
236+
* which forces the autoConnect parameter to true.
237+
* If autoConnect is used (true) and createDirectConnectionFirst is set to false, the connection
238+
* to a device will be created with autoConnect flag to true from the start.
239+
*
240+
* @param autoConnect true to use autoConnect feature.
241+
* @param createDirectConnectionFirst If true, the first connection is always done with autoConnect
242+
* parameter equal to false, to make it faster and allow to timeout
243+
* if the device is unreachable.
244+
* If false, the connection to a device will be created with
245+
* autoConnect flag to true from the start.
246+
* @return The request.
247+
*/
248+
public ConnectRequest useAutoConnect(final boolean autoConnect, final boolean createDirectConnectionFirst) {
249+
this.autoConnect = autoConnect;
250+
this.autoConnectCreateDirectConnectionFirst = createDirectConnectionFirst;
251+
return this;
252+
}
253+
212254
/**
213255
* Sets the preferred PHY used for connection. The value should be a bitmask composed of
214256
* {@link PhyRequest#PHY_LE_1M_MASK}, {@link PhyRequest#PHY_LE_2M_MASK} or
@@ -293,4 +335,8 @@ int getRetryDelay() {
293335
boolean shouldAutoConnect() {
294336
return autoConnect;
295337
}
338+
339+
boolean shouldAutoConnectCreateDirectConnectionFirst() {
340+
return autoConnectCreateDirectConnectionFirst;
341+
}
296342
}

0 commit comments

Comments
 (0)