Search code examples
androidbroadcastreceiverandroid-servicealarmmanagerandroid-broadcastreceiver

Running an Android Service after every 20 sec using AlarmManager doesn't restart on killing the app from the app list


I am trying to run an Android Service which runs in background every 20 sec and send user's lat-long data to server for tracking. It works for the first time when I launch my application. Now If I click the Home Button, It still runs in the background. But, now if I kill my application from the app list using the home button. And restart my App with the launcher icon. Now the Service doesn't start. I am using Alarm Manager to trigger my service after every 20 sec. But on Restart my Alarm is set but doesn't registers on Broadcast Receiver, as a Result My Service is not called. Below is my code:- MyFragment.java's onCreateView() where I am setting My Alarm:-

Intent alarm = new Intent(mContext, AlarmReceiver.class);
    boolean alarmRunning = (PendingIntent.getBroadcast(mContext, 0, alarm, PendingIntent.FLAG_NO_CREATE) != null);
    if (alarmRunning == false) {
        Log.e("In OnCreateView DDFrag", "AlarmRunning == False");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, alarm, 0);
        AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 20000, pendingIntent);
    } else{
        Log.e("In OnCreateView DDFrag", "AlarmRunning == True");
    }

AlarmReceiver.class:-

    public class AlarmReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent background = new Intent(context, MyService.class);
        Log.e("AlarmReceiver", "Broadcasr Receiver started");
        context.startService(background);
    }
}

MyService.class :-

    public class MyService extends Service {

    public boolean isServiceRunning;

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

    @Override
    public void onCreate() {
        this.isServiceRunning = false;
    }



    @Override
    public void onDestroy() {
        this.isServiceRunning = false;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(!this.isServiceRunning) {
            sendDataToServer();
            this.isServiceRunning = true;
        }
        return START_STICKY;
    }


    private void sendDataToServer() {
        // Performing my operation in this method..
    // On Success of the method performed I am calling the below method and setting the below variables:
    stopSelf();
        this.isServiceRunning = false;
    }
}

Also I am defining my service and receiver in the manifest.xml file as:-

<service android:name="com.mypackagename.services.MyService" />

    <receiver android:name="com.mypackagename.services.AlarmReceiver" />

Please help me to resolve the issue, or point me what i am doing wroung. As For the first time. as my Alarm manager is not set, it sets and the service is called after 20 sec appropiatley. But if I kill my application and start it again, then My Alarm is set so it doesn't start or set again. and now my AlarmReceiver class never receives the Alarm BroadcastReceiver.


Solution

  • Here's a few things:

    Please remove the "alarmRunning" code where you set the alarms. Just do it all the time. If the alarm is already set, setting it again will just cancel the old one and set a new one. This isn't a problem.

    You cannot rely on the existence of a PendingIntent to determine whether or not an alarm is set in the alarm manager. This is most likely the reason why you get no alarms after killing and restarting your app.

    Also, you cannot reliably schedule an alarm every 20 seconds using setRepeating(). Android has strict power management rules and will not reliably trigger a repeating alarm that is less than 2 minutes on most devices. You might see this alarm going off after 2 or 3 or 5 minutes instead of 20 seconds, depending on the power management settings, battery level, busyness of the device, whether it is sleeping, etc.

    If you really want something running every 20 seconds then you should set a single alarm and when that alarm goes off, process it and set the next alarm for 20 seconds from now.