javaandroidrepeatingalarm

AlarmManager RepeatingAlarm not firing more than once


Ok so I have a background refresh which the user can toggle in the settings. Here is the code from the Settings activity:

intent  = new Intent(context, UpdateScoresService.class);
recurringDownloadDaily = PendingIntent.getService(context,0,intent, 0);
recurringDownloadWeekly = PendingIntent.getService(context, 1, intent, 0);
 Preference.OnPreferenceChangeListener refreshListener = new Preference.OnPreferenceChangeListener() {
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    if(newValue.toString().equals("1")){ /* daily */
                        background_refresh.setSummary("Scores will be refreshed daily.");

                        AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                        manager.cancel(recurringDownloadDaily);
                        manager.cancel(recurringDownloadWeekly);
                        Log.e("DAILY REFRESH", " ");
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTimeInMillis(System.currentTimeMillis());
                        calendar.set(Calendar.HOUR_OF_DAY,10);
                        calendar.set(Calendar.MINUTE,00);
                        if(calendar.before(Calendar.getInstance())){
                            Log.e("AFTER", "10 AM DAILY");
                            calendar.add(Calendar.DATE, 1);
                        }
                        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringDownloadDaily);
                    }else if(newValue.toString().equals("2")){ /* weekly */
                        Log.e("WEEKLY REFRESH", " ");
                        background_refresh.setSummary("Scores will be refreshed weekly.");
                        AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                        manager.cancel(recurringDownloadDaily);
                        manager.cancel(recurringDownloadWeekly);
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTimeInMillis(System.currentTimeMillis());
                        calendar.set(Calendar.HOUR_OF_DAY,10);
                        calendar.set(Calendar.MINUTE,00);
                        if(calendar.before(Calendar.getInstance())){
                            Log.e("AFTER", "10 AM WEEKLY");
                            calendar.add(Calendar.DATE, 1);
                        }
                        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, recurringDownloadWeekly);
                    }else{ /* manually */
                        background_refresh.setSummary("Scores will be refreshed manually.");
                        Log.e("MANUAL REFRESH", " ");
                        AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
                        manager.cancel(recurringDownloadDaily);
                        manager.cancel(recurringDownloadWeekly);
                    }
                    return true;
                }
            };
            background_refresh.setOnPreferenceChangeListener(refreshListener);

If the user sets the daily alarm, I expect it to refresh every morning at 10 AM. For testing, when I set the date to the following day and set the time to 9:59AM, the alarm fires around 10AM. And can keep changing the date and time on the phone manually, and it fires off every time. However, it seems if i set the option and simply wait till the next day, the alarm may or may not fire. I feel that more often than not, it doesn't happen.

I also have this code to know when the device has finished booting to reschedule the alarm after the device has turned off and back on:

public void onReceive(Context context, Intent intent) {
        Log.e("Boot reciever", "a");
        if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
//            Toast.makeText(context, "Boot Reciever", Toast.LENGTH_SHORT).show();
            Log.e("Boot reciever", "b");
            SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
            intent1  = new Intent(context, UpdateScoresService.class);
            recurringDownload = PendingIntent.getService(context,0,intent1, 0);

            String refreshRate = sharedPreferences.getString("background_refresh", "1");

            if(refreshRate.equals("1")){ /* daily */
                daily(context);
            }else if(refreshRate.equals("2")){ /* weekly */
                weekly(context);
            }else { /* manually */
                manually(context);
            }

        }
    }

    public void daily(Context context){
        Log.e("DAILY REFRESH", "BRUH!");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY,10);
        calendar.set(Calendar.MINUTE,00);
        if(calendar.before(Calendar.getInstance())){
            Log.e("AFTER", "10 AM WEEKLY");
            calendar.add(Calendar.DATE, 1);
        }
        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY, recurringDownload);
    }
    public void weekly(Context context){
        Log.e("WEEKLY REFRESH", "BRUH!");
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        calendar.set(Calendar.HOUR_OF_DAY,10);
        calendar.set(Calendar.MINUTE,00);
        if(calendar.before(Calendar.getInstance())){
            Log.e("AFTER", "10 AM WEEKLY");
            calendar.add(Calendar.DATE, 1);
        }
        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY * 7, recurringDownload);
    }

    public void manually(Context context){
        Log.e("MANUAL REFRESH", "BRUH!");
        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        manager.cancel(recurringDownload);
    }

And as far as I can tell this seems to work as well if I turn off the phone at 9:55 and boot it back up, the service still runs.

The problem is, it's not running the following day or days. I'm not really sure why, maybe the service is getting killed in the background? I was thinking adding the same code to the MainActivity's onResume to reschedule the alarm, but that seems a bit excessive and I should be able to get it to run consistently without doing that.


Solution

  • Not sure, but check below points:

    1. Created two unique alarms with 0 & 1 ids but on boot completed, restarting only one alarm with 0 id.
    2. When testing with repeating alarms with date changing to and fro, might be an issue. Since alarm for that day might be fired and later you have changing to previous date, it wont fire for that day once again until restart it.
    3. On boot completed or assigning any alarms, you must cancel previous alarms for that pending intent before assigning to it.
    4. You service is not killed because they haven't started, since pending intent are to be triggered the service.

    If you still face issue, please check this blog. (Not sure where it went wrong, so posting my blog URL for references)