android - сделать - обнаружено фоновое использование разрешений whatsapp



Android 9.0: Запрещено запускать службу: приложение находится в фоновом режиме.. после onResume() (4)

Может быть, android.arch.lifecycle можно использовать в качестве обходного пути для этой ошибки Android 9?

public class MyActivity extends Activity implements LifecycleObserver {

    protected void onResume() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (ProcessLifecycleOwner.get().getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) {
                startService(intent);
            } else {
                ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
            }
        } else {
            startService(intent);
        }
    }


    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onEnterForeground() {
        startService(intent);
        ProcessLifecycleOwner.get().getLifecycle().removeObserver(this);
    }
}

Я нашел это здесь.

https://ffff65535.com

У меня есть музыкальный проигрыватель, который пытается запустить Service в onResume() Activity . Я удалил несколько строк для ясности, но код эффективен:

@Override
protected void onResume() {
    super.onResume();

    startService(new Intent(this, MusicService.class));
}

Согласно журналам сбоев, это исключение на некоторых устройствах под управлением Android P:

Caused by java.lang.IllegalStateException: Not allowed to start service Intent { cmp=another.music.player/com.simplecity.amp_library.playback.MusicService }: app is in background uid UidRecord{6a4a9c6 u0a143 TPSL bg:+3m25s199ms idle change:cached procs:1 seq(1283,1283,1283)}
       at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1577)
       at android.app.ContextImpl.startService(ContextImpl.java:1532)
       at android.content.ContextWrapper.startService(ContextWrapper.java:664)
       at android.content.ContextWrapper.startService(ContextWrapper.java:664)
       at com.simplecity.amp_library.utils.MusicServiceConnectionUtils.bindToService(SourceFile:36)
       at com.simplecity.amp_library.ui.activities.BaseActivity.bindService(SourceFile:129)
       at com.simplecity.amp_library.ui.activities.BaseActivity.onResume(SourceFile:96)

Как это возможно, что мое приложение находится в фоновом режиме, сразу после onResume()super.onResume() )?

Это не имеет никакого смысла для меня. Может ли это быть ошибкой платформы? Все 3500+ пользователей, пострадавших от этого сбоя, на Android P.


ОБНОВЛЕНИЕ: Это работает для нас в Prod, но это не 100%. Я получил один отчет о сбое за последние полтора месяца, в противном случае было бы более сотни. Пока это не исправлено, это кажется нашим лучшим вариантом на данный момент. Может быть, если бы я поднял время за 300, то одного сбоя бы никогда не произошло?

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

class ResumingServiceManager(val lifecycle: Lifecycle) : LifecycleObserver {

    init {
        lifecycle.addObserver(this)
    }

    val disposable: CompositeDisposable = CompositeDisposable()

    fun startService(context: Context, intent: Intent) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            context.startService(intent)
        } else {
            Single.just(true)
                    .delaySubscription(300, TimeUnit.MILLISECONDS)
                    .subscribeOn(AndroidSchedulers.mainThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeBy(
                            onSuccess = {
                                context.startService(intent)
                            }

                    ).addTo(disposable)
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stopped() {
        disposable.clear()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun destroy() {
        lifecycle.removeObserver(this)
    }
}

В onCreate() инициализируйте его, а затем в любое время, когда вы захотите запустить службу в onResume, просто вызовите resumingServiceManager.startService resumingServiceManager.startService(this, intent)

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


Существует обходной путь от Google:

Проблема была решена в будущем выпуске Android.

Существует обходной путь, чтобы избежать сбоя приложения. Приложения могут получить состояние процесса в Activity.onResume (), вызвав ActivityManager.getRunningAppProcesses () и избежать запуска Service, если уровень важности ниже, чем ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND. Если устройство не полностью проснулось, действия будут немедленно приостановлены и, в конце концов, возобновлены после его полного пробуждения.

Поэтому я думаю, что так должно быть:

// hack for https://issuetracker.google.com/issues/113122354
    List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
    if (runningAppProcesses != null) {
        int importance = runningAppProcesses.get(0).importance;
        // higher importance has lower number (?)
        if (importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND)
            URLPlayerService.startActionBroadcastServiceData(PlayerActivity.this);
    }

Я использовал обработчик как обходной путь, и он работает довольно хорошо, но не на 100%:

// hack for https://issuetracker.google.com/issues/113122354
   handler.postDelayed(() -> URLPlayerService.startService(PlayerActivity.this),200);

Это было помечено как «исправлено» в трекере проблем Android:

Предположительно исправление будет выпущено в одном из выпусков Android Q.

По словам Гуглера, который закрыл вопрос,

Существует обходной путь, чтобы избежать сбоя приложения. Приложения могут получить состояние процесса в Activity.onResume() , вызвав ActivityManager.getRunningAppProcesses() и избежать запуска Service, если уровень важности ниже, чем ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND . Если устройство не полностью проснулось, действия будут немедленно приостановлены и, в конце концов, возобновлены после его полного пробуждения.





android-9.0-pie