J'essaie d'arrêter un service qui s'exécute en tant que service de premier plan.
Le problème actuel est que lorsque j'appelle stopService()
la notification reste.
Donc, dans ma solution, j'ai ajouté un récepteur auquel je m'inscris dans la onCreate()
Dans la méthode onReceive()
j'appelle stopforeground(true)
et elle masque la notification. Et puis stopself()
pour arrêter le service.
À l'intérieur de la onDestroy()
J'ai désenregistré le récepteur.
Existe-t-il un moyen plus approprié de gérer cela? parce que stopService () ne fonctionne tout simplement pas.
@Override
public void onDestroy(){
unregisterReceiver(receiver);
super.onDestroy();
}
À partir de votre activité, appelez startService(intent)
et transmettez-lui des données qui représenteront une clé pour arrêter le service.
Depuis votre service, appelez stopForeground(true)
puis stopSelf()
juste après.
pour démarrer et arrêter un service de premier plan à partir d'une activité, utilisez:
//start
Intent startIntent = new Intent(MainActivity.this, ForegroundService.class);
startIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(startIntent);
//stop
Intent stopIntent = new Intent(MainActivity.this, ForegroundService.class);
stopIntent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(stopIntent);
dans votre service de premier plan - utilisez (au moins) ce code:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Start Foreground Intent ");
// your start service code
}
else if (intent.getAction().equals( Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
//your end servce code
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
En plus d'autres réponses, j'ai terminé avec cet extrait en utilisant Android oreo et laters pour arrêter les services de travail.
Intent intent = new Intent(getApplicationContext(), LocationService.class);
intent.setAction(status);
ContextCompat.startForegroundService(getApplicationContext(), intent);
Et en service
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
startForeground(121, notification);
if (intent.getAction().equals("StopService")) {
stopForeground(true);
stopSelf();
}
startForeground () est obligatoire sauf si l'application se bloque sans l'appeler
La nouvelle méthode Context.startForegroundService () démarre un service de premier plan. Le système permet aux applications d'appeler Context.startForegroundService () même lorsque l'application est en arrière-plan. Cependant, l'application doit appeler la méthode startForeground () de ce service dans les cinq secondes suivant la création du service.
https://developer.Android.com/about/versions/oreo/Android-8.0-changes.html
Comme indiqué ici: https://developer.Android.com/guide/components/services#Stopping
Un service démarré doit gérer son propre cycle de vie. Autrement dit, le système n'arrête ni ne détruit le service à moins qu'il ne doive récupérer la mémoire système et que le service continue de s'exécuter après le retour de onStartCommand () . Le service doit s'arrêter en appelant stopSelf () , ou un autre composant peut l'arrêter en appelant stopService () .
Une fois demandé d'arrêter avec stopSelf () ou stopService () , le système détruit le service dès que possible.
Vous pouvez donc appeler stopService () à partir de l'activité que vous avez utilisée pour appeler startService (). Je l'ai fait ici:
start_button.setOnClickListener {
applicationContext.startForegroundService(Intent(this, ServiceTest::class.Java))
}
stop_button.setOnClickListener {
applicationContext.stopService(Intent(this, ServiceTest::class.Java))
}
J'ai créé deux boutons pour démarrer et arrêter le service et cela fonctionne.
Si vous souhaitez arrêter le service, puis mettre à jour la notification, vous pouvez d'abord appeler stopSelf () puis notifier (). stopForeground (false) rend la notification annulable.
private final BroadcastReceiver myBgWorkCompleteReceiver= new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
stopSelf();
notificationLayoutExpanded.setTextViewText(R.id.file_download_notify_download_percentage, "Background work completed");
manager.notify(mNotificationId, notification);
stopForeground(false);
}
};
public void onDestroy() {
super.onDestroy();
// cancel any running threads here
LocalBroadcastManager.getInstance(this).unregisterReceiver(myBgWorkCompleteReceiver);
}
J'ai trouvé que la meilleure façon d'arrêter un service est de s'arrêter. De cette façon, vous êtes sûr qu'il s'arrêtera et préservera l'intégrité des données. Si vous voulez le faire de l'extérieur (activité), j'utilise généralement un attribut statique global.
Vérifiez ma réponse ici: https://stackoverflow.com/a/57833370/7795547