user8430 user8430 - 1 month ago 23
Android Question

Which correct flag of autoConnect in connectGatt of BLE?

my goal is making an auto connection between Bluetooth Low Energy device and phone. I followed the sample code and I found the line

// We want to directly connect to the device, so we are setting the autoConnect parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);


The above code means that
false
uses to autoconnection. However, I found the API at here, it said that


BluetoothGatt connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback, int transport)
Connect to GATT Server hosted by this device.


And I also tried two flags:
true
and
false
, and only
true
is work. I am using version >= Android 5.0. Has something inconsistent between code and API? Which flag is correct? Do I need note something if I want to make the auto connection?

This is my code

public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
return false;
}

// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, "Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}

final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, true, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}

Answer

"Direct connect" is the opposite to "auto connect", so if you set the autoConnect parameter to false you get a "direct connect". Note that doing a "mBluetoothGatt.connect()" will also use auto connect.

Beware of https://code.google.com/p/android/issues/detail?id=69834 which is a bug affecting older versions of Android which might make your auto connections to be direct connections instead. This can be worked around with reflection.

There are a few non-documented differences between direct and auto connect:

Direct connect is a connection attempt with a 30 seconds timeout. It will suspend all current auto connects while the direct connect is in progress. If there already is a direct connect pending, the last direct connect will not be executed immediately but rather be queued up and start when the previous has finished.

With auto connect you can have multiple pending connections at the same time and they will never time out (until explicitly aborted or until Bluetooth is turned off).

If the connection was established through an auto connect, Android will automatically try to reconnect to the remote device when it gets disconnected until you manually call disconnect() or close(). Once a connection established through direct connect disconnects, no attempt is made to reconnect to the remote device.

Direct connect has a different scan interval and scan window at a higher duty than auto connect, meaning it will dedicate more radio time to listen for connectable advertisements for the remote device, i.e. the connection will be established faster.