¿Cómo reiniciar automáticamente un servicio incluso si la fuerza del usuario lo cierra?

Quiero que un servicio se ejecute todo el tiempo en mi aplicación. Así que quiero reiniciarlo incluso si el usuario cierra la fuerza. Definitivamente hay una manera de hacerlo, como lo hacen las aplicaciones como Facebook. (No se hace mediante notificaciones automáticas, Facebook reinicia su servicio incluso si Internet está apagado).

Cualquier ayuda sería apreciada. ¡Gracias!

En primer lugar, es realmente un patrón muy malo para ejecutar el servicio en contra de la voluntad del usuario .

De todos modos, puede reiniciarlo utilizando un BroadcastReceiver que maneja la transmisión enviada desde onDestroy() de su servicio.

StickyService.java

 public class StickyService extends Service { private static final String TAG = "StickyService"; @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand"); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); sendBroadcast(new Intent("YouWillNeverKillMe")); } } 

RestartServiceReceiver.java

 public class RestartServiceReceiver extends BroadcastReceiver { private static final String TAG = "RestartServiceReceiver"; @Override public void onReceive(Context context, Intent intent) { Log.e(TAG, "onReceive"); context.startService(new Intent(context.getApplicationContext(), StickyService.class)); } } 

Declare los componentes en el archivo de manifiesto :

          

Inicie el StickyService en un Componente (es decir, Application , Activity , Fragment ):

 startService(new Intent(this, StickyService.class)); 

O

 sendBroadcast(new Intent("YouWillNeverKillMe")); 

onTaskRemoved crear un sticky service onTaskRemoved con anulación en el método onTaskRemoved , donde puede configurar un servicio de alarma para activar su código nuevamente.

 public class BackgroundService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { return START_STICKY; } @Override public void onTaskRemoved(Intent rootIntent) { //create an intent that you want to start again. Intent intent = new Intent(getApplicationContext(), BackgroundService.class); PendingIntent pendingIntent = PendingIntent.getService(this, 1, intent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmManager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime() + 5000, pendingIntent); super.onTaskRemoved(rootIntent); } } 

También en algunos dispositivos como Xiaomi, Huwaei, la aplicación se cierra a la fuerza una vez que se elimina de las aplicaciones recientes. Esto se debe a que los fabricantes tienen funciones de administrador de tareas que mejoran el rendimiento de la batería / ram.

Puede consultar este enlace para obtener más información: https://stackoverflow.com/a/41360159/2798289

Cuando se mata un servicio, siempre se llama su método onDestroy . Es mejor usar un BroadcastReceiver para comenzar su servicio cuando se mata.

Aquí hay un código de muestra que ilustra su implementación:

 @Override public void onDestroy() { Intent in = new Intent(); in.setAction("StartkilledService"); sendBroadcast(in); Log.d("debug", "Service Killed"); } 

Luego registre un receptor en AndroidManifest.xml : –

       

Finalmente, cree un BroadcastReceiver e inicie su servicio en el método onReceive :

 @Override public void onReceive(Context context, Intent intent) { Log.d("debug", "ServeiceDestroy onReceive..."); Log.d("debug", "action:" + intent.getAction()); Log.d("debug", "Starting Service"); ServiceManager.startService(); } 

Espero que esto ayude.

en el método startCommand del servicio, devuelve START_STICKY. generalmente le dice al sistema operativo que inicie el servicio cuando es asesinado.

Según el documento de Android

 Starting from Android 3.1, the system's package manager keeps track of applications that are in a stopped state and provides a means of controlling their launch from background processes and other applications. Note that an application's stopped state is not the same as an Activity's stopped state. The system manages those two stopped states separately. FLAG_INCLUDE_STOPPED_PACKAGES — Include intent filters of stopped applications in the list of potential targets to resolve against. FLAG_EXCLUDE_STOPPED_PACKAGES — Exclude intent filters of stopped applications from the list of potential targets. When neither or both of these flags is defined in an intent, the default behavior is to include filters of stopped applications in the list of potential targets. Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all broadcast intents. It does this to prevent broadcasts from background services from inadvertently or unnecessarily launching components of stopped applications. A background service or application can override this behavior by adding the FLAG_INCLUDE_STOPPED_PACKAGES flag to broadcast intents that should be allowed to activate stopped applications. 

En Forzar detener la aplicación, Android simplemente mata la identificación del proceso. No se dan advertencias, se otorgan rellamadas a los servicios / actividades. Según el documento de Android, cuando se mata la aplicación hay posibilidades de que invoque aPausa ().

Cuando probé en mi aplicación, incluso onPause () no fue llamado. Creo que la única forma es usar FLAG_INCLUDE_STOPPED_PACKAGES indicador de intención y enviarlo desde otra aplicación

Si entiendo correctamente, entonces en realidad esto no es posible, la función de Android para forzar el cierre de la aplicación fue diseñada para permitir al usuario deshacerse de las aplicaciones no deseadas, por lo que no permite ninguna actividad hasta que el usuario vuelva a iniciar cualquiera de sus actividades.

Reinicia el servicio incluso si la aplicación se detiene por la fuerza y ​​sigue funcionando el servicio en segundo plano incluso después de cerrar la aplicación ¿Cómo?

Si la situación permite usar ‘raíz’, generalmente es posible implementar el paradigma Humpty-Dumpty.

Su aplicación (1st) instala otra aplicación (2nd, toma APK de los activos) y ejecuta el servicio de la segunda aplicación. El servicio de la segunda aplicación se une al primer servicio de la aplicación y se vuelve a unir cuando se desconecta. La primera aplicación hace lo mismo.

Claro que no ayudará cuando todas las aplicaciones sean destruidas por alguna RAM libre o aplicación similar, pero cuando Android mata a cualquiera de esas dos, la otra reiniciará su contraparte.

Existe una solución muy hacky para mantener el servicio en funcionamiento incluso si lo fuerza a detenerlo. No lo recomiendo porque va en contra de la voluntad del usuario. Puede definir un receptor de difusión para recibir el bash con la acción X. onStartCommand controlador de su servicio, transmitir X (si el servicio aún no se ha iniciado). en el receptor de emisión al recibir X, primero inicie el servicio, luego, duerma durante algunos minutos y finalmente vuelva a emitir X.

Creo que la única solución infalible aquí es tener 2 servicios en procesos separados ( android:process="somecustomprocessname" en manifest, en la entrada del servicio) que escuchan transmisiones y reinician entre sí, porque actualmente la UI no permite que los usuarios matar a múltiples procesos en una acción. Luego puede configurar un hilo de pinger en cada servicio que verifica si el otro servicio se está ejecutando cada 100 milisegundos, y si no, intenta reiniciarlo. Pero esto empieza a parecerse cada vez más al malware …

La única solución real para mantener vivos los servicios es llamar a Service.startForeground(...) con una Notificación provista. Esta será la única solución válida, todas las demás dependerán en gran medida de cómo Google cambiará el comportamiento de su sistema. Con cada actualización de API, Google podría evitar cualquier otro ataque.

Esto también mantiene al usuario al tanto de que su aplicación está realizando una tarea en segundo plano que mantendrá la aplicación viva y el usuario deberá detenerla. Sin embargo, si proporciona al usuario la posibilidad de detenerlo, es parte de su aplicación.

Ver la documentación:

 void startForeground (int id, Notification notification) 

Haga que este servicio se ejecute en primer plano y proporcione la notificación en curso para que se muestre al usuario mientras está en este estado. Por defecto, los servicios son de fondo, lo que significa que si el sistema necesita matarlos para reclamar más memoria (como para mostrar una página grande en un navegador web), se pueden eliminar sin causar demasiado daño. Puede establecer este indicador si matar su servicio podría ser perjudicial para el usuario, por ejemplo, si su servicio está ejecutando una reproducción de música de fondo, por lo que el usuario se daría cuenta si su música dejó de reproducirse.

    Intereting Posts