I am developing an alarm based application, in which i have to repeat the alarm for every weekday like (every monday, tuesday, wednesday) based on user input. I used this snippet
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, alarmToSetInMilliSeconds, sender);
If user selects every monday means, i found the milliseconds more to next monday date and i set an alarm, and its working fine, how can i repeat it for other next monday, I want some idea to achieve it, any help are appreciated. Thanks.
here is my code to set alarm to repeat every month in 4th
public void init(Context context) {
Intent intent = new Intent(context, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
}
public void createAlarmControler(Context context) {
init(context);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 4);
cal.set(Calendar.HOUR_OF_DAY, 10);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
Date now = new Date(System.currentTimeMillis());
if (cal.getTime().before(now)) {
cal.add(Calendar.MONTH, 1);
}
long firstTime = cal.getTime().getTime();
alarmManager.cancel(pendingIntent);
Log.e("", "firstTime: " + firstTime);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, firstTime, 1000 * 60
* 60 * 24 * 30, pendingIntent);
}
public void cancelAlarmControler(Context context) {
init(context);
alarmManager.cancel(pendingIntent);
}
Related
I have an AlarmManager that I call at the end of every day, ie 23.59PM, to do some stuff for the new day. (Its called, NewDayReceiver.class.) It repeats every day.
I also set a broadcast receiver that will run the alarm on reboot. It all works fine.
However, if the phone is off at the end of the day, the alarm for that day is not called. When the phone is turned back on, on boot the alarm is set again, however its set for the end of the new day. It comes out, that the alarm for that day was never called. For example, if its off Sunday night, on Monday morning the phone is turned on but the alarm hasn't been called. It will only be called Monday night?
How can I do it, that on the boot broadcast receiver, I can check if the alarm was called for that day, and if it wasn't set the alarm to go off right away.
I hope its clear.
Here is my alarm for every day.
Intent intent = new Intent(this, NewDayReceiver.class);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
if(!calendar.before(Calendar.getInstance())) {
// Repeat every 24 hours
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24*60*60*1000, pendingIntent);
Log.d(TAG, "New day alarm set for:" + calendar.getTime() + " and will repeat every day");
}
Here is my BroadcastReceiver, that I call on boot:
public class BootBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "999.BootBroadcastReceiver";
#Override
public void onReceive(Context pContext, Intent intent) {
newDayAlarm(pContext);
newWeekAlarm(pContext);
}
private void newWeekAlarm(Context context) {
Intent intent = new Intent(context, NewWeekReceiver.class);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 55, intent, 0);
// real for end of week
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
if(!calendar.before(Calendar.getInstance())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Log.d(TAG, "New week alarm set for:" + calendar.getTime());
}
}
}
Scenario :
My task will executed every midnight using AlarmManager, let's say at 00:00:00 and should be repeated everyday
i use the following code :
Calendar setCalendar = Calendar.getInstance();
setCalendar.set(Calendar.HOUR_OF_DAY, 0);
setCalendar.set(Calendar.MINUTE,0);
setCalendar.set(Calendar.SECOND,0);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(this, AlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC, setCalendar.getTimeInMillis(), 1000 * 60 *60 *24, pi);
I also did this alarmManager.setInexactRepeating(AlarmManager.RTC, setCalendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi); but the result still same (not execute every midnight)
The receiver :
public static class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//execute my task
}
}
Android Manifest :
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<receiver android:name="com.projectx.activity.MainActivity$AlarmReceiver"/>
The code above didn't do anything even midnight has passed. Is there any wrong with my code? please help.
And also sometimes the alarm executed every several second after i set the alarm (not only at midnight)
I have no idea, what causes it.
try this:
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(context, TestNotifyService.class);
PendingIntent alarmIntent = PendingIntent.getService(context, 0, intent1, 0);
long _Nalarm;
Calendar now = Calendar.getInstance();
Calendar wakeupcall = Calendar.getInstance();
wakeupcall.setTimeInMillis(System.currentTimeMillis());
wakeupcall.set(Calendar.HOUR_OF_DAY, 21);
wakeupcall.set(Calendar.MINUTE, 59);
if (wakeupcall.getTimeInMillis() <= now.getTimeInMillis())
_Nalarm=wakeupcall.getTimeInMillis() + (AlarmManager.INTERVAL_DAY+1);
else
_Nalarm=wakeupcall.getTimeInMillis();
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, _Nalarm,AlarmManager.INTERVAL_DAY, alarmIntent);
}
Try the below code
Calendar setCalendar = Calendar.getInstance();
setCalendar.set(Calendar.HOUR_OF_DAY, 0);
setCalendar.set(Calendar.MINUTE,0);
setCalendar.set(Calendar.SECOND,0);
setCalendar.add(Calendar.DATE, 1);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(this, AlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC, setCalendar.getTimeInMillis(), 1000 * 60 *60 *24 , pi);
And the receiver:
public static class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//execute my task
Toast.makeText(context, " hello", Toast.LENGTH_SHORT).show();
}
}
Let me know if any issues.
How do i use the two vales i have (hour and minute ) to set and alarm at that time? The values i have unfortuntly arent formated so if hour is > 12 it wont go to one (Its in milatary time format) .Did i set up the pending intent correctly?
public void setUpAlarm(int hour,int minute) {
long newTime;
Intent alarm = Intent(setAlarmList.this, AlarmReciever.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent waiting = PendingIntent.getBroadcast(setAlarmList.this, 0, alarm, 0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, hour.);
use below code
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, h); // h->hour in 24 hrs system
cal.set(Calendar.MINUTE, m); // m->minutes
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
if (android.os.Build.VERSION.SDK_INT>16)
{
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), broadcast);
}else
{
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmIntent);
} //alarmIntent is your PendingIntent
read this documentation
My application creates an alarm that repeats every day. Since it is not possible to know if an alarm is already registered, I create the alarm every time the application is launched.
Here is the function that is called at the beginning of the main activity (inside onCreate()):
public static void setAlarm(Context context) {
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar firingCal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"));
Calendar currentCal = (Calendar)firingCal.clone();
Random rnd = new Random();
// Each day between 1:00 AM and 1:30 AM (some jitter added)
firingCal.set(Calendar.HOUR_OF_DAY, 1);
firingCal.set(Calendar.MINUTE, rnd.nextInt(30));
firingCal.set(Calendar.SECOND, 0);
long intendedTime = firingCal.getTimeInMillis();
long currentTime = currentCal.getTimeInMillis();
if (intendedTime >= currentTime) {
//set from today
alarmManager.setInexactRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
} else {
//set from next day
firingCal.add(Calendar.DAY_OF_MONTH, 1);
intendedTime = firingCal.getTimeInMillis();
alarmManager.setInexactRepeating(AlarmManager.RTC, intendedTime, AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
Is it OK to recreate the alarm each time the application is launched? Should I use some flags on the PendingIntent (like update or cancel existing PendingIntent)?
Thanks!
Update: is it a problem if I use flag 0 instead of PendingIntent.FLAG_UPDATE_CURRENT from a performance perspective?
I have this alarm manager which I want to fire at 6 AM everyday. I call the class notification, when the app is first launched and hence, it sets an repeating alarm for 6 AM every day(repeatedly).
The alarm manager works fine when the user installs(and runs the app first time) from 6 to 9 AM, however if the user runs the app for the first time after 9 AM, I'm supposed to add a day and fire the alarm the next day at 6AM. On doing so, (changing the date to the next day), the alarm gets fired at a random time, around 10 PM (That's a huge difference). Here's my code"
public notification(Context context) {
this.context=context;
Intent appstart=new Intent(context,appstartreceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context,0,appstart,PendingIntent.FLAG_UPDATE_CURRENT); // For appstart in the morning
AlarmManager alarmManager = (AlarmManager)context.getSystemService(context.ALARM_SERVICE);
Calendar currentCal=Calendar.getInstance();
Calendar startapp = Calendar.getInstance();// FOr app start in the morning
startapp.set(Calendar.HOUR_OF_DAY,6);
startapp.set(Calendar.MINUTE, 0);
startapp.set(Calendar.SECOND, 0);
long currentTime = currentCal.getTimeInMillis();
int diff=(int)(currentTime-startapp.getTimeInMillis())/(1000*60*60);
if (diff<3)
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,startapp.getTimeInMillis(),1000*24*60*60,pi);
else {
startapp.add(Calendar.HOUR_OF_DAY, 24);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, startapp.getTimeInMillis(), 1000 * 24 * 60 * 60, pi);
}
}
Replace your code with below code...this will fire everyday at 6 am. It may helps you.
public void notification(Context context) {
Intent intent = new Intent(this, appstartreceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 99, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
long startUpTime = calendar.getTimeInMillis();
// To avoid firing the alarm if the time is passed while setting
if (System.currentTimeMillis() > startUpTime) {
startUpTime = startUpTime + 24 * 60 * 60 * 1000;
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, startUpTime, 24 * 60 * 60 * 1000, pendingIntent);
}
You could try adding a day
if (calendar.before(Calendar.getInstance())) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
}
....// your code
That way it will fire everyday at the set time.
Try commonwares's wakeful intent service,it may help.
public class DailyListener implements AlarmListener {
public void scheduleAlarms(AlarmManager mgr, PendingIntent pi, Context context) {
// every day at scheduled time
Calendar calendar = Calendar.getInstance();
// if it's after or equal 6 am schedule for next day
if (Calendar.getInstance().get(Calendar.HOUR_OF_DAY) >= 6) {
calendar.add(Calendar.DAY_OF_YEAR, 1);
}
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
mgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
}
}