Android перестает находить устройства BLE: onClientRegistered() - status=133 clientIf=0

Я разрабатываю приложение, в котором я могу найти и настроить устройства BLE. Я использую стандартный Android BLE API, но недавно столкнулся с некоторыми странными проблемами.

Когда я включаю свое приложение, сканирование BLE работает нормально. Я сканирую с помощью:

mBluetoothAdapter.startLeScan(mLeScanCallback); // for Kitkat and below

и

mBluetoothAdapter.getBluetoothLeScanner().startScan(mScanCallback); // for Lollipop and above

В Logcat я получаю следующие сообщения (я думаю, это важно для этой проблемы):

D/BluetoothAdapter: onClientRegistered() - status=0 clientIf=5

В моем приложении я также могу считывать определенные характеристики с моих устройств BLE (например, состояние батареи). Я подключаюсь к устройству, чтобы прочитать эту характеристику в отдельном фрагменте, используя:

mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mMacAddress);
mBluetoothGatt = mBluetoothDevice.connectGatt(mContext, false, mGattCallback);

Характеристики читаются правильно. В обратном вызове onCharacteristicRead я также отключаю и закрываю Gatt:

mBluetoothGatt.disconnect();
mBluetoothGatt.close();

Каждый раз, когда я открываю фрагмент для чтения характеристики (неважно, одно и то же это устройство или нет) значение clientIf увеличивается. Я вижу в LogCat:

D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=8
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=9
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=10

Все работает нормально, пока значение clientIf не станет равным 10. Сканирование BLE перестает находить какие-либо устройства, я не могу подключиться ни к одному из своих устройств, чтобы прочитать какие-либо характеристики и т. д. И LogCat бесконечно отображает эти сообщения:

D/BluetoothGatt: unregisterApp() - mClientIf=0
D/BluetoothGatt: onClientRegistered() - status=133 clientIf=0

Единственный способ исправить это — закрыть приложение и перезапустить его или перезапустить Bluetooth, выключив и включив его вручную. Я столкнулся с этой проблемой только на некоторых устройствах, таких как Xperia Z1 (Android KitKat) и Galaxy S4 (Android Lollipop). Мне не удалось воспроизвести эту проблему на Xperia Z3 Compact под управлением Android Marshmallow...

Могу ли я что-нибудь с этим поделать? Я уже пробовал несколько «решений», таких как вызов всех методов BLE из потока пользовательского интерфейса и закрытие/отключение GATT, но ничего не помогает. Как я могу это исправить?


person fragon    schedule 22.09.2016    source источник


Ответы (2)


Я отвечу на свой вопрос, потому что, возможно, это поможет кому-то с той же проблемой.

Прежде всего, я не мог решить проблему с падением Bluetooth после того, как значение mClientIf достигло 10. Однако я нашел обходной путь, который помог в моем случае.

Несмотря на то, что я останавливал поиск маяка в первом Fragment и запускал чтение характеристик в другом, BLE API, по-видимому, не останавливал поиск сразу, и после открытия следующего Fragment система создавала другого "клиента".

Вот почему мне нужно подождать некоторое время после выхода из первого Fragment и перед тем, как начать читать характеристику в другом.

Этот метод вызывается в onCreateView "нового" Fragment (использование postDelayed помогло мне решить проблему):

private void getBatteryCharacteristic() {
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                mBeaconBatteryStateReader = new BeaconBatteryStateReader(
                        BeaconDetailsActivity.this,
                        mBeacon.getMacAddress());
                mBeaconBatteryStateReader.readBatteryState(BeaconDetailsActivity.this);
            }
        }, 100);
    }
person fragon    schedule 26.09.2016
comment
У меня была аналогичная проблема, и для меня добавление небольшой задержки между отключением и сканированием также решило проблему. Спасибо! - person Tijn; 08.08.2017
comment
Я нашел то же решение, что и вы. Подробности: github.com/googlesamples/android-BluetoothLeGatt/issues/44 - person Sam Protsenko; 06.12.2017

Закрытие объекта gatt — правильный способ освободить ресурсы. Если он по-прежнему не работает, значит, на этом конкретном телефоне есть ошибка в Android.

Чтобы свести к минимуму вероятность достижения предела, вы можете убедиться, что у вас никогда не будет более одного объекта gatt на устройство.

person Emil    schedule 22.09.2016