web-dev-qa-db-fra.com

stopService n'arrête pas, c'est mon service .... pourquoi?

j'ai un service d'arrière-plan sur mon application Android qui récupère ma position GPS et l'envoie à une base de données distante. Ça fonctionne bien.

Le problème, c'est quand je veux arrêter le service ... ça n'arrête pas: S. De plus, aucune exception ou erreur sur logcat n'est apparue ... elle ne s'arrête tout simplement pas.

c'est le code pour démarrer mon service (avec un bouton):

startService(new Intent(GPSLoc.this, MyService.class)); //enciendo el service

c'est le code où je l'arrête (sur la méthode onactivityresult):

stopService(new Intent(GPSLoc.this, MyService.class));

J'ai été débogué de l'application et j'ai vérifié que la ligne de code stopService a été appelée à chaque fois que je l'ai déboguée, mais elle ne s'arrête pas ......

je suis sûr que ce n'est pas arrêté car sur ma base de données, je reçois toujours des positions GPS de l'émulateur quand j'ai appuyé sur le bouton pour arrêter le service.

qu'est-ce que je fais mal?

22

Avez-vous implémenté onDestroy()? Sinon, je pense que cela pourrait être la solution - et vous arrêtez votre Timer ou ce que vous utilisez pour exécuter le service dans onDestroy().

Un service peut être arrêté en appelant sa méthode stopSelf () ou en appelant Context.stopService ().

Voir ce link pour plus d’informations.

32
Joakim Berglund

je suis sûr que ce n'est pas arrêté car sur ma base de données, je reçois toujours des positions GPS de l'émulateur quand j'ai appuyé sur le bouton pour arrêter le service.

Vous ne désenregistrez probablement pas votre LocationListener.

9
CommonsWare

J'ai eu le même problème. J'ai constaté que si le service était connecté à GoogleApiClient et que la mise à jour de l'emplacement était toujours présente, la stopService() n'avait aucun effet, l'industrie du service () n'était pas appelée. Pour résoudre le problème, j'ai créé une fonction permettant d'arrêter le service de localisation. dans le code de service. Appelez la stopLocationService() de l'activité, puis appelez stopService. Voici l'exemple de code:

public class myLocationService extends Service{
...

    public void stopLocationUpdates() {

        LocationService.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,this);       
        mGoogleApiClient.disconnect();

    }
    ...
} 

En activité,

{
    ...
    if(mService != null && isBound) {

        mService.stopLocationUpdates();
        doUnbindService();
        stopService(new Intent(this,   myLocationService.class));

     }
     ...
} 
3
Hannah Zhang

Il est très courant dans cette situation que je doive arrêter mon service avant de terminer le processus. Dans certains cas, stopService (intention) ne suffit pas. Vous devriez avoir à l'esprit l'implémentation onDestroy () dans mon service. Exemple:

public class MyIntentService extends IntentService {

    // Defines and instantiates an object for handling status updates.
    private BroadcastNotifier mBroadcaster = null;
    private int progress = 0; //THIS IS MY COUNTER FOR EXAMPLE!!!

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        progress = 0;
        int tiempo_disponible = intent.getIntExtra("minutos_disponible", 0);

        if (mBroadcaster == null){

            mBroadcaster = new BroadcastNotifier(this);
        }
        // Broadcasts an Intent indicating that processing has started.
        mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_STARTED);

        mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_RUNNING);

        while (progress < tiempo_disponible) {

            progress++;
            try {
                Log.i(Constants.TAG, "Procesing " + progress);
                mBroadcaster.notifyProgress(progress);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        // Reports that the feed retrieval is complete.
        mBroadcaster.broadcastIntentWithState(Constants.STATE_ACTION_COMPLETE);
    }

    @Override
    public void onDestroy() {
        progress = 1000000; // WHITH THAT YOU FINISH THE CICLE IF tiempo_disponible NEVER IS MAYOR THAT 1000000, YOU CAN USE OTHER CONDITIONAL!!!!!!
        super.onDestroy();
    }
} 

De cette façon, lorsque vous aurez arrêté le service à l'aide de la méthode stopService, vous aurez également arrêté le compteur de processus. 

public void stopService(){
        context.stopService(intent);
        LocalBroadcastManager.getInstance(context).unregisterReceiver(responseReceiver);
        responseReceiver = null;
        intent = null;
}

Prenez soin de vous! @ Yaircarreno

2
yaircarreno

Si vous suivez la position GPS, vous avez probablement utilisé GoogleApiClient.

Le concept est que le service ne s'arrête pas,

si une instance GoogleApiClient est toujours connectée en son sein.

(Ou tout autre problème qui doit être détruit/non enregistré en premier)

Donc, pour que cela fonctionne, implémentez onDestroy() dans votre service:

@Override
public void onDestroy()
{
    // Unregistered or disconnect what you need to
    // For example: mGoogleApiClient.disconnect();
    super.onDestroy();
}
1
David

@Passer outre

public void onDestroy() {

    Log.d(TAG, "onDestroy");
    super.onDestroy();
    if (mLocationManager != null) {

        for (int i = 0; i < mLocationListeners.length; i++) {

            try {

                mLocationManager.removeUpdates(mLocationListeners[i]);

            } catch (Exception ex) {

                Log.d(TAG, "fail to remove location listners, ignore", ex);

            }

        }

    }

}
0
Ashwin H

il se peut que vous créiez une nouvelle intention à chaque fois que vous appelez le service d'arrêt.

stopService(new Intent(GPSLoc.this, MyService.class));

peut-être essayer: 

Intent intnet = new Intent(GPSLoc.this, MyService.class); // create el service

startService(intenet); 
stopService(intent);
0
Stelios Philippou

Dans mon cas, la stopService est appelée avec startService presque simultanément afin qu'aucun service ne soit arrêté. Essayez de retarder stopService pendant quelques secondes. :)

0
He Yifei 何一非

Pour ceux qui souhaitent envoyer une requête au serveur régulièrement, voici ma solution. Vous devriez avoir ceci dans votre activité ou activité de fragment

{
private static final Long UPDATE_LOCATION_TIME  = 30 * 60 * 1000l; // 30 minute

private AlarmManager alarm;
private PendingIntent pIntent; 
...

@Override
    protected void onResume() {
        super.onResume();

        // Run background service in order to update users location
        startUserLocationService();

        Log.e(TAG, "onResume");
    }

    @Override
    protected void onStop() {
        super.onStop();

        stopUserLocationService();

        Log.e(TAG, "onStop");
    }

private void startUserLocationService() {
        Log.i(TAG, "Starting service...");
        Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
        pIntent = PendingIntent.getService(this, 0, intent, 0);

        alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        Calendar cal = Calendar.getInstance();
        alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), UPDATE_LOCATION_TIME, pIntent);
    }

    private void stopUserLocationService() {
        alarm.cancel(pIntent);
        Intent intent = new Intent(MainFragmentHolder.this, ServiceUserLocation.class);
        stopService(intent);
    }

}
0
Hesam

mon problème a été résolu en supprimant les vues ajoutées à WindowManagerondestroy

public void onDestroy() {
    isRunning = false;
    super.onDestroy();
    if (checkBox!=null) {
        windowManager.removeView(getlayoutparm(fabsetting,fabrateus,fabexit,true)); 
        windowManager.removeView(checkBox); 
    }
 }
0
smaznet