I want AlarmManager to be fired at 10:30 AM daily based on user mobile device time. It fires at 10:30 AM for sure but the problem is that after 10:30 AM, It repeats without time like after at every half hour or after any unusual time interval.
How to prevent this problem ? I am calling this on Successfull Login and Registration ButtonCick() Event. I also want to stop this if user Logout.
My code is as below :
Intent myIntent = new Intent(Register.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Register.this,
0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar firingCal = Calendar.getInstance();
Calendar currentCal = Calendar.getInstance();
firingCal.set(Calendar.HOUR_OF_DAY, 10);
firingCal.set(Calendar.MINUTE, 30);
firingCal.set(Calendar.SECOND, 0);
long intendedTime = firingCal.getTimeInMillis();
long currentTime = currentCal.getTimeInMillis();
if (intendedTime >= currentTime) {
WakeLocker.acquire(getApplicationContext());
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, intendedTime,
AlarmManager.INTERVAL_DAY, pendingIntent);
WakeLocker.release();
} else {
WakeLocker.acquire(getApplicationContext());
firingCal.add(Calendar.DAY_OF_MONTH, 1);
intendedTime = firingCal.getTimeInMillis();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, intendedTime,
AlarmManager.INTERVAL_DAY, pendingIntent);
WakeLocker.release();
}
Code seems fine. If the target version is 19,
Note:
as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
Source:
http://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int,long,long,android.app.PendingIntent)
Note:
Beginning in API 19, the trigger time passed to this method is treated as inexact: the alarm will not be delivered before this time, but may be deferred and delivered some time later. The OS will use this policy in order to "batch" alarms together across the entire system, minimizing the number of times the device needs to "wake up" and minimizing battery use. In general, alarms scheduled in the near future will not be deferred as long as alarms scheduled far in the future.
With the new batching policy, delivery ordering guarantees are not as strong as they were previously. If the application sets multiple alarms, it is possible that these alarms' actual delivery ordering may not match the order of their requested delivery times. If your application has strong ordering requirements there are other APIs that you can use to get the necessary behavior; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent).
Applications whose targetSdkVersion is before API 19 will continue to get the previous alarm behavior: all of their scheduled alarms will be treated as exact.
Source:
http://developer.android.com/reference/android/app/AlarmManager.html#set(int,long,android.app.PendingIntent)
Please check if that works for your requirement.
Related
Muslims prayer times are 5 time a day , so i want my app to always check time , and when the current time matches with one from the 5 time, the App trigger an Action like play a media file , or send A notification to the userŅ
Use AlarmManager
AlarmManager mAlarmManger = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
//Create pending intent & register it to your alarm notifier class
Intent intent = new Intent(this, AlarmReceiver_maandag_1e.class);
intent.putExtra("uur", "1e"); // if you want
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
//set timer you want alarm to work (here I have set it to 9.00)
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
//set that timer as a RTC Wakeup to alarm manager object
mAlarmManger.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Thanks to zipo13 for the correction. As GoogleDeveloper say
Note: Beginning with API 19 (Build.VERSION_CODES.KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
This is my code. I think this method is right but I am not able to show the notification at exact time. There is always a delay of a few minutes.
public void setSimpleAlarm() {
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, 10);
c.set(Calendar.MINUTE, 19);
c.set(Calendar.SECOND, 40);
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(getActivity().ALARM_SERVICE);
Intent intentAlarm = new Intent(getActivity(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 3, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
Well, you're using setInexactRepeating(). As the name suggest and the [documentation](https://developer.android.com/reference/android/app/AlarmManager.html#setInexactRepeating(int, long, long, android.app.PendingIntent)) confirms it's for a "repeating alarm that has inexact trigger time requirements".
The documentation for [setRepeating()](https://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent)) contains the answer:
Note: as of API 19, all repeating alarms are inexact. If your
application needs precise delivery times then it must use one-time
exact alarms, rescheduling each time as described above. Legacy
applications whose targetSdkVersion is earlier than API 19 will
continue to have all of their alarms, including repeating alarms,
treated as exact.
I am trying to set an Alarm that goes off daily at 2:20 pm. Here is the code
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,14);
calendar.set(Calendar.SECOND,20);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent;
Intent intentService = new Intent(context, DownloadService.class);
//setting alarm to run at 2:20 pm
pendingIntent= PendingIntent.getService(context,0,intentService,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
When I use 5*60*1000 as the value for interval it works fine. But when I use AlarmManager.INTERVAL_DAY, it doesn't go off. Can someone tell me if the code above is correct ? Thanks.
I think you just oversaw the description in the INTERVAL_DAY:
Available inexact recurrence interval recognized by
setInexactRepeating(int, long, long, PendingIntent) when running on
Android prior to API 19.
In your code your using setRepeating not setInexactRepeating
AlarmManager.INTERVAL_DAY
Here is the difference in intervalMillis parameters:
setRepeating
intervalMillis interval in milliseconds between subsequent repeats of
the alarm.
setInexactRepeating
intervalMillis 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.
Hope I helped good luck!
Just replace this line :
calendar.set(Calendar.SECOND,20);
with this line :
calendar.set(Calendar.MINUTE,20);
I want to show toast at a specific time using AlarmManger but my toast is not shown at given time? Help me.
My code is as follows:
private void startAlarm() {
Calendar cal=Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH,9);
cal.set(Calendar.MONTH,7);
cal.set(Calendar.YEAR,2015);
cal.set(Calendar.HOUR_OF_DAY,2);
cal.set(Calendar.MINUTE,55);
cal.set(Calendar.AM_PM,Calendar.PM);
Intent intent = new Intent(this, WelcomActivity.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)getApplicationContext().getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
Toast.makeText(this, "Alarm worked.", Toast.LENGTH_LONG).show();
}
The documentation for setInexactRepeating states:
Your alarm's first trigger will not be before the requested time, but it might not occur for almost a full interval after that time.
[edit thanks to ci_]
Note: as of API 19, all repeating alarms are inexact. If your
application needs precise delivery times then it must use one-time
exact alarms, rescheduling each time as described above. Legacy
applications whose targetSdkVersion is earlier than API 19 will
continue to have all of their alarms, including repeating alarms,
treated as exact.
So you need to use one-time exact alarms and reschedule as described in the documentation.
I am creating a clock application that has alarm feature too. The time is showing up properly and I am also setting multiple alarm properly.
I am creating multiple alarm using different id and also saving the same into Database so that I can view the list of alarms in a listview. Now I am trying to set ON and OFF functionality for my alarm. I have a problem there.
On itemclick if alarm is ON it switches OFF with the help of:
Intent intent = new Intent(Main.this,TaskRecieverForAlarm.class);
PendingIntent pi = PendingIntent.getBroadcast(Main.this, Integer.parseInt(cont[0]), intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.cancel(pi);
The above code cancels the alarms perfectly fine.
To switch ON the alarm I am using:
Intent intent = new Intent(Main.this, TaskRecieverForAlarm.class);
intent.putExtra("AlarmDate", cont[1]);
intent.putExtra("key", Integer.parseInt(cont[0]));
PendingIntent sender = PendingIntent.getBroadcast(Main.this, Integer.parseInt(cont[0]) , intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
if(type.equalsIgnoreCase("daily"))
{
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1440*60000 ,sender);
}
else if(type.equalsIgnoreCase("weekly"))
{
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender); am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 7*1440*60000 ,sender);
}
Now as soon as I click the OFF to ON, alarm triggers and calls the TASKReceiverFORAlarm (broadcast receiver) even though the alarm time is 4 or 5 hours from the current time. I am not sure where I am going wrong?
Can somebody help me out?
Thanks!
I think I found the answer here:
public void setRepeating (int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
Added in API level 1
Schedule a repeating alarm. Note: for timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler. If there is already an alarm scheduled for the same IntentSender, it will first be canceled.
Like set(int, long, PendingIntent), except you can also supply a rate at which the alarm will repeat. This alarm continues repeating until explicitly removed with cancel(PendingIntent). If the time occurs in the past, the alarm will be triggered immediately, with an alarm count depending on how far in the past the trigger time is relative to the repeat interval.
If an alarm is delayed (by system sleep, for example, for non _WAKEUP alarm types), a skipped repeat will be delivered as soon as possible. After that, future alarms will be delivered according to the original schedule; they do not drift over time. For example, if you have set a recurring alarm for the top of every hour but the phone was asleep from 7:45 until 8:45, an alarm will be sent as soon as the phone awakens, then the next alarm will be sent at 9:00.
If your application wants to allow the delivery times to drift in order to guarantee that at least a certain time interval always elapses between alarms, then the approach to take is to use one-time alarms, scheduling the next one yourself when handling each alarm delivery.
Parameters
type One of ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP}, RTC or RTC_WAKEUP.
triggerAtMillis time in milliseconds that the alarm should first go off, using the appropriate clock (depending on the alarm type).
intervalMillis interval in milliseconds between subsequent repeats of the alarm.
operation Action to perform when the alarm goes off; typically comes from IntentSender.getBroadcast().
The way you use that function is:
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1440*60000 ,sender);
Try this one:
//The only variable here is the desired hour of the alarm, which
// has to be obtained in milliseconds
long alarmSetAt = // The hour of the Alarm for the current date in milliseconds
long time = cal.getTimeInMillis() - alarmSetAt;
if(time > 0){
time = -time + cal.getTimeInMillis();
}
else{
time = time + cal.getTimeInMillis() + 1440*60000;
}
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 1440*60000 ,sender);