Continuer le service même si l’application est effacée de l’application récente

J’ai un petit problème.

Dans mon application, un service est démarré après que l’utilisateur est connecté avec succès. Auparavant, le service devait s’arrêter si l’application était supprimée. (par exemple, enlevé de la liste des applications récentes en glissant.) Nous avons donc utilisé android:stopWithTask="true" . Maintenant, le service doit être exécuté tel quel, même si la tâche qui l’a lancé est supprimée de la liste des applications récentes. J’ai donc changé le service pour inclure android:stopWithTask="false" . Mais cela ne semble pas fonctionner.

Code associé:

Voici une partie manifeste liée au service:

  

Dans 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 est une classe personnalisée qui étend Sevrice :

 public abstract class AbstractService extends Service { protected final Ssortingng 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); } } 

Maintenant, si je me connecte à l’application, MyService est démarré. Après cela, j’appuie sur le bouton Home pour que l’application soit déplacée en arrière-plan. Maintenant, je supprime l’application de la liste Application récente. À ce moment-là, je devrais voir le message Toast et la console, conformément à la description de cette méthode:

public void onTaskRemoved (Intention rootIntent)

Ajouté au niveau de l’API 14

Ceci est appelé si le service est en cours d’exécution et que l’utilisateur a supprimé une tâche provenant de l’application du service. Si vous avez défini ServiceInfo.FLAG_STOP_WITH_TASK, vous ne recevrez pas ce rappel; au lieu de cela, le service sera simplement arrêté.

Paramètres rootIntent Intent racine d’origine utilisé pour lancer la tâche en cours de suppression.

Mais je ne vois rien de cela. Le service retourne START_STICKY dans onStartCommand , donc je pense que onTaskRemoved doit être déclenché avec un drapeau android:stopWithTask="false" .

Est-ce que je manque quelque chose?

Faites-moi savoir au cas où je dois append un code qui pourrait être important pour comprendre ce qui ne va pas.

PS: j’ai testé cela sur 4.2.2 jusqu’à maintenant.

PS: Je viens de tester le même code dans 4.1.2, sur lequel Service continue à tourner, et j’obtiens également le message “onTaskRemoved called” dans le journal.

Que dois-je faire pour que cela fonctionne dans toutes les versions?

Suivez simplement ces scénarios, votre service et vos processus (les threads s’exécutent dans votre service) restront continus.

  1. Créer un service et utiliser START_STICKY comme valeur de retour dans la méthode onStartCommand comme ci-dessous

      @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { //your code return START_STICKY; } 
  2. Le code ci-dessus redémarre le service s’il est détruit et rest toujours en cours d’exécution, mais le processus (threads) exécuté à partir du service cessera de fonctionner si votre application est supprimée des applications récentes. Pour vous assurer que vos processus (Threads) restnt toujours en cours d’exécution, vous devez remplacer la méthode onTaskRemoved () et append du code pour redémarrer les tâches comme ci-dessous.

     @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); } 
  3. Démarrer le service comme ci-dessous

startService (nouvelle intention (this, YourService.class));

Dans votre service, ajoutez le code suivant. Cela fonctionne bien pour moi en 4.4.2

Voici une solution de contournement que j’ai trouvée et qui fonctionne bien pour redémarrer un service si son processus est interrompu à la fermeture de l’application.

  @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 vous vous connectez à votre service à partir d’une sous-classe de la classe Application et que vous restz connecté à votre connexion IBinder, le service rest actif même après la suppression de l’application des applications récentes.

Il semble que passer une application des «tâches récentes» tue tout ce qui est attaché.

Peut-être devriez-vous y jeter un coup d’œil pour trouver un moyen de relancer votre service s’il s’arrête: https://stackoverflow.com/a/22464640/4232337

Écrivez les 5 lignes que j’ai ajoutées dans oncreate() de la classe de service

Comme ça:

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

ou

essaye celui-là

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