Сканирование BLE не работает, когда экран отключен на Android 8.1.0

Я использую пиксель с последним обновлением android 8.1.0.

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

Я проверил последний код для BLE. Google снова представит эту функцию (Ссылка Ссылка).

Есть ли способ пропустить эту часть, я имею в виду, что сканирование не должно останавливаться независимо от того, включен или выключен экран.

Ответ 1

Начиная с Android 8.1 нефильтрованное сканирование по Bluetooth блокируется при выключении экрана. Несмотря на то, что столь существенное изменение было внесено в небольшом выпуске Android, это, конечно же, намеренное изменение, основанное на комментариях в коммите: Остановите нефильтрованные сканирования BLE, когда экран выключится.

Обходной путь должен использовать ScanFilter со всеми сканированиями. Новый код операционной системы 8.1 просто подтверждает, что все активные сканирования, когда экран выключен, имеют хотя бы один фильтр сканирования. Если эти условия соблюдены, результаты сканирования выдаются как в Android 8.0.x и более ранних версиях.

Чтобы настроить такое сканирование, вы должны использовать API, представленные в Android 5.0, и создавать ScanFilter при каждом сканировании. Ниже приведен фильтр, который найдет рекламу производителя для любого устройства Apple с идентификатором производителя 0x004c (включая iBeacons):

ScanFilter.Builder builder = new ScanFilter.Builder();
builder.setManufacturerData(0x004c, new byte[] {});
ScanFilter filter = builder.build();

Аналогичным образом, если вас интересуют рекламные объявления службы GATT (например, такие, которые используются с маяками Eddystone), вы можете выполнить поиск UUID службы GATT с помощью фильтра, подобного следующему:

ScanFilter.Builder builder = new ScanFilter.Builder();
String serviceUuidString = "0000feaa-0000-1000-8000-00805f9b34fb";
String serviceUuidMaskString = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF";
ParcelUuid parcelUuid = ParcelUuid.fromString(serviceUuidString);
ParcelUuid parcelUuidMask = ParcelUuid.fromString(serviceUuidMaskString);
builder.setServiceUuid(parcelUuid, parcelUuidMask);
ScanFilter filter = builder.build();

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

Вы начинаете сканирование с помощью кода, подобного следующему:

bluetoothAdapter.getBluetoothLeScanner().startScan(filters, settings, scanCallback);

РЕДАКТИРОВАТЬ: Это также возможно сделать с пустым ScanFilter который выглядит следующим образом:

ScanFilter.Builder builder = new ScanFilter.Builder();
ScanFilter filter = builder.build();

Если вы используете такой фильтр сканирования, он будет соответствовать любому рекламному пакету и по-прежнему разрешать обнаружение с выключенным экраном на Android 8.1, что фактически даст вам такое же поведение на Android 8.0.x и более ранних версиях.

РЕДАКТИРОВАТЬ 2: На Galaxy Note 9 с Android 8.1 и, возможно, на других устройствах Samsung с 8.1, сканирование блокируется с выключенным экраном даже при пустом фильтре сканирования. Сканирование разрешено с выключенным экраном с непустым фильтром сканирования, как описано выше.

Ответ 2

Очевидно, нет, если они ничего не пропустили. Но он все равно будет работать в фоновом режиме, если у вас есть фильтры сканирования, которые вы должны иметь в любом случае. Так это действительно проблема?

Ответ 3

Я столкнулся с той же проблемой. У меня были фильтры сканирования для сканирования устройств BLE, даже если экран был заблокирован. Но на устройствах Samsung это не сработало, поэтому я поискал на форуме Samsung и обнаружил Knox SDK (https://seap.samsung.com/sdk/knox-android).

И это было решением моей проблемы. Все, что вам нужно сделать, это добавить его в ваше приложение, создать лицензию, активировать ее и, наконец, использовать этот метод addPackageToBatteryOptimizationWhiteList, чтобы разблокировать сканирование, когда экран устройства Samsung заблокирован.

Ответ 4

У меня такая же проблема на телефоне 10 (COL L-29) 8.1.0, но добавление сервисного фильтра не решает проблему сканера. У вас есть другие идеи или вы столкнулись с той же проблемой в EMUI? Для информации, на моем устройстве рекламные данные содержат только сервис UUID.

Заранее спасибо ;)