Сон и пробуждение переднего плана ограничены IntentService каждые 10 секунд также на Oreo - PullRequest
0 голосов
/ 11 июня 2018

Наше приложение может подключаться к устройству HVAC, и ему необходимо каждые 10 секунд выполнять выборку его состояния.

Устройство HVAC предоставляет интерфейс Modbus и выборки буфера CANNOT.Нам на самом деле нужно пробуждать сервис каждые 10 секунд.Типичная пробная сессия длится от 1 часа до нескольких часов.(Существуют различные типы подключения / кабели / мосты: USB-конвертер OTG + RS232, TCP через мост RS232 / TCP, Bluetooth classic и мосты BLE через RS232 / BT или BLE.)

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

До Nougat 7.0 наше рабочее решение было:

  • Запустите IntenService, затем установите для него Foreground Сервис
  • Связанный с этим сервисом, так что это также сервис Bounded (чтобы остановить его, распространите взаимодействие с устройством HVAC отGUI и т. Д.)
  • Получение PowerManager.PARTIAL_WAKE_LOCK
  • Использование Thread.Sleep() для цикла 10 секунд, а также для управления тайм-аутами в реализации транспорта различных соединений

Должен ли я разместить код?Соответствующие детали являются наиболее распространенными шаблонами.

Несмотря на отсутствие документированных гарантий, Thread.Sleep() с PowerManager.PARTIAL_WAKE_LOCK в Foreground Service работал отлично, пока Nougat 7.0

На нашем тестируемом устройстве Oreo, оба компилируя API 26 и 23 для таргетинга (как наша предыдущая выпущенная версия), при этом не взаимодействуя с действиями приложения (отключение отображения, другие приложения на переднем плане и т. Д.), Сервис не активируется, он спитдо первого взаимодействия с приложением.

Чтобы иметь возможность запускать службу переднего плана на API нацеливания Oreo 26, я реализовал решение Бикрама Пандита из Android O - Старый запуск службы переднего плана все еще работает? ,Ничего не изменилось.

Я запросил исключение Battery Optimizations с ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (как описано в https://developer.android.com/training/monitoring-device-state/doze-standby#whitelisting-cases) и предоставил его.Ничего не изменилось.(И приложение работало без него до Nougat 7.0)

В документации о предельных значениях фонового выполнения Oreo, https://developer.android.com/about/versions/oreo/background, говорится, что ограниченные службы или службы Foreground не должны подвергаться этим ограничениям.И все же сервис не просыпается.

AlarmManager не может быть использован, поскольку из Oreo он может срабатывать максимум каждые 9 минут, даже с setAndAllowWhileIdle() или setExactAndAllowWhileIdle().(Опять же в https://developer.android.com/training/monitoring-device-state/doze-standby#whitelisting-cases)

Я также попытался использовать wait(sleepTime) вместо Thread.sleep(): еще хуже, он даже не просыпается при возобновлении взаимодействия.

Я остановилсяперед повторной реализацией как JobIntentService или с использованием JobScheduler / JobService, чтобы переосмыслить каждый образец как задание, но:

  • ВАЖНО: мне все равно понадобится Thread.Sleep() внекоторые реализации соединений транспортного уровня, это проснется во время работы?
  • Будет ли JobScheduler фактически позволять запускать задания каждые 10 секунд, или это будет связывать их вместе в Oreo? Нам на самом деле нужен пример каждый10 секунд. Вероятно, мы могли бы расслабиться до 1 минуты, но не больше.
  • Могу ли я сохранить очень сложное состояние (мой объект ModbusDevice) в JobService, чтобы разделить его между всеми этими заданиями, иначе будут ограничения?

Опять же, я должен опубликовать какой-нибудь код? Это самый распространенный шаблон.

...