Непрерывное и быстрое обнаружение маяков на Android - PullRequest
0 голосов
/ 23 мая 2018

В нашем проекте нам нужно очень быстрое (в идеале менее нескольких секунд) надежное и непрерывное обнаружение маяка, что особенно важно в фоновом режиме.Прямо сейчас мы используем библиотеку AltBeacon, BeaconManager запускается с контекстом службы переднего плана (код предоставлен).

На переднем плане она отлично работает практически на любом устройстве, проблема в работе в фоновом режиме.Некоторые устройства в фоновом режиме не работают через некоторое время (например, Huawei P9 2017, я знаю, что это проблема с устройством).В общем, нам нужна лучшая надежность.

Самая большая проблема заключается в том, что обнаружение на Oreo в фоновом режиме происходит медленно - от секунд до долгих минут, пока он не сообщит о первом маяке.Я прочитал запись на веб-сайте AltBeacon об изменениях для Oreo, поэтому я знаю, что в системе есть ограничения.Итак, вот мой вопрос, есть ли способ улучшить отзывчивость обнаружения (в идеале на всех версиях Android)?Даже по цене большего расхода батареи или некоторых хаков?Я попытался по крайней мере получить исключение из оптимизации батареи в системе, но результаты, вероятно, такие же.

Конфигурация BeaconManager в Фоновом сервисе:

@Override
public void onCreate() {
    super.onCreate();
    beaconManager = BeaconManager.getInstanceForApplication(this);
    beaconManager.setForegroundScanPeriod(1500);
    beaconManager.setForegroundBetweenScanPeriod(0);
    beaconManager.setBackgroundScanPeriod(1500);
    beaconManager.setBackgroundBetweenScanPeriod(0);
    beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(BeaconParser.EDDYSTONE_UID_LAYOUT));
    beaconManager.bind(this);
    if (CommConstants.sdkIsAtLeastSDK(21)) {
        BluetoothMedic medic = BluetoothMedic.getInstance();
        medic.enablePowerCycleOnFailures(this);
        medic.enablePeriodicTests(this, BluetoothMedic.SCAN_TEST);
    }
    goForeground();
}

Запуск мониторинга:

private static final Region REGION = new Region(BuildConfig.APPLICATION_ID, null, null, null);

protected void startBeaconMonitoring() {
    if (beaconManager.isBound(this)) {
        findingEnabled = true;
        beaconManager.addRangeNotifier(
                (collection, region) -> {
                    for (Beacon beacon : collection) {
                        // beacon processing
                    }
                });
        try {
            mLogger.debug("Started beacon monitoring");
            beaconManager.startRangingBeaconsInRegion(REGION);
            beaconManager.startMonitoringBeaconsInRegion(REGION);
        } catch (RemoteException e) {
            LoggerFactory.getLogger(App.class).error("Monitoring start exception", e);
        }
        regionBootstrap = new RegionBootstrap(this, REGION);
        startLocationUpdates();
    }
}

Я заметил, что PR-служба маяка находится на переднем плане в библиотеке-маяка-андроида, возможно ли, что это повысит надежность?

1 Ответ

0 голосов
/ 24 мая 2018

Проблема

По умолчанию библиотека, работающая на Android 8+, будет использовать JobScheduler для планирования сканирования, когда ваше приложение находится в фоновом режиме.Но поскольку Android ограничивает задания в JobScheduler каждые 15 минут, вызов beaconManager.setBackgroundBetweenScanPeriod(0); не влияет на Android 8. В последней версии библиотеки в LogCat появляется предупреждение об этом: Setting a short backgroundBetweenScanPeriod has no effect on Android 8+, which is limited to scanning every ~15 minutes.Для получения более подробной информации об этом ограничении см. Здесь:

http://www.davidgyoungtech.com/2017/08/07/beacon-detection-with-android-8

Известное решение

Служба переднего плана в Android 8 позволит службе работать непрерывносканировать маяки, как в Android 4.x-7.x.Как известно, создание службы сканирования библиотеки в качестве приоритетного.Это изначально поддерживается библиотекой версии 2.15+.Подробнее см. здесь .

Возможная альтернатива

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

 beaconManager.setSceduledScanJobsEnabled(false);

, так как для Android 8+ по умолчанию установлено значение true.После внесения этого изменения долгосрочная Служба будет использоваться для планирования проверок с заданной вами скоростью.

Будет ли это работать?Это неясно, потому что служба сканирования библиотеки все еще не является приоритетной службой и может быть убита Android 8 после работы в течение> 5 минут в фоновом режиме.Тот факт, что у вас есть другая служба в вашем приложении, которая является приоритетной службой, может или не может быть достаточной для Android 8, чтобы запустить службу сканирования.Вам придется попробовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...