Как использовать диспетчер работы для решения проблемы с выходом из региона после того, как приложение было убито пользователем? - PullRequest
0 голосов
/ 19 апреля 2019

У меня проблема с библиотекой altbeacon . Я готовлю небольшую библиотеку, в которой один модуль сканирует маяки в фоновом режиме и на переднем плане. Я нашел пример приложения в одной библиотеке на Github и проверил их код (класс приложения), и все в порядке. После того, как пользователь переходит к переключателю задач и смахивает приложение с экрана, сканирование продолжается в фоновом режиме.

Но я создаю библиотеку, поэтому не могу вставить свой код в класс Application. После этого мне нужно сделать что-то вроде этого: MyLibrary.init (this) внутри метода onCreate в ApplicationClass. Поэтому я написал класс BeaconService с точно таким же кодом, как в классе приложения. Я перешел к этому контексту приложения класса (я проверил, что у меня внутри контекста приложения BeaconService, отладив мой код). После этого, когда приложение не убивается выключением из переключателя задач, все работает отлично. После закрытия приложения я получил выход из региона и не могу продолжить сканирование, даже если маяк находится на расстоянии около 20 см от устройства.

Я создал проблему на altbeacon Github (вы можете найти мой пример кода и журналы здесь ), и я получил ответ, что библиотека не предназначена для моих требований. Более того, если у меня есть дополнительные вопросы, как решить мою проблему, я должен спросить об этом в stackoverflow.

Итак, у меня есть идея, что, возможно, я смогу использовать WorkManager и повторно планировать рабочий маяк сканирования (OneTimeWork) снова и снова. Это может быть способ обойти ограничения задержки планирования фоновых задач, которые введены в Android 8+.

Пример кода ниже:

class BeaconWorker(appCtx: Context, workerParameters: WorkerParameters) : CoroutineWorker(appCtx, workerParameters) {

override val coroutineContext: CoroutineDispatcher
    get() = Dispatchers.Default

override suspend fun doWork() = supervisorScope {
    // rescheduling worker
    if(isActive) {
        enqueNextWork()
    }
    // make scan (This could be only one scan with list of found beacons)
    val beacons = makeScan()
    Result.success()
  }
}

Как этого добиться с помощью библиотеки altbeacon?

1 Ответ

0 голосов
/ 19 апреля 2019

Я думаю, вы делаете это слишком сложно.

Библиотека маяков Android предназначена для сканирования маяков в фоновом режиме и автоматического перезапуска после того, как приложение убито, для сканирования маяков. Он делает все это автоматически из коробки без необходимости создавать какие-либо службы упаковки или менеджеры работ. Такие обертки, вероятно, усложняют ситуацию и вызывают неожиданные побочные эффекты.

Вышеприведенное также работает, если вы создаете свою собственную библиотеку, которая оборачивает библиотеку маяков Android, при условии, что записи библиотеки AndroidManifest.xml объединены в файл AndroidManifest.xml вашей библиотеки. Это откроет ряд внутренних служб библиотеки Android Beacon в манифесте, включая StartupBroadcastReceiver, BeaconService и ScanJob. Эти три службы необходимы для выполнения функций, указанных в первом абзаце.

Если вы сделали вышеупомянутое, единственное, что вам нужно сделать, - это предоставить некоторый кодовый хук для настройки мониторинга / измерения радиомаяка при запуске приложения. Это может быть просто вызов метода POJO внутри вашей библиотеки, например new MyLibraryManager().start(Context context); (вам, вероятно, придется передать объект Context, поскольку это необходимо для создания BeaconManager библиотеки маяков Android.)

Для автоматического перезапуска сканирования после прекращения работы приложения вышеупомянутый хук должен каким-то образом выполняться при запуске приложения. (Автоматический перезапуск библиотеки - это службы, описанные выше, но вам все равно нужно сделать вызовы, чтобы сообщить библиотеке, начинать ли сканирование и с какими настройками.)

Самое простое решение - поручить разработчикам, использующим вашу библиотеку, поместить вызов описанной выше ловушки (например, new MyLibraryManager().start(Context context);) в их собственный пользовательский метод Application#onCreate(). Возможно, вам удастся найти другое умное решение с BroadcastReceiver, которое не требует этого.

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