I have this code in my class:
public void setAlarm(Context context)
{
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, StepCountUpdaterAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
Long startOfTommorowMillis = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Long startOfTodayMillis = calendar.getTimeInMillis();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 0);
Long startOfAlarmMillis = calendar.getTimeInMillis() - startOfTodayMillis;
Long totalWaitMillis = (startOfTodayMillis + startOfAlarmMillis) - System.currentTimeMillis();
if(totalWaitMillis < 0) return;
if (android.os.Build.VERSION.SDK_INT >= 23) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
totalWaitMillis,
pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP,
totalWaitMillis,
pendingIntent);
}
}
What I am trying to do is to have this alarm fire at 6:30am UTC every day. To do that I use Long totalWaitMillis = (startOfTomorrowMillis + startOfAlarmMillis) - System.currentTimeMillis();
but for testing purposes, i changed it to use startOfTodayMillis
so i can test the alarm.
I managed to get the calendar to show the correct firing times with startOfTodayMillis - startOfAlarmMillis
. When i subtract System.currentTimeMillis()
, it seems to provide the correct amount of millisecond delay for the alarm to fire next. In effect, it calculates the time in milliseconds till it hits 6:30 today (I have not fired it in the past in this scenario). Yet despite this, it fires extremely early and does its task far earlier than expected. When I use startOfTomorrowMillis + startOfAlarmMillis
as well, it fires practically a day early and multiple times. I am a novice when it comes to working with AlarmManager so any help here would be appreciated.
EDIT: I am aware that these alarm timers are not exact. I expected a few seconds offset but not minutes or near enough a day. To add a bit of detail, I just tried setting the alarm an hour from now, it fired at least 5 times within around 20 seconds, after an initial 30 seconds from the alarm being set. My device currently uses the setAndAllowWhileIdle
method.
2
Answers
The method shown in the question was to have the alarm work in idle but to repeat itself which is not a feature i have seen available in the AlarmManager from reading its documentation.
My initial misconception with the AlarmManager was that the
setAndAllowWhileIdle
andset
methods's second parameterLong triggerAtMillis
wasn't a count down to the next time it should fire the alarm, it was the actual time it should fire for the next alarm. The documentation for thetriggerAtMillis
parameter shown here and below:Courtesy of @Niaj Mahmud 's I have made my own twist to the answer he provided that works such that it does a scheduled task while the phone is in doze mode/ is idle. In this example I schedule the task at 11:58pm of each day, without the need for a notification.
Activity.java code:
BroadcastReciever.java code
For recurring alarm why you are doing like that.. alarm manager already has own method for alarm in every 24 hour.
first create a class with broadcast receiver like
after that go to your activity class make 2 method and call in oncreate
Note – Must to do(go to your app setting and give notification permission on) 1.alarmManager.setRepeating here you can use your alarm type as your wish. 2.requestcode must be unique for each alarm. 3. you must take a alarm time and keep in calender.timeInMillis which is you expecting alarm time.
still problem comments below