android - restablecer - si reseteo mi celular se borra el whatsapp
¿Cómo reiniciar automáticamente un servicio incluso si la fuerza del usuario lo cierra? (10)
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 ...
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!
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
: -
<receiver android:name=".app.ServiceDestroyReceiver" >
<intent-filter>
<action android:name="StartKilledService" >
</action>
</intent-filter>
</receiver>
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 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 :
<service android:name=".StickyService" >
</service>
<receiver android:name=".RestartServiceReceiver" >
<intent-filter>
<action android:name="YouWillNeverKillMe" >
</action>
</intent-filter>
</receiver>
Inicie el StickyService
en un Componente (es decir, Application
, Activity
, Fragment
):
startService(new Intent(this, StickyService.class));
O
sendBroadcast(new Intent("YouWillNeverKillMe"));
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 intento 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.
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.
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.
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.
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.
en el método startCommand del servicio, devuelve START_STICKY. generalmente le dice al sistema operativo que inicie el servicio cuando es asesinado.
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://.com/a/41360159/2798289