В нашем приложении есть служба, которая обычно запускается во время Application.OnCreate
(прямой вызов context.startService
), а также позже через AlarmManager
(выполняется рефакторинг для переноса части своей работы в JobScheduler).
В нашем приложении также есть BroadcastReceiver
, который запускается с прямым намерением.
Учитывая новые ограничения в Android Oreo (https://developer.android.com/about/versions/oreo/android-8.0-changes.html) возникла следующая проблема:
- приложение/процесс находится в фоновом режиме/мертвый
- BroadcastReceiver запускается ОС
- Application.onCreate() выполняется перед BroadcastReceiver
- Код Application.onCreate() пытается запустить службу
это приводит к сбою с «IllegalStateException: не разрешено запускать намерение службы».
Мне известны новые рекомендуемые способы запуска Службы, на которые ответил CommonsWare здесь https://stackoverflow.com/a/44505719/906362, но для этого конкретного случая я просто хочу иметь if(process in foreground) { startService }
. В настоящее время я использую следующий метод, и он, кажется, работает:
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static boolean isProcessInForeground_V21(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.AppTask> tasks = am.getAppTasks();
return tasks.size() > 0;
}
Но я не могу найти точные проверки, которые выполняет Android Oreo (я добрался до здесь https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/ContextImpl.java на startServiceCommon
, но оттуда флаг requireForeground
похоже уходит в какую-то нативную реализацию)
Итак, мой вопрос:
Для конкретной цели новых ограничений Android Oreo, как проверить, находится ли мой процесс на переднем плане перед вызовом startService
?
onCreate()
пользовательскогоApplication
. Запускайте службу только тогда, когда она необходима. Если ваше приложение находится на переднем плане, сервис бесполезен. - person CommonsWare   schedule 28.08.2017