0

I'm trying to write code that will run a task on specific hours every day.

I have an hours array that contains integers and I loop through it to set a repeating alarm from that hour and with an interval of a day.

If I just create the service and run the task every 10 seconds or something it does run the AlarmReciever but this code doesn't work after the addition of the Calendar API, what am I doing wrong?

    AlarmManager alarmManager;
    Calendar current = new GregorianCalendar();
    Calendar calendar = new GregorianCalendar();
    int[] hours = new int[] {14, 18, 21, 22};

    public int onStartCommand(Intent intent, int flags, int startId) {
        current.setTimeInMillis(System.currentTimeMillis());

        alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent1 = new Intent(this, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent1, 0);
        for (int hour : hours) {
            calendar.add(Calendar.DAY_OF_YEAR, current.get(Calendar.DAY_OF_YEAR));
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            calendar.set(Calendar.DATE, current.get(Calendar.DATE));
            calendar.set(Calendar.MONTH, current.get(Calendar.MONTH));
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
        }
        return START_STICKY;
    }

EDIT: I tried printing out calendar.getTimeInMillis() for every loop and here is the output

I/System.out: 2391249600000
I/System.out: 2643724800000
I/System.out: 2769962400000
I/System.out: 2833038000000

Lets say I take the two first numbers: 2643724800000 - 2391249600000 = 252475200000. 252475200000 / 1000 = 252475200. 252475200 / 60 = 4207920. I'm pretty sure 4207920 minutes is more than one hour. Why is like this?

  • You know that you override the adding day of year with date when you call calendar.set(Calendar.DATE...), right? – MikeL Oct 10 '16 at 20:25
  • @MikeL I don't really understand how this works. I did it the same way its done here: http://stackoverflow.com/questions/3052149/using-alarmmanager-to-start-a-service-at-specific-time – Gregory Skliar Oct 10 '16 at 20:29
  • Actually i was wrong regarding override, you do something even worse, you add every time the current day of year (for example now it is 284) so you set the calendar to the next year and then you override the date to current date but the year is still the next one. Try removing the ".add" part and test it. – MikeL Oct 10 '16 at 20:40
  • In general i would not use this loop method because even if you will find a solution of triggering your alarm you will have this issue: Your app starts at 21:30 and sets all the alarms. In that case all the alarms that were set in the past like 14:00, 18:00 and 21:00 will be triggered immediately. – MikeL Oct 10 '16 at 20:49
  • @MikeL I will check if its works and be back with answer, but about this not being a good solution, can't I just use an if statement to check if that hour already happened today? – Gregory Skliar Oct 10 '16 at 20:57
  • @MikerL The values are correct now, my hours array looks like this for debugging `int[] hours = new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};` and the difference between every hour's milliseconds is 3600000 so that's working but I'll see if it actually displays the notifications. – Gregory Skliar Oct 10 '16 at 21:16

1 Answers1

0

Okay, I found out how to fix my problem. First of all thanks to @MikeL for suggesting to remove calendar.add(Calendar.DAY_OF_YEAR, current.get(Calendar.DAY_OF_YEAR)); because that did fix some stuff, but even after that it didn't work.

To fix the problem I changed PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent1, 0); to PendingIntent pendingIntent = PendingIntent.getBroadcast(this, hour, intent1, 0);

Basically changing the 0 to hour so that every pending intent is different.