AlarmManager.RTC_WAKEUP not working for some devices - android

I am using AlarmManager in my application to set alarm for a particular time. I have used AlarmManager.RTC_WAKEUP to set the alarm. When I am testing the same it's working on number of device like Lg optimus, Sony Xperia etc. But while testing the same app in Samsung Galaxy S3 I found that alarm is not working. I am still unable to understand why is this happening.
I am using following code to set alarm :-
// create the object
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
//set the alarm for particular time
alarmManager.set(AlarmManager.RTC_WAKEUP,cal1.getTimeInMillis(), PendingIntent.getBroadcast(getActivity(),reminderId, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
Someone please help me to solve this strange problem. Any help would be appreciable.
Thank you

I'm not sure but it sounds the problem is with the way you set cal1's time and maybe different timezone.

I'm not sure what the particular issue you are having is, but you could try to replace cal1.getTimeinMillis() with System.currentTimeMillis() + your time delta in ms. This works consistently for me.

Is your testing getting tripped up by the long-time Android OS bug https://code.google.com/p/android/issues/detail?id=2880 ? If the clock gets set backwards, Intent.ACTION_DATE_CHANGED broadcast won't be delivered until the clock catches up to what was going to be the alarm time. (Reboot to reset this broken state.) That's because this Intent is based on an AlarmManager alarm which does not get updated when the clock changes.
That situation is pretty rare in normal use. But it occurs frequently when testing alarm code.
If you're testing an AlarmManager alarm by adjusting the clock, AFAIK any alarm set to a target Calendar on any Android device will get messed up by adjusting the clock. You can work around it by rescheduling your alarm whenever the clock gets adjusted. This assumes the system properly broadcasts Intent.ACTION_TIME_CHANGED so you can tell when the clock gets adjusted. (That Intent is misnamed. It's not like Intent.ACTION_DATE_CHANGED which occurs when the date changes due to time passing.)

I think you have problem in your "cal1" object;
When you set time in calendar object, actually setting Month, you should not use exact numeric value of month;
ex: - April = 4, you must use 3 instead of 4
I face this problem in API Level 19, but don't know about others.
This Question may give you better explanation.Why month give wrong value
public Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR,2014);
c.set(Calendar.MONTH, 03);//One minus from actual month numeric value
c.set(Calendar.DATE, 24);
c.set(Calendar.HOUR_OF_DAY,16 );
c.set(Calendar.MINUTE, 39);
c.set(Calendar.SECOND, 0);
am.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(),pi);

Related

setExactAndAllowWhileIdle is almost triggered exactly

I searched the Internet for an answer but have not found anything.
I wrote an app where every 17 minute an SMS must be sent ( every 17 minute means: 10:17:00 and not at 10:17:49 )
Therefore, I use an AlarmManager with setExactAndAllowWhileIdle, and AlarmManager.RTC_WAKEUP.
Long whenToFireOff = treeMapInstance.getFirstEntryInTreeMap().getKey();
Calendar alarmCal = Calendar.getInstance();
alarmCal.set(Calendar.HOUR_OF_DAY, treeMapInstance.convertMillisecondsToHour(whenToFireOff));
alarmCal.set(Calendar.MINUTE, treeMapInstance.convertMillisecondsToMinutes(whenToFireOff));
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmCal.getTimeInMillis(), pi);
However, it gets always triggered round about 10:17:49, and the next scheduled alarm also at 10:34:49, and so on.
I calculated my next alarm correctly. I am absolutely 100% sure :)
Is setExactAndAllowWhileIdle not as exactly as it is written in the documentation?
Thanks

AlarmsManager triggers whenever it wants

I want to trigger a notification each day at a specific time choosen by the user, like 6' / 7' / 8'.
For this, I created a WakefulBroadcastReceiver, that pass to an IntentService to create the notification.
And this is how I setup my AlarmsManager. timeInHours is an integer passed as parameter, between 6 and 12 :
Intent i = new Intent(context, StepCountNotifyBroadcast.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
// Get the next day at timeInHours hours'.
Calendar cal = Calendar.getInstance();
cal.setTime(new Date()); // compute start of the day for the timestamp
cal.set(Calendar.HOUR_OF_DAY, timeInHours);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.AM_PM, Calendar.AM);
if (new Date().getTime() > cal.getTime().getTime())
cal.add(Calendar.DAY_OF_YEAR, 1);
long nextDay = cal.getTime().getTime();
// Setup the alarm.
long timeBetween = AlarmManager.INTERVAL_DAY; // Each day.
AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarms.cancel(pi);
alarms.setRepeating(AlarmManager.RTC_WAKEUP, nextDay, timeBetween, pi);
Date nextDayAsDate = new Date(nextDay);
GLog.d("AlarmUtils", "scheduleNotifiation for next date: " + nextDayAsDate.toString());
It works well 50% of the time, but still do crazy things like... Trigger the notification at 2:00 AM ?!
I know the system will not trigger the notification at the specific time I want and this is ok. But here we talk about approximately 18 hours later.
In logs, it seems that my IntentService code is effectively running in the middle of the night in some cases. So that's not an issue with the notification itself.
I can switch this line :
alarms.setRepeating(AlarmManager.RTC_WAKEUP, nextDay, timeBetween, pi);
to another line of code :
alarms.setExact(AlarmManager.RTC_WAKEUP, nextDay, pi);
But this is not good for the battery life I'm afraid.
Now my questions :
Can somebody tell me a reason about the way Android devices works with AlarmsManager ?
Do you find another solution than will not drain battery life and be sure the notification will be triggered in maximum 2 or 3 hours later?
Do you have any ideas, in this particular case, to debug and do code testing without waiting a day or two to detect issues?
Thanks in advance.
After API Level 23, Doze mode was introduced on the Android System to reduce battery consumption. Go through below link:
How to make Alarm Manager work when Android 6.0 in Doze mode?

Setting Notification using AlarmManager by passing calendar.getTimeInMillis(),triggers notification instantly not at the time intended

I have followed the following link https://developer.android.com/training/scheduling/alarms.html.
RTC examples first one, to set an alarm for a specific time on all days. Even after following the same code, the alarm is not triggered at the time it is suppose to get triggered. Instead the notification gets triggered immediately after setting the time which is done with the help of a time picker. Following is my code snippet,
AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, NotificationReceiver.class);
PendingIntent intentalarm = PendingIntent.getBroadcast(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,4);
calendar.set(Calendar.MINUTE, 30);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, intentalarm);
Instead of setRepeating I also tried setInexactRepeating but there was no luck.I would also like to add that when I changed the
calendar.getTimeInMillis() and used SystemClock.elapsedRealtime() + 120 * 1000 the alarm triggered exactly after 2 minutes from the time it was set.
But when calendar.getTimeInMillis() is being used the intended working does not happen instead immediate triggering occurs.
Would be indeed very helpful if anyone can help me out find a solution.Only for a note, I could learn if alarm is set before current device time the alarm would be triggered immediately but that is not the case here.
NotificationReceiver.class is working fine as it is generated and appears on the title. But the time it appears is the cause of concern.
You are using both setTimeInMillis and hourofday and minute.
If you want your alarm to be triggered at 4:30 just add hourofday and minute.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,4);
calendar.set(Calendar.MINUTE, 30);`
I could Identify the issue I was facing. I was using a TimePicker with 24 hour format. But I used SimpleDateFormat "hh:mm". What 'h' stands for is as follows "h->Hour in am/pm (1-12) ". So any alarm that I set at AM triggers correctly. When I set a time at PM since I had used 1-12 'h' format, alarm gets set for a AM time and since that time is already passed when compared to the device time the alarm/notification got triggered immediately.The right format to use was "HH:MM" where 'H' stands for "H->Hour in day (0-23)". This resolved my issue.
Checking the TimeinMillis on online epoch time converter helped me identify this issue.Once again thanks for helping me.

Why alarmmanager not exactly repeats an event android

Please help me. Why does AlarmManager not exactly repeats an event when the repetition period of more than one day?
Here is my code to run AlarmManager. The variable time_period contains the following value 60*1000*60*24*7 which is equal to 7 days. In the end, if I change the date on your phone, the event is triggered by 6-4-7-7-7-7 days.
This can be seen in the logs of the application (See link http://prntscr.com/7kdqbw ) Thanks in advance for your reply.
Intent notification = new Intent(this , ServiceReminders.class);
notification.putExtra("backup", "backup");
AlarmManager alarmManagerBackup = (AlarmManager)getSystemService(ALARM_SERVICE);
PendingIntent pibackup = PendingIntent.getService(this, 3, notification, 10);
if (sdkVersion < 19) {
alarmManagerBackup.setRepeating(AlarmManager.RTC_WAKEUP, 0, time_period, pibackup);
}
else if (sdkVersion >= 19) {
alarmManagerBackup.setInexactRepeating(AlarmManager.RTC_WAKEUP, 0, time_period, pibackup);
}
Log.d("ServiceManagerNotification", "AlarmBackup sdkVersion = "+sdkVersion);
You are explicitly leveraging the inexact alarms by calling setInexactRepeating(). Unsurprisingly, this results in your alarms being set at inexact intervals.
The problem is further compounded by the fact that you are supplying a custom period. If you do not use one of the pre-defined intervals, then the framework will simply call setRepeating() using your interval instead of using setInexactRepeating().
From the documentation for the intervalMillis parameter:
interval in milliseconds between subsequent repeats of the alarm. Prior to API 19, if this is one of INTERVAL_FIFTEEN_MINUTES, INTERVAL_HALF_HOUR, INTERVAL_HOUR, INTERVAL_HALF_DAY, or INTERVAL_DAY then the alarm will be phase-aligned with other alarms to reduce the number of wakeups. Otherwise, the alarm will be set as though the application had called setRepeating(int, long, long, PendingIntent). As of API 19, all repeating alarms will be inexact and subject to batching with other alarms regardless of their stated repeat interval.
In the end, regardless of how you set this alarm, it will be inexact if you set it as a repeating alarm and there isn't a whole lot you can do about it.
If you need more precision, you should use either setWindow() or setExact() and set the next alarm every time your alarm triggers. Although if you are only performing an action once a week, it is likely that in the end you don't need that precision.

How to create Recurring of Alarm in Android After taking user input?

I am an android developer.I am making an application in which I have to take user input like
8:00,9:00,10:00 etc and I have to set alarm for 20 or 30 days for each time user enter .A user can enter two or three or any times the timings.I know there is a function
alarm.setRepeating(AlarmManager.RTC,System.currentTimeMillis()+timeinminutes*60*1000,30*1000, pintent);
But I have to set the alarm for ever or days entered by user .So can any body tell me .How can I do this .
the following code help you,firstWake the app will run at very fast time,you can specify as your requirements
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
long interval = android.text.format.DateUtils.DAY_IN_MILLIS*20;//or 30
long firstWake = System.currentTimeMillis() ;
am.setRepeating(AlarmManager.RTC,firstWake, interval, pendingIntent);
Maybe you can use another nonrepeating alarm for 20 or 30 days that stops repeating alarms.

Categories

Resources