Android Altbeacon интервал, когда приложение в фоновом режиме - PullRequest
3 голосов
/ 14 марта 2019

Я работаю над приложением, которое запускает фоновую службу для интервалов между маяками bluetooth.

Я запускаю ForegroundService с таймером для запуска ранжирования маяков в течение 10 секунд каждую минуту с интервалом 200Миллис, вычисляет самый сильный маяк и передает его бэкэнд-API.

Это работает аккуратно, когда приложение находится на переднем плане, и, когда экран выключен, до тех пор, пока я подключен с помощью adb logcat.Как только я его снимаю, на серверы больше ничего не отправляется, а это означает, что маяки больше не ранжируются.

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

class BeaconService : Service(), BeaconConsumer {
    private var beaconManager: BeaconManager? = null
    private var rangingTimer = Timer("rangingTimer", true)
    private val region = Region("com.beacon.test", Identifier.parse("f7826da6-4fa2-4e98-8024-bc5b71e0893e"), null, null)

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return Service.START_STICKY
    }

    override fun onCreate() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val notificationManager = MyNotificationManager.getInstance()
            val notification = notificationManager.buildBeaconServiceNotification(this, "iBeacon service", null)
            startForeground(NOTIFICATION_ID, notification)
        }

        initBeaconManager()
    }

    private fun initBeaconManager() {
        BeaconManager.setDebug(true)
        beaconManager = BeaconManager.getInstanceForApplication(this)
        beaconManager?.foregroundScanPeriod = 200L
        beaconManager?.beaconParsers?.add(BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"))
        beaconManager?.bind(this)
    }

    override fun onBeaconServiceConnect() {
        beaconManager?.addRangeNotifier { beacons, _ ->
            if (beacons.isNotEmpty()) {
                //code add ranged beacons to list
            }
        }
        startRanging()
    }

    private fun startRanging() {

        //code to reset the list of ranged beacons

        beaconManager?.startRangingBeaconsInRegion(region)

        rangingTimer.schedule(10000L) {
            stopRanging(50000L)
        }

    }

    private fun stopRanging(restartRangingAfter: Long? = null) {
        beaconManager?.stopRangingBeaconsInRegion(region)

        //code calcuate the strongest beacon and submit to server

        if (restartRangingAfter != null) {
            rangingTimer.schedule(restartRangingAfter) {
                startRanging()
            }
        }
    }
}

1 Ответ

2 голосов
/ 14 марта 2019

В версиях ОС 8+ Android ограничивает фоновую обработку, если она не является частью службы переднего плана или заданием, инициированным JobScheduler.В результате этого ограничения библиотека маяков Android по умолчанию будет использовать JobScheduler на Android 8+.На переднем плане «немедленный» ScanJob будет постоянно выполняться для сканирования.В фоновом режиме (то есть, когда никакие действия не видны с разблокированным экраном), Android не позволяет этого.Работа может быть запланирована не чаще, чем раз в ~ 15 минут.Вот почему вы видите, что сканирование прекращается.

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

Два варианта:

  1. Работа с ограничениями задания (сканирование один раз каждые 15 минут).Используйте BackgroundPowerSaver для автоматического переключения между режимом переднего плана / фона и установите beaconManager.setBackgroundScanPeriod(5000) (для сканирования в течение 5 секунд каждые 15 минут). Для ясности также следует установить beaconManager.setBackgroundBetweenScanPeriod(15*60*1000) (15 минут), хотя можно установить более низкое значение, которое будетбыть запрещенным ОС на Android 8 +.

  2. Настройте библиотеку для сканирования с помощью собственной службы Foreground (да, как службы второго плана), как описано здесь .Затем вы можете прекратить использовать свой собственный сервис переднего плана или оставить его.Если вы сохраните его, вы увидите два значка уведомлений о двух запущенных службах переднего плана.Можно объединить эти два уведомления , если вы хотите сохранить две службы переднего плана и показать только одно уведомление.

...