Какой правильный флаг автоматического подключения в connectGatt BLE?

#android #bluetooth #bluetooth-lowenergy #bluetooth-gatt

#Android #bluetooth #bluetooth-низкое энергопотребление #bluetooth-gatt

Вопрос:

Моя цель — установить автоматическое соединение между устройством Bluetooth с низким энергопотреблением и телефоном. Я проследил за примером кода и нашел строку

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

Приведенный выше код означает, что false используется для автоматического подключения. Тем не менее, я нашел API по адресу здесь, в нем сказано, что

BluetoothGatt connectGatt (контекстный контекст, логическое автоматическое подключение, обратный вызов BluetoothGattCallback, внутренний транспорт) Подключается к серверу GATT, размещенному на этом устройстве.

И я также попробовал два флага: true и false , и только true работает. Я использую версию > = Android 5.0. Есть ли что-то несовместимое между кодом и API? Какой флаг правильный? Нужно ли мне что-то отмечать, если я хочу установить автоматическое подключение?

Это мой код

 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 amp;amp; address.equals(mBluetoothDeviceAddress)
            amp;amp; 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;
}
  

Ответ №1:

«Прямое подключение» противоположно «автоматическому подключению», поэтому, если вы установите для параметра AutoConnect значение false, вы получите «прямое подключение». Обратите внимание, что при выполнении «mBluetoothGatt.connect()» также будет использоваться автоматическое подключение.

Остерегайтесь https://code.google.com/p/android/issues/detail?id=69834 какая ошибка влияет на более старые версии Android, из-за которой ваши автоматические подключения могут быть прямыми подключениями вместо этого. Это можно обойти с помощью отражения.

Есть несколько недокументированных различий между прямым и автоматическим подключением:

Прямое подключение — это попытка подключения с таймаутом в 30 секунд. Это приостановит все текущие автоматические подключения, пока выполняется прямое подключение. Если прямое подключение уже находится в ожидании, последнее прямое подключение не будет выполнено немедленно, а скорее будет помещено в очередь и начнется после завершения предыдущего.

С автоматическим подключением у вас может быть несколько ожидающих подключений одновременно, и у них никогда не истечет время ожидания (до явного прерывания или до отключения Bluetooth).

Если соединение было установлено с помощью автоматического подключения, Android автоматически попытается повторно подключиться к удаленному устройству при его отключении, пока вы вручную не вызовете disconnect () или close (). Как только соединение, установленное через direct connect, отключается, попытки повторного подключения к удаленному устройству не предпринимаются.

У Direct connect другой интервал сканирования и окно сканирования с более высокой нагрузкой, чем у auto connect, что означает, что он будет выделять больше времени на прослушивание подключаемой рекламы для удаленного устройства, т. е. соединение будет установлено быстрее.

НОВОЕ ИЗМЕНЕНИЕ В ANDROID 10

Начиная с Android 10, очередь прямого подключения удалена и больше не будет временно приостанавливать автоматическое подключение. Это потому, что прямое подключение теперь использует белый список точно так же, как и автоматическое подключение. Улучшено окно / интервал сканирования при продолжающемся прямом подключении.

Комментарии:

1. Это полезная информация о поведении автоматического подключения. У вас есть ссылка на это? В документах connectGatt не приводится много подробностей, и я до сих пор не нашел нужную часть исходного кода Android ( BluetoothGatt.java вызовы clientConnect на IBluetoothGatt , которые поступают из .aidl файла, но я пока не нашел ничего, что бы это реализовывало)

2. Команда connect проходит через довольно много уровней. Вы можете проверить GATT_Connect в android.googlesource.com/platform/system/bt/ /master/stack/gatt /… . Вот другой конец интерфейса aidl: android.googlesource.com/platform/packages/apps/Bluetooth / /… .

3. @Emil, работает ли автоматическое подключение, когда приложение работает в фоновом режиме? Возможно, в сервисе?

4. Соединения и передачи BLE GATT не влияют на то, как приложение поддерживается в рабочем состоянии или является кандидатом на уничтожение. Итак, если вы хотите долговременное соединение GATT или ожидающее подключения, у вас должна быть запущена служба переднего плана в процессе вашего приложения, чтобы ваш процесс не был остановлен.

Ответ №2:

Параметр автоматического подключения определяет, следует ли активно подключаться к удаленному устройству или, скорее, пассивно сканировать и завершать подключение, когда удаленное устройство находится в зоне действия / доступно. Как правило, первое подключение к устройству должно быть прямым (для автоматического подключения установлено значение false), а последующие подключения к известным устройствам должны вызываться с параметром AutoConnect, установленным в true.