В соответствии с бизнес-требованиями я должен постоянно поддерживать фоновую службу в своем приложении для Android.

Я решил задать этот вопрос после почти трехнедельного исследования.

Требование таково, что у моего приложения есть только одна фоновая служба, и оно должно все время искать устройства BLE. (Не волнуйтесь, я установил режим медленного сканирования, когда в диапазоне нет устройств BLE, в котором я приостанавливаю и возобновляю сканирование). Приложение предназначено не для всех, поскольку оно предназначено для аутентификации устройств BLE всякий раз, когда они находятся в пределах досягаемости. Надеюсь, это устанавливает ВАЖНОСТЬ службы, работающей все время. Я не могу использовать службу переднего плана (бизнес-требование).

Всякий раз, когда андроид убивает мою службу, onDestroy() не вызывается. Поэтому лучше всего использовать диспетчер тревог, который срабатывает каждые 5 минут и проверяет, убита ли служба, и если она убита, она вызывает startService(). Будильник какое-то время срабатывает нормально, но через случайные промежутки времени (1, 2, 3 часа) даже будильник отключается и больше не срабатывает.

Отправляю трансляцию через аларм чей onReceive() отвечает за запуск сервиса если его убили. У меня нет обходных путей, может ли кто-нибудь объяснить или предложить, почему диспетчер аварийных сигналов дает сбой через некоторое случайное время. В настоящее время я тестирую свое приложение на nexus 6p, Galaxy s7 edge, Samsung A5, Huawei P9.

Любое дополнительное объяснение может быть предоставлено.


person madking    schedule 21.12.2016    source источник


Ответы (1)


Будильник какое-то время срабатывает нормально, но через случайные промежутки времени (1, 2, 3 часа) даже будильник отключается и больше не срабатывает.

Если adb shell dumpsys alarm не показывает ваш будильник, вы можете сказать, что "будильник отключается". Обычно этого не происходит, если пользователь не использует принудительную остановку в настройках.

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

  • Попробуйте setAndAllowWhileIdle(), который может отправляться не так часто, как хотелось бы, или

  • Попросите пользователя добавить ваше приложение в белый список оптимизации батареи, учитывая, что пользователи могут не делать этого или

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

Я отправляю широковещательную рассылку через будильник, чей onReceive() отвечает за запуск службы, если она убита

Если вы не используете WakeLock (осторожно), есть вероятность, что устройство снова заснет до того, как ваша служба действительно запустится.

person CommonsWare    schedule 21.12.2016
comment
Спасибо за ответ. Я проверю завтра с помощью adb, действительно ли будильник перестает существовать. Как можно использовать setAndAllowWhileIdle() и заставить будильник повторяться каждые 5 минут? А что касается «WakeLock», я получаю его в onReceive() моего широковещательного приемника и после вызова startService() отключаю его. Разве не так должно быть? - person madking; 21.12.2016
comment
@madking: Как можно использовать setAndAllowWhileIdle() и заставить будильник повторяться каждые 5 минут? -- Вы не можете. Я думаю, что рекламируемый минимальный период составляет 9 минут, и это может быть даже не так часто. Разве не так должно быть? -- это означает, что ваш WakeLock получен примерно за микросекунду. startService() асинхронный; служба не запускается, когда startService() возвращается. Я ожидаю, что вашему сервису в любом случае понадобится WakeLock для выполнения своей работы, поэтому пользователи могут быть недовольны вашим приложением. - person CommonsWare; 21.12.2016
comment
Кроме того, я использую RTC_WAKEUP, и у меня есть уведомление, выдаваемое в onReceive(), поэтому независимо от того, запущена ли служба или нет, или телефон находится в режиме DOZE (представлен в Android 6), уведомление должно отображаться всякий раз, когда срабатывает будильник, когда он просыпается. ЦП на очень короткий момент. Но уведомления перестают приходить через какое-то время. - person madking; 21.12.2016
comment
Меня устраивает 9 минут, но разве setAndAllowWhileIdle() не срабатывает только один раз? Тогда, может быть, мне следует снять блокировку внутри службы? Я уже получаю wakelock внутри службы в широковещательном приемнике, который транслируется всякий раз, когда изменяется состояние экрана. Дело в том, что пользователь хочет, чтобы я запускал сервис все время, так как это приложение для бизнес-клиента. - person madking; 21.12.2016
comment
@madking: но setAndAllowWhileIdle() не срабатывает только один раз? -- часть вашей работы при срабатывании будильника состоит в том, чтобы запланировать следующий будильник. Тогда, может быть, мне следует снять блокировку внутри службы? -- да, приобретите в BroadcastReceiver, но отпустите в Service. Вот как работает WakefulBroadcastReceiver. Дело в том, что пользователь хочет, чтобы я запускал службу все время, поскольку это приложение для бизнес-клиента — пользователь может передумать, когда узнает, сколько батареи использует ваше приложение. - person CommonsWare; 21.12.2016
comment
лол, это не так уж плохо, я оптимизировал процесс сканирования, и приложение не расходует безумное количество батареи. И последнее, пожалуйста, где мне снять блокировку, так как я также получаю блокировку внутри службы (когда экран поворачивается off получите блокировку, когда экран включится, снимите блокировку), и нет гарантии, что onDestroy() будет вызван, когда android убьет мою службу. PS Я тоже возвращаю STICKY в onStartCommand() и использую android:persistent в теге <application> моего приложения. - person madking; 21.12.2016
comment
@madking: где мне снять блокировку - когда она тебе больше не нужна. Я предполагаю, что он нужен вам для сканирования BLE, поэтому, возможно, вы отпустите его, когда сканирование завершится. - person CommonsWare; 21.12.2016
comment
@CommonsWare, где другая проблема для устройств Huawei: любой процесс принудительно уничтожается ОС. stackoverflow.com/a/41622804/1979882 . - person Vyacheslav; 13.01.2017