alarm manager/ service/ broadcast receiver is not working after app is closed or swiped away from the recent app

909 views Asked by At

I know there are so many questions about this. I tried most of them and spent so much time on it. but not getting any solution

Actually, I want a background process to run to infinite time even app is removed from recent app I want to take GPS location of user repetitively after 15 minute

so first I had tried with following

TRY 1****** I have created broadcast receiver who will call my service name of that broadcast receiver is LocationServiceRestarter I am initiating alarm repeater who will call LocationServiceRestarter at regular interval of 5 seconds

Intent intent = new Intent("com.lmf.overduereport.gpstimer.LocationServiceRestarter");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
        0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
        (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
alarm_manager.setRepeating(AlarmManager.RTC_WAKEUP,SystemClock.elapsedRealtime()+5*1000,5*1000,pendingIntent);

it works fine if I don't remove app from recent apps I have added a log inside broadcast receiver who writes log in my folder about if broadcast receiver called or not. in this case broadcast receiver itself is not called from alarm manager then it will obviously not call service that i want to be called to record location.

TRY 2****** I have also tried services who can run infinitely. but it also stops working after app closes

TRY 3****** This time I will not call repetitive alarm manager instead of that I did following

Intent intent = new Intent("com.lmf.overduereport.gpstimer.LocationServiceRestarter");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),
        0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
        (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
//--
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 5000, pendingIntent);

above will call broadcast receiver and in broadcast receiver I have added alarm manager as follows

LocationServiceM.appendLog("Got Reciever******");
intent = new Intent("com.lmf.overduereport.gpstimer.LocationServiceRestarter");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
        12345, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am =
        (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);

am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 5000, pendingIntent);

above will reinitiate broadcast receiver with new schedule time so chain will continue.

but sadly that also don't work. it works fine if app is not removed from the recent app.

even I had tried same above thing with service and intent service with no luck.

Conclusion: alarm manager or Broadcast receiver is not called after app is removed from the recent app.

but I have seen many app that runs in background even app is closed from recent app.

1

There are 1 answers

1
rafsanahmad007 On

you can use START_STICKY which tells the OS to recreate the service after it has enough memory and call onStartCommand() again with a null intent. START_NOT_STICKY tells the OS to not bother recreating the service again.

you can use a service to fired when app is closed or kill from the task:

public class SensorService extends Service {
public int counter=0;
public SensorService(Context applicationContext) {
    super();
    Log.i("HERE", "here I am!");
}

public SensorService() {
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    startTimer();
    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.i("EXIT", "ondestroy!");
    Intent broadcastIntent = new Intent("uk.ac.shef.oak.ActivityRecognition.RestartSensor");
    sendBroadcast(broadcastIntent);
    stoptimertask();
}

private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() {
    //set a new Timer
    timer = new Timer();

    //initialize the TimerTask's job
    initializeTimerTask();

    //schedule the timer, to wake up every 1 second
    timer.schedule(timerTask, 1000, 1000); //
}

/**
 * it sets the timer to print the counter every x seconds
 */
public void initializeTimerTask() {
    timerTask = new TimerTask() {
        public void run() {
            Log.i("in timer", "in timer ++++  "+ (counter++));
        }
    };
}

/**
 * not needed
 */
public void stoptimertask() {
    //stop the timer, if it's not already null
    if (timer != null) {
        timer.cancel();
        timer = null;
    }
}

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

you also need a BroadcastReceiver which will receive a signal when someone or something kills the service; its role is to restart the service.

 public class SensorRestarterBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(SensorRestarterBroadcastReceiver.class.getSimpleName(), "Service Stops! Oooooooooooooppppssssss!!!!");

        context.startService(new Intent(context, SensorService.class));;
    }
}

For full implementation see this link http://fabcirablog.weebly.com/blog/creating-a-never-ending-background-service-in-android