Close the service when remove the app via swipe in

2019-03-16 20:03发布

问题:

I want to close the service when user removes the app from current running app list. Here, what I'm doing, when user starts the app, service gets started and remain in progress. But when user removes the app via swipe, new service is being created. I want to close the service. Below is my code.

// Start service using AlarmManager



    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.SECOND, 10);

    Intent intent = new Intent(this, MyService.class);

    PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);

    AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                5000, pintent);
    startService(new Intent(getBaseContext(), MyService.class));

MyService.java

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class MyService extends Service {
    int count = 0;
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "The new Service was Created", Toast.LENGTH_LONG).show();

    }

    @Override
    public void onStart(Intent intent, int startId) {
        // For time consuming an long tasks you can launch a new thread here...
        count++;
        Toast.makeText(this, " Service Started" + "  " + count, Toast.LENGTH_LONG).show();

    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();

    }



}

回答1:

According with google's employee Dianne Hackborn explains in a comment on one of her Google+ posts, you have to implemente the onTaskremoved on your service.

[W]hat specifically happens when you swipe away a recent task is it: (1) kills any background or empty processes of the application (see http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html#Lifecycle for what this means), and (2) uses the new http://developer.android.com/reference/android/app/Service.html#onTaskRemoved(android.content.Intent) API to tell any services of the application about the task being removed so it can do whatever it thinks is appropriate.

So I think you can do it this way: In that callback you have to stop the service, and tell the alarm manager to stop starting it again. For that, first of all, you need to pass to the service the pending intent that you use with the AlarmManger, so the service can use the intent to cancel the schedule. At least, you need all this:

In your service

public class MyService extends Service {
    private DefaultBinder mBinder;
    private AlarmManager  alarmManager ;
    private PendingIntent alarmIntent;

    private void setAlarmIntent(PendingIntent alarmIntent){
        this.alarmIntent=alarmIntent;
    }

    public void onCreate() {
        alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        mBinder = new DefaultBinder(this);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public void onTaskRemoved (Intent rootIntent){
        alarmManager.cancel(alarmIntent);
        this.stopSelf();
    }
}

Then in other file, you create DefaultBinder Class

public class DefaultBinder extends Binder {
    MyService s;

    public DefaultBinder( MyService s) {
        this.s = s;
    }

    public MyService getService() {
        return s;
    }
}

in your activity

MyService service;
protected ServiceConnection mConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder binder) {
        service = ((DefaultBinder) binder).getService();
        service.setAlarmIntent(pIntent);
    }

    public void onServiceDisconnected(ComponentName className) {
        service = null;
    }
};

protected void onResume() {
    super.onResume();
    bindService(new Intent(this, MainService.class), mConnection,
            Context.BIND_AUTO_CREATE);
}

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

    if (mConnection != null) {
        try {
            unbindService(mConnection);
        } catch (Exception e) {}
    }
}