Which correct flag of autoConnect in connectGatt of BLE?
Asked Answered
F

2

24

My goal is to make 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 works. 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;
}
Flew answered 20/10, 2016 at 14:2 Comment(0)
U
50

"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.

NEW CHANGE IN ANDROID 10

Since Android 10, the direct connect queue is removed and will not temporarily pause auto connects any more. This is because direct connect now uses the white list just like auto connects. The scan window/interval is improved while a direct connect is ongoing.

Unstuck answered 22/10, 2016 at 0:20 Comment(4)
This is useful information about the auto connect behaviour. Do you have a reference for it? The connectGatt docs don't give much detail, and I've so far not found the right bit of the Android source code (BluetoothGatt.java calls clientConnect on IBluetoothGatt, which comes from an .aidl file, but I haven't found anything implementing that yet)Vermilion
It's quite many layers the connect command goes through. You can check out GATT_Connect in android.googlesource.com/platform/system/bt/+/master/stack/gatt/…. Here is the other end of the aidl interface: android.googlesource.com/platform/packages/apps/Bluetooth/+/….Unstuck
@Emil, does autoconnect work when the app is in background? Perhaps in service?Matador
BLE GATT connections and transmissions are not involved in how an app is kept alive or is candidate for being killed. So if you want a long-lived GATT connection or pending connection, you should have a foreground service running in your app process so your process isn't killed.Unstuck
I
0

The autoConnect parameter determines whether to actively connect to the remote device, or rather passively scan and finalize the connection when the remote device is in range/available. Generally, the first ever connection to a device should be direct (autoConnect set to false) and subsequent connections to known devices should be invoked with the autoConnect parameter set to true.

Ivory answered 12/2, 2021 at 10:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.