Alarm Manager every week

This is how to fire an Alarm every week on Android.

Since the Android device may restart multiple times during that period of time I’ve had a hard time setting triggerAtMillis in setInexactRepeating. I’ve finally settled on the following solution.

Utils.java

private static SharedPreferences sharedPreferences = null;

/* Shared preferences getter */
public static SharedPreferences getPreferences(Context context) {
    if (sharedPreferences==null) {
        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
    }
    return sharedPreferences;
}

Constants.java

public final static String lastTriggerKey = "TRIGGER";

CronSend.java

public class CronSend extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
        wl.acquire();

        //Extend period by 7 days - this is called when the Alarm is fired
        Long lastTime = Utils.getPreferences(context).getLong(Constants.lastTriggerKey, System.currentTimeMillis());
        Utils.getPreferences(context).edit().putLong(Constants.lastTriggerKey, lastTime+(AlarmManager.INTERVAL_DAY*7)).apply();

        // Put here YOUR code.
        Toast.makeText(context, "Alarm. Last: " + String.valueOf((System.currentTimeMillis()-lastTime)/(1000*60*60*24)), Toast.LENGTH_LONG).show();

        wl.release();
    }

    public void SetAlarm(Context context) {
        AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, CronSendSMS.class);
        PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);

        Long lastTime = Utils.getPreferences(context).getLong(Constants.lastTriggerKey, System.currentTimeMillis());
        Log.i(Constants.TAG, "LastTime is " + String.valueOf(lastTime));
        am.setInexactRepeating(AlarmManager.RTC_WAKEUP, lastTime, AlarmManager.INTERVAL_DAY*7, pi);
    }

    public void CancelAlarm(Context context) {
        Intent intent = new Intent(context, CronSendSMS.class);
        PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        alarmManager.cancel(sender);
    }
}

Enjoy!