Режим переднего плана библиотеки Altbeacon не работает на Android

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

Проблема

Когда я перевожу свое приложение в фоновый режим (нажимая кнопку «Домой»), несмотря на то, что сканирование все еще работает в течение минуты, по истечении этого интервала непрерывное сканирование останавливается и снова начинается через 5 минут.

Код

public class BoikomApplication extends MultiDexApplication implements BootstrapNotifier, BeaconConsumer, RangeNotifier { 
...
 public void startListening() {

    final Notification.Builder builder = new Notification.Builder(this);
    builder.setSmallIcon(R.drawable.ic_logo);
    builder.setContentTitle(getString(R.string.foreground_notification_title));
    builder.setContentText(getString(R.string.foreground_notification_text));
    Intent intent = new Intent(this, BeaconActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(
            this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT
    );
    builder.setContentIntent(pendingIntent);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                "Notification Channel", NotificationManager.IMPORTANCE_DEFAULT);
        channel.setDescription("Listening for beacons");
        NotificationManager notificationManager = (NotificationManager) getSystemService(
                Context.NOTIFICATION_SERVICE);
        if (notificationManager != null) {
            notificationManager.createNotificationChannel(channel);
            builder.setChannelId(channel.getId());
        }
    }
    beaconManager.enableForegroundServiceScanning(builder.build(), 456);
    beaconManager.setBackgroundMode(false);
    beaconManager.setEnableScheduledScanJobs(false);
    beaconManager.setBackgroundBetweenScanPeriod(0);
    beaconManager.setBackgroundScanPeriod(1100);

    backgroundPowerSaver = new BackgroundPowerSaver(this);

    beaconManager.bind(this);
   }
@Override
public void didEnterRegion(Region region) {
    LoggingHelper.i("[Beacon Service] didEnterRegion");
    BeaconServiceHandler.getInstance().onEnterRegion(region, this);
}
@Override
public void didExitRegion(Region region) {
    Log.d("App", "didExitRegion");
}

@Override
public void didDetermineStateForRegion(int state, Region region) {
    LoggingHelper.i("[Beacon Service] didDetermineStateForRegion");
}

@Override
public void onBeaconServiceConnect() {
    beaconManager.addMonitorNotifier(this);
    try {
        for (Region region : regions) {
            beaconManager.startRangingBeaconsInRegion(region);
        }
    } catch (Exception e) {
        LoggingHelper.e("[Beacon Service] Error while connecting to beacon service", e);
    }
    beaconManager.addRangeNotifier(this);
}
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> collection, Region region) {
    LoggingHelper.i("[Beacon Service] didRangeBeaconsInRegion");
    BeaconServiceHandler.getInstance().onEnterRegion(region, this);
}
public void stopListening() {
    beaconManager.unbind(this);
    beaconManager.disableForegroundServiceScanning();
}

Журналы

  2019-07-20 01:13:35.409 13181-13181/package D/CycledLeScanner: Waiting to stop scan cycle for another 89 milliseconds
    2019-07-20 01:13:35.417 13181-13181/package D/CycledLeScanner: Set a wakeup alarm to go off in 300000 ms: PendingIntent{69e638a: android.os.BinderProxy@a809dfb}
    2019-07-20 01:13:35.506 13181-13181/package D/CycledLeScanner: Done with scan cycle
    2019-07-20 01:13:35.509 13181-13181/package D/ScanHelper: Calling ranging callback
    2019-07-20 01:13:35.509 13181-13181/package D/Callback: attempting callback via local broadcast intent: org.altbeacon.beacon.range_notification
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: Not stopping scan because this is Android N and we keep scanning for a minimum of 6 seconds at a time. We will stop in 424 millisconds.
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: starting a new scan cycle
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: We are already scanning and have been for 904944386 millis
    2019-07-20 01:13:35.514 13181-13181/package D/CycledLeScanner: Waiting to stop scan cycle for another 1100 milliseconds
    2019-07-20 01:13:35.522 13181-13181/package D/CycledLeScanner: Set a wakeup alarm to go off in 300000 ms: PendingIntent{69e638a: android.os.BinderProxy@a809dfb}
    2019-07-20 01:13:35.522 13181-13181/package D/CycledLeScanner: Scan started
    2019-07-20 01:13:35.522 13181-13181/package D/IntentHandler: got ranging data
    2019-07-20 01:13:35.522 13181-13181/package I/Boikom: Thread: main
            ├ package.core.util.LoggingHelper.i(LoggingHelper.java:84)
            └ package.BoikomApplication.didRangeBeaconsInRegion(Application.java:133)
        [Beacon Service] didRangeBeaconsInRegion
    2019-07-20 01:13:35.523 13181-13181/package W/Boikom: Thread: main
            ├ package.core.util.LoggingHelper.w(LoggingHelper.java:217)
            └ package.core.service.BeaconServiceHandler.onEnterRegion(BeaconServiceHandler.java:89)
        [BeaconServiceHandler] The specified beacon has already show recently. Abort
    2019-07-20 01:19:25.142 13181-13181/package D/CycledLeScanner: Done with scan cycle
    2019-07-20 01:19:25.149 13181-13181/package D/ScanHelper: Calling ranging callback
    2019-07-20 01:19:25.155 13181-13181/package D/Callback: attempting callback via local broadcast intent: org.altbeacon.beacon.range_notification
    2019-07-20 01:19:25.159 13181-13181/package D/CycledLeScanner: stopping bluetooth le scan
    2019-07-20 01:19:25.159 13181-13181/package D/CycledLeScannerForLollipop: Stopping scan
    2019-07-20 01:19:25.162 13181-13181/package D/CycledLeScanner: starting a new scan cycle
    2019-07-20 01:19:25.162 13181-13333/package D/CycledLeScannerForLollipop: Stopping LE scan on scan handler
    2019-07-20 01:19:25.164 13181-13333/package D/BluetoothAdapter: isLeEnabled(): ON
    2019-07-20 01:19:25.164 13181-13181/package D/CycledLeScanner: starting a new bluetooth le scan
    2019-07-20 01:19:25.164 13181-13333/package D/BluetoothLeScanner: could not find callback wrapper
    2019-07-20 01:19:25.168 13181-13181/package D/CycledLeScanner: Waiting to stop scan cycle for another 1100 milliseconds
    2019-07-20 01:19:25.170 13181-13181/package D/CycledLeScanner: Set a wakeup alarm to go off in 300000 ms: PendingIntent{69e638a: android.os.BinderProxy@a809dfb}
    2019-07-20 01:19:25.171 13181-13181/package D/CycledLeScanner: Scan started
    2019-07-20 01:19:25.172 13181-13181/package D/StartupBroadcastReceiver: onReceive called in startup broadcast receiver
    2019-07-20 01:19:25.173 13181-13181/package D/StartupBroadcastReceiver: got wake up intent
    2019-07-20 01:19:25.175 13181-13181/package D/IntentHandler: got ranging data

person mspapant    schedule 19.07.2019    source источник
comment
Что регистрируется на системном уровне (не только при фильтрации для вашего приложения) в течение 5 минут, когда вы не получаете обратных вызовов? Какая это модель телефона и версия ОС?   -  person davidgyoung    schedule 20.07.2019
comment
Привет, @davidgyoung, слишком много журналов, чтобы добавить сюда. Телефон разработки - android 8.1, huwei p20. Кажется, что почему-то, когда приложение переходит в фоновый режим, сканирование также переходит в фоновый режим (создание запланированных заданий). Например, 2019-07-20 01: 23: 46.880 13181-13181 / package D / ScanJobScheduler: Scheduling ScanJob (job: 208352940 / package / org.altbeacon.beacon.service.ScanJob) для запуска каждые 300000 миллисекунд.   -  person mspapant    schedule 20.07.2019


Ответы (1)


Операционная система Huawei EMUI - это ответвление Android, которое содержит недокументированные изменения в стандартном поведении Android:

  • Приложения могут не использовать JobScheduler для работы в фоновом режиме на неопределенный срок, что приведет к прекращению работы стандартного механизма фонового сканирования Android 8+ библиотеки.
  • Сканирование Bluetooth иногда блокируется при выключенном экране с использованием секретного алгоритма, который Huawei не раскрывает.

Итог: фоновое сканирование маяков просто ненадежно на устройствах Huawei.

Команда разработчиков библиотеки попыталась самостоятельно реконструировать секретный алгоритм Huawei, но пока не нашла приемлемых решений. См. Здесь: https://github.com/AltBeacon/android-beacon-library/issues/554

В приведенной выше работе эта строка logcat на системном уровне, как известно, связана с блокирующим сканированием:

E/Bth: G.GattService:App 'my_package_name' is scanning too frequently on screen off

Вышеупомянутая работа была для EMUI 5.0-8.0, тогда как вопрос выше для P20 с EMUI 8.1. Поведение звучит немного иначе, чем описано в проблеме с библиотекой выше, поэтому алгоритм блокировки сканирования секретов мог быть изменен между EMUI 8 и 8.1. Приветствуется любая помощь в сборе журналов системного уровня, помогающая охарактеризовать это поведение и добавление их к описанной выше проблеме.

person davidgyoung    schedule 21.07.2019