Continuar el servicio incluso si la aplicación se ha eliminado de la aplicación Reciente.
Estoy teniendo un pequeño problema.
En mi aplicación, un servicio se inicia después de que el usuario ha iniciado sesión correctamente. Anteriormente, el servicio necesitaba detenerse si se mataba la aplicación. (Por ejemplo, eliminado de la lista de aplicaciones recientes por deslizamiento.) Así que habíamos utilizado android:stopWithTask="true"
. Ahora necesitamos que el Servicio se ejecute tal como está, incluso si la tarea que lo inició se elimina de la lista de aplicaciones recientes. Así que cambié el servicio para incluir android:stopWithTask="false"
. Pero eso no parece funcionar.
- Android onCreate o onStartCommand para iniciar el servicio
- ¿La actualización de una notificación elimina el estado de primer plano de un servicio?
- Android: escucha los mensajes SMS entrantes
- AVD no se está ejecutando
- Problema con android: protectionLevel = "firma"
Código relacionado:
Aquí está la parte manifiesta relacionada con el Servicio:
<service android:enabled="true" android:name=".MyService" android:exported="false" android:stopWithTask="false" />
En MyService.java:
public class MyService extends AbstractService { @Override public void onStartService() { Intent intent = new Intent(this, MyActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); Notification notification = new Notification(R.drawable.ic_launcher, "My network services", System.currentTimeMillis()); notification.setLatestEventInfo(this, "AppName", "Message", pendingIntent); startForeground(MY_NOTIFICATION_ID, notification); } @Override public void onTaskRemoved(Intent rootIntent) { Toast.makeText(getApplicationContext(), "onTaskRemoved called", Toast.LENGTH_LONG).show(); System.out.println("onTaskRemoved called"); super.onTaskRemoved(rootIntent); } }
AbstractService.java es una clase personalizada que extiende Sevrice
:
public abstract class AbstractService extends Service { protected final String TAG = this.getClass().getName(); @Override public void onCreate() { super.onCreate(); onStartService(); Log.i(TAG, "onCreate(): Service Started."); } @Override public final int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStarCommand(): Received id " + startId + ": " + intent); return START_STICKY; // run until explicitly stopped. } @Override public final IBinder onBind(Intent intent) { return m_messenger.getBinder(); } @Override public void onDestroy() { super.onDestroy(); onStopService(); Log.i(TAG, "Service Stopped."); } public abstract void onStartService(); public abstract void onStopService(); public abstract void onReceiveMessage(Message msg); @Override public void onTaskRemoved(Intent rootIntent) { Toast.makeText(getApplicationContext(), "AS onTaskRemoved called", Toast.LENGTH_LONG).show(); super.onTaskRemoved(rootIntent); } }
Ahora, si inicio una sesión en la aplicación, MyService se inicia. Después de que presione el botón de inicio, por lo que la aplicación se mueve a fondo. Ahora elimino la aplicación de la lista de aplicaciones recientes. En ese momento, debería ver el mensaje Toast y consola, según la descripción de este método:
Public void onTaskRemoved (Intención rootIntent)
Añadido en el API nivel 14
Esto se llama si el servicio se está ejecutando actualmente y el usuario ha eliminado una tarea que proviene de la aplicación del servicio. Si ha configurado ServiceInfo.FLAG_STOP_WITH_TASK, no recibirá esta devolución de llamada; En su lugar, el servicio simplemente se detendrá.
Parámetros rootIntent La raíz original Intent que se utilizó para iniciar la tarea que se está eliminando.
Pero no estoy viendo nada de eso. El servicio está devolviendo START_STICKY en onStartCommand
, así que creo que onTaskRemoved
debe ser disparado junto con flag android:stopWithTask="false"
.
¿Estoy perdiendo algo?
Déjeme saber en caso de que necesite añadir algún código que podría ser importante para averiguar lo que está mal.
PS: He probado esto en 4.2.2 hasta ahora.
PS: Acabo de probar el mismo código en 4.1.2, en el que Servicio sigue funcionando, y recibo el mensaje "onTaskRemoved llamado" en el registro, también.
¿Qué debo hacer para que esto funcione en todas las versiones?
- ¿Cómo ejecutar el servicio no en el hilo principal?
- Android Service está creando una y otra vez
- Servicio de detector de balizas de estimación en segundo plano
- ¿Se puede utilizar un LoaderManager de un servicio?
- Firebase + Android - Notificaciones ChildAdded - ¿Cómo obtener sólo New Childs?
- ¿Cuál es el número máximo de servicios limitados por el sistema operativo Android?
- Cree sólo una instancia de Service (Android)
- Android ResultReceiver a través de paquetes
Simplemente siga estos escenarios, sus servicios y procesos (los Temas se ejecutan dentro de su servicio) se mantendrán continuos.
-
Cree servicio y use START_STICKY como valor devuelto en el método onStartCommand como a continuación
@Override public int onStartCommand(final Intent intent, final int flags, final int startId) { //your code return START_STICKY; }
-
El código anterior reiniciará el servicio si se destruye y permanece siempre en ejecución, pero el proceso (Threads) que se ejecuta desde el servicio dejará de funcionar si su aplicación se elimina de las aplicaciones recientes. Para asegurarse de que sus procesos (hilos) permanezcan siempre en condiciones que funcionan usted tiene que sobrescribir el método onTaskRemoved () y agregar el código para reiniciar Tareas como abajo.
@Override public void onTaskRemoved(Intent rootIntent){ Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass()); restartServiceTask.setPackage(getPackageName()); PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT); AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); myAlarmService.set( AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartPendingIntent); super.onTaskRemoved(rootIntent); }
- Inicie el servicio como a continuación
StartService (nuevo Intent (esto, YourService.class));
En su servicio, agregue el código siguiente. Me funciona bien en 4.4.2
Aquí hay una solución que encontré y funciona bien para reiniciar un servicio si su proceso se destruye al cerrar la aplicación.
@Override public void onTaskRemoved(Intent rootIntent){ Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass()); PendingIntent restartServicePendingIntent = PendingIntent.getService( getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmService = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmService.set(ELAPSED_REALTIME, elapsedRealtime() + 1000, restartServicePendingIntent); super.onTaskRemoved(rootIntent); }
Si vincula a su servicio desde una subclase de clase de aplicación y se aferra a su conexión de IBinder, el servicio permanecerá activo incluso después de que la aplicación se haya eliminado de las aplicaciones recientes.
Parece que eliminar una aplicación de las 'tareas recientes' mata todo lo relacionado.
Tal vez deberías echar un vistazo allí para encontrar una manera de relanzar tu servicio si se detiene: https://stackoverflow.com/a/22464640/4232337
Escriba las 5 líneas que agregué en oncreate()
de la clase de servicio
Me gusta esto:
public class AlarmService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Intent iHeartBeatService = new Intent(AlarmService.this, AlarmService.class); PendingIntent piHeartBeatService = PendingIntent.getService(this, 0, iHeartBeatService, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmManager.cancel(piHeartBeatService); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, piHeartBeatService); } }
o
Prueba este
public class MyService extends Service{ @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); System.out.println("service created"); } @SuppressLint("NewApi") @Override public void onTaskRemoved(Intent rootIntent) { // TODO Auto-generated method stub System.out.println("onTaskRemoved"); super.onTaskRemoved(rootIntent); } @Override @Deprecated public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); System.out.println("Service started"); new Handler().postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("Service is running"); } }, 5000); } }
- La intención de vinculación profunda no funciona
- ¿Cómo ver la identidad de la persona que firmó el apk en el dispositivo Android?