wake-up-neo.com

stopService hört nicht auf, mein Service ... warum?

ich habe einen Hintergrunddienst auf meiner Android-App, der meine GPS-Position abruft und an eine entfernte Datenbank sendet. Es funktioniert gut.

Das Problem ist, wenn ich den Dienst stoppen möchte .... es hört nicht auf: S. Es sind auch keine Ausnahmen oder Fehler auf logcat aufgetreten ... es hört einfach nicht auf.

dies ist der Code, um meinen Dienst zu starten (mit einem Knopf):

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

dies ist der Code, in dem ich ihn stoppe (bei der Methode onactivityresult):

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

Ich habe die App debuggt und überprüft, dass die stopService-Codeline jedes Mal aufgerufen wurde, wenn ich sie debuggt habe, aber sie stoppt nicht ......

ich bin sicher, dass es nicht gestoppt ist, weil in meiner Datenbank ich immer noch GPS-Positionen vom Emulator erhalte, wenn ich die Taste gedrückt habe, um den Dienst zu stoppen.

was mache ich schlecht

22

Haben Sie onDestroy() implementiert? Wenn nicht, glaube ich, dass dies die Lösung sein könnte - und Sie stoppen Ihre Timer oder was auch immer Sie verwenden, um den Dienst innerhalb von onDestroy() auszuführen.

Ein Dienst kann gestoppt werden, indem die Methode stopSelf () oder Context.stopService () aufgerufen wird.

In diesem link finden Sie weitere Informationen.

32
Joakim Berglund

ich bin sicher, dass es nicht gestoppt wird, weil auf meiner Datenbank immer noch GPS-Positionen aus dem Emulator empfangen werden, wenn ich die Taste gedrückt habe, um den Dienst zu beenden.

Sie können Ihre LocationListener-Registrierung wahrscheinlich nicht aufheben.

9
CommonsWare

Ich hatte das gleiche Problem. Ich habe festgestellt, dass, wenn der Dienst GoogleApiClient verbunden ist und immer noch eine Standortaktualisierung erhält, die stopService() keinerlei Auswirkungen hat und die Industrie () des Dienstes nicht aufgerufen wurde. Um das Problem zu beheben, habe ich eine Funktion zum Beenden des Standortdienstes erstellt im Service-Code. Rufen Sie stopLocationService() aus der Aktivität auf, und rufen Sie dann stopService auf. Hier ist das Codebeispiel:

public class myLocationService extends Service{
...

    public void stopLocationUpdates() {

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

    }
    ...
} 

In der Tätigkeit

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

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

     }
     ...
} 
3
Hannah Zhang

Diese Situation ist sehr üblich, in der ich meinen Dienst einstellen muss, bevor der Vorgang abgeschlossen werden kann. In manchen Fällen reicht es nicht mit stopService (intent). Sie sollten die onDestroy () - Implementierung in meinem Dienst berücksichtigen. Beispiel:

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

Auf diese Weise haben Sie, wenn Sie den Dienst mit der Methode stopService beendet haben, auch den Prozesszähler gestoppt. 

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

Passen Sie auf! @ Yaircarreno

2
yaircarreno

Wenn Sie die GPS-Position verfolgen, haben Sie wahrscheinlich GoogleApiClient verwendet.

Das Konzept ist, dass der Service NICHT aufhört,

wenn eine GoogleApiClient-Instanz noch mit ihr verbunden ist.

(Oder ein anderes Problem, das zuerst gelöscht/nicht registriert werden muss)

Damit es funktioniert, implementieren Sie onDestroy() in Ihrem Service:

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

@Überfahren

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

es könnte sein, dass Sie jedes Mal, wenn Sie den Stop-Service aufrufen, eine neue Absicht erstellen.

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

vielleicht versuchen Sie es: 

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

startService(intenet); 
stopService(intent);
0

In meinem Fall wird stopService fast gleichzeitig mit startService aufgerufen, so dass kein Dienst dort gestoppt werden kann. Versuchen Sie, einige Sekunden lang stopService zu warten. :)

0

Für diejenigen, die regelmäßig eine Anfrage an den Server senden möchten, ist dies meine Lösung. Sie sollten dies in Ihrer Aktivität oder Fragmentaktivität haben

{
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

Ich habe den besten Weg gefunden, einen Dienst zu stoppen, indem ich ihn stoppen lasse. Auf diese Weise können Sie sicher sein, dass die Datenintegrität tatsächlich erhalten bleibt. Wenn Sie es von außerhalb (Aktivität) tun möchten, verwende ich normalerweise ein globales statisches Attribut.

Pro Beispiel (Kotlin), wenn ich MyService, MyActivity und MyObject habe

Mein Objekt

object MyObject{
    abort = false
}

MeinService

override fun onHandleIntent(intent: Intent?) {
    startForeground(id,notification)   
    for (i in range){
        if (MyObject.abort) break
        // RUN SOME CODE HERE
    }
    stopForeground(true)
    stopSelf()
}

Meine Aktivität

fun startService() {
    startForegroundService(Intent(this, OptimizationService::class.Java))
}
fun stopService() {
    MyObject.abort = true
}
0
D Dimitrov

mein Problem wurde gelöst, indem die hinzugefügten Ansichten zu WindowManagerondestroy entfernt wurden.

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