una studio servicios segundo reiniciar plano destruir aplicaciones activity actividades activar android android-service android-9.0-pie

studio - Android 9.0: No se permite iniciar el servicio: la aplicación está en segundo plano... después de onResume()



reiniciar una activity (6)

Tengo un reproductor de música que intenta iniciar un Service en onResume() de una Activity . He eliminado algunas líneas para mayor claridad, pero el código es efectivamente:

@Override protected void onResume() { super.onResume(); startService(new Intent(this, MusicService.class)); }

De acuerdo con los registros de fallos, esto está lanzando una excepción en algunos dispositivos que ejecutan 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)

¿Cómo es posible que mi aplicación esté en segundo plano, inmediatamente después de onResume() (y super.onResume() )?

Esto no tiene ningún sentido para mí. ¿Podría ser esto un error de plataforma? Todos los más de 3500 usuarios afectados por este bloqueo están en Android P.


¿Tal vez android.arch.lifecycle podría usarse como una solución para este error de 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); } }

Lo he encontrado aquí.


ACTUALIZACIÓN: Esto está funcionando para nosotros en Prod, pero no es 100%. Recibí un informe de colisión en el último mes y medio, de lo contrario habría sido más de cien. Hasta que esto se arregle adecuadamente, esta parece ser nuestra mejor opción por ahora. Tal vez si aumentara el tiempo más allá de los 300, ¿ese choque nunca hubiera ocurrido?

Estamos probando esto ahora mismo, que hasta ahora parece estar funcionando. Se actualizará a medida que veamos más resultados.

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) } }

En onCreate() y luego, en cualquier momento que desee iniciar un servicio en onResume, simplemente llame a resumingServiceManager.startService resumingServiceManager.startService(this, intent)

Es consciente del ciclo de vida, por lo que eliminará el desechable si hace una pausa en la cancelación de la activación de onSuccess cuando podría estar en el camino hacia el fondo con una apertura / cierre inmediato.



Esto se ha marcado como ''arreglado'' en el Rastreador de problemas de Android:

Presumiblemente, la solución se publicará en uno de los lanzamientos de Android Q.

Según el Googler que cerró el tema,

Hay una solución para evitar la caída de la aplicación. Las aplicaciones pueden obtener el estado del proceso en Activity.onResume() llamando a ActivityManager.getRunningAppProcesses() y evitan iniciar el servicio si el nivel de importancia es menor que ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND . Si el dispositivo no está completamente despierto, las actividades se detendrían de inmediato y, finalmente, se reanudarán después de que esté completamente despierto.


Hay una solución de Google:

El problema ha sido abordado en el futuro lanzamiento de Android.

Hay una solución para evitar la caída de la aplicación. Las aplicaciones pueden obtener el estado del proceso en Activity.onResume () llamando a ActivityManager.getRunningAppProcesses () y evitan iniciar el servicio si el nivel de importancia es menor que ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND. Si el dispositivo no está completamente despierto, las actividades se detendrían de inmediato y, finalmente, se reanudarán después de que esté completamente despierto.

Así que creo que debería gustar eso:

// 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); }

He utilizado el manejador como solución alternativa y funciona bastante bien, pero no al 100%:

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


Nuestro equipo se enfrentó con el mismo problema. Mi calendario muestra el 5 de abril de 2019, pero el problema aún se reproduce en mi Samsung Galaxy S9 +, Android 9.0 (una interfaz de usuario)

Iniciamos el servicio en onResume y desenlazamos onPause.

Como reproducirse

Simplemente bloquee su dispositivo, cuando la actividad con esta lógica está en la pantalla, y no la toque entre 10 y 15 minutos. Después de desbloquear la pantalla, la aplicación se bloqueará.

Como arreglar

Encontramos una solución que realmente funciona. Desde Android 8+, inicie su servicio en android.os.Handler.post (...)

Ejemplo (Kotlin):

override fun onResume() { super.onResume() Handler().post { val serviceIntent = Intent(activity, SomeService::class.java) activity?.startService(serviceIntent) activity?.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE) } }

¡Buena suerte!