Как подключить Android после отключения и включения адаптера Bluetooth? - PullRequest
0 голосов
/ 30 августа 2018

Я написал приложение, которое подключается к устройству BLE. Приложение работает нормально на большинстве устройств; но некоторые устройства (наиболее заметно Huawei P8 Lite и Nexus 6P) отказываются подключаться после отключения адаптера Bluetooth.

Это тестовая последовательность:

  1. Убедитесь, что приложение НЕ запущено.
  2. Сдвиньте сверху вниз, отключите BT на пару секунд, затем снова включите Bluetooth.
  3. Запустите приложение. Приложение автоматически подключается к адресу Bluetooth, сохраненному в настройках.
  4. Дождитесь подключения. Именно здесь ничего не происходит на телефонах Huawei, но другие телефоны, такие как Samsung, работают как шарм.
  5. Проверьте с другого телефона, что устройство рекламирует, и вы можете подключиться к нему.

Это код, который я использую для подключения:

private final Runnable mBeginConnectRunnable = new Runnable() {
    @Override
    public void run() {
        synchronized (GattConnection.this) {
            if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
                try {
                    mBluetoothAdapter.cancelDiscovery();
                    mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mAddress);
                    mGatt = mBluetoothDevice.connectGatt(mContext, mBackgroundConnect, mGattCallback);
                    final boolean connectSuccess = mGatt.connect();
                    Log.d(TAG, String.format(Locale.ENGLISH, "mGatt.connect(%s, %s) %s",
                            mAddress,
                            mBackgroundConnect ? "background[slow]" : "foreground[fast]",
                            connectSuccess ? "success" : "failed"));
                    refreshDeviceCache(mGatt);

                } catch (Exception ex) {
                    Log.e(TAG, "Create connection failed: " + ex.getMessage());
                    setState(State.Closed);
                }
            } else {
                Log.d(TAG, "Can't create connection. Adapter is disabled");
                setState(State.Closed);
            }
        }
    }
};

Все звонки отправляются через обработчик в основную ветку. Я вижу, что он ждет подключения, сдается через 30 секунд, после чего я вызываю BluetoothGatt.close () для объекта и обнуляет его. Как будто там ничего нет.

Через некоторое время, позже в тот же день, он снова работает.

Помощь высоко ценится: -)

Обновление 14 сентября 2018 года. После великолепного объяснения от Эмиля я обновил наше приложение, и поэтому у Nexus такой проблемы нет. Я заметил, что Huawei P8 Lite продолжает сканирование в фоновом режиме, и кажется, что вы ничего не можете сделать, чтобы остановить его.

Чтобы продемонстрировать проблемы, я сделал очень простое и понятное приложение, которое выполняет функции Bluetooth LE на телефоне, и использовал его для демонстрации этой проблемы, а также P8 сломался. Приложение доступно здесь: https://play.google.com/store/apps/details?id=eu.millibit.bluetootherror Источник доступен здесь: https://bitbucket.org/millibit/eu.millibit.bluetootherror/src/master/

Надеюсь, со временем я смогу расширить это приложение, чтобы оно стало тестовым средством для Android, документировавшим все странное поведение с Android и собирающим его в базу данных. Если вы заинтересованы в участии, не стесняйтесь, напишите мне на bt.error@millibit.dk

1 Ответ

0 голосов
/ 30 августа 2018

У стека Android Bluetooth есть недостаток дизайна в его API. Когда вы подключаетесь к определенному устройству по адресу устройства Bluetooth, невозможно определить, имеете ли вы в виду публичный или случайный адрес.

Если вы начнете подключаться к устройству с autoConnect = false, которое не связано и недавно не было просмотрено при сканировании, это будет означать, что вы имеете в виду публичный адрес. Поэтому, если вы попытаетесь подключиться к устройству, имеющему статический случайный адрес, произойдет сбой.

Чтобы быть уверенным, что вы подключаетесь с правильным типом адреса, если устройство не подключено, вы ДОЛЖНЫ сначала выполнить сканирование, найти устройство и ЗАТЕМ запустить попытку подключения.

...