I am trying to develop alarm functionality in a my app which runs on a week days specified by user on fixed time. Problem here is that my scheduler running for all days instead of running on specified day . here is the code i wrote for this please help to fix this
Calendar calNow = Calendar.getInstance();
SimpleDateFormat simpDate;
simpDate = new SimpleDateFormat("kk:mm:ss");
if(in_Date==1)
{
calNow.set(Calendar.HOUR_OF_DAY, hourOfDay);
calNow.set(Calendar.MINUTE, minute);
calNow.set(Calendar.SECOND, 0);
calNow.set(Calendar.MILLISECOND, 0);
}
else if(in_Date==2)
{
calNow.set(Calendar.HOUR_OF_DAY, hourOfDay);
calNow.set(Calendar.MINUTE, minute);
calNow.set(Calendar.SECOND, 0);
calNow.set(Calendar.MILLISECOND, 0);
calNow.set(Calendar.DAY_OF_WEEK,in_SelectedDay);
}
etTime.setText(simpDate.format(calNow.getTime()));
Seconds=calNow.getTimeInMillis();
private void setAlarm(){
//etTime.setText(simpDate.format(calNow.getTime()));
Intent intent = new Intent(getBaseContext(), AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(getBaseContext(), RQS_1, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
if(in_Date==1)
{
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Seconds,alarmManager.INTERVAL_DAY,pendingIntent);
}
else if(in_Date==2)
{
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Seconds,1 * 60 * 60 * 1000,pendingIntent);
}
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Seconds, AlarmManager.INTERVAL_DAY, pendingIntent);
In this line you set the start time to the user selected day, but then set the interval to INTERVAL_DAY.
You should use INTERVAL_DAY * 7 to make sure it repeats on a weekly basis instead:
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Seconds, AlarmManager.INTERVAL_DAY * 7, pendingIntent);
Is your alarm getting triggered everyday or every hour ?
I am supposing your in_Date is an indicator to choose daily alarm or for specific days .
My idea-> set the alarm for all days, check your day condition in the alarm receiver .
Related
I'm working on alarm clock app. I've faced with one problem. I do not know how to set alarm for several days. I've already tried the code that is below but in log I saw this Wed Apr 06(didn't change any date so it should be nearest tuesday and friday). What do I do wrong? May be I should set alarm separately for every other day?
This is my code:
calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY, Calendar.FRIDAY);
//calendar.add(Calendar.DAY_OF_WEEK,Calendar.FRIDAY);
Log.e("Point_1","Calendar " + calendar.getTime());
calendar.set(Calendar.HOUR_OF_DAY,timePicker.getCurrentHour());
calendar.set(Calendar.MINUTE,timePicker.getCurrentMinute());
Intent intent1 = new Intent(MyService_alarm.this,MyReceiver_Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService_alarm.this,intent.getIntExtra("Size", 1),intent1,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent);
Thank you.
That is because you are logging the time before setting the hour and minutes from the time picker,
your code si working fine but to display the time that was set to the Alarm in your log you have to move the Log.e to after you set the Calendar to the hour and minute from your picker so your code should look like this :
calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY, Calendar.FRIDAY);
//calendar.add(Calendar.DAY_OF_WEEK,Calendar.FRIDAY);
calendar.set(Calendar.HOUR_OF_DAY,timePicker.getCurrentHour());
calendar.set(Calendar.MINUTE,timePicker.getCurrentMinute());
Log.e("Point_1","Calendar " + calendar.getTime());
Intent intent1 = new Intent(MyService_alarm.this,MyReceiver_Alarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService_alarm.this,intent.getIntExtra("Size", 1),intent1,0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent);
Also since you are making an Alarm for several days it would be wise to save all the set alarms and to add a receiver to detect when the device has been booted since your alarms are cancelled on reboot and will need to be added again.
The line
calendar.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY, Calendar.FRIDAY);
is not correct. If you look at the documentation you will see that there is no such method.
By writing Calendar.DAY_OF_WEEK you are telling system that you are entering some value as day of the week. But instead of one specific day you are entering two. Calendar object is used to store one specific date.
Therefore, in order to get set alarms for several days, you need to set each of the alarms separately. For this reason you may create separate Calendar objects or reuse one by changing the time. However, you have same receiver class for both alarms. Therefore, you need to create different pending intents to make alarm manager differentiate them. For this reason I have shown you the example with different request_code.
calendar1.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY);
calendar2.set(Calendar.DAY_OF_WEEK, Calendar.FRIDAY);
calendar1.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
calendar1.set(Calendar.MINUTE, timePicker.getCurrentMinute());
calendar2.set(Calendar.HOUR_OF_DAY, timePicker.getCurrentHour());
calendar2.set(Calendar.MINUTE, timePicker.getCurrentMinute());
Intent intent1 = new Intent(MyService_alarm.this, MyReceiver_Alarm.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(MyService_alarm.this, 1, intent1, 0);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(MyService_alarm.this, 2, intent1, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar1.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent1);
alarmManager.setRepeating(AlarmManager.RTC, calendar2.getTimeInMillis(), 7 * 24 * 3600 * 1000, pendingIntent2);
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);
}
}
I am trying to trigger action everyday at 00:00:00 AM using AlarmManager but the problem is first time action is triggered quickly and then works as expected. First time, action triggers as soon as the code is run. Please see the following code:
private void setAlarmManagerForDateChange()
{
Intent intent = new Intent(this, DateTimeChangeReceiver.class);
intent.putParcelableArrayListExtra("names", names);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
999, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM, Calendar.AM);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
24 * 60 * 60 * 1000, pendingIntent);
}
It action triggers before 00:00:00 AM for the first time. Please point out what is being missed. Thanks,
You're scheduling the alarm in the past, which causes the AlarmManager to fire instantly.
You take the current date (e.g. 05/29/14 20:08:32), and set the hour, minute and second to 0.
What you get is: 05/29/14 00:00:00.
What you actually want, is to add another day to get to 06/29/14 00:00:00.
calendar.add(Calendar.DAY, 1);
I want to fetch location every hours in android . For that i use alarm manager and set repeated alarm for every hour and just want to write into file after fix time i.e at 8 AM and 12 PM .
I got a problem in setting alarm manager , while i set for every one hour but it execute in 1/2 hour .
on button click i start service :
serviceButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(AutoMainActivity.this, TrackerService.class);
pendingIntent = PendingIntent.getService(AutoMainActivity.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, ALARM_TRIGGER_AT_TIME,
3600000, pendingIntent);
//3600000 1hrs
finish();
}
});
And Service Class are as :
Tracker Service.class
String FINAL_STRING;
SharedPreferences pref;
static final int START_TIME = 8;
static final int MID_TIME = 12;
java.util.Date systemDates = Calendar.getInstance().getTime();
int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
if(hour == START_TIME)
{
edit.putString("smsdata", FINAL_STRING);
edit.commit();
//sendSms(START_TAG+pref.getString("smsdata", ""));
edit.putString("smsdata", "");
edit.commit();
}else {
System.out.println("currentdate:"+simpleDateFormat.toString());
System.out.println("current_time:"+currentTime);
Editor edit = pref.edit();
edit.putString("smsdata", pref.getString("smsdata", "")+FINAL_STRING+"#");
edit.commit();
if(hour==MID_TIME)
{
//sendSms(START_TAG+pref.getString("smsdata", ""));
generateNoteOnSD("\n"+START_TAG+pref.getString("smsdata", ""));
edit.putString("smsdata", "");
edit.commit();
System.out.println("mid time");
}
}
When i execute this the service start on every 30min. but i want on every 60min.
First, you really want to use one of the available constants, like INTERVAL_HOUR, with setInexactRepeating().
Second, setInexactRepeating() is inexact. Android reserves the right to flex the times of the alarms to coalesce events with other scheduled inexact alarms.
So, try switching briefly to setRepeating(). If it now works as you expect, your behavior is due to the "inexact" nature of setInexactRepeating().
Also, you can use adb shell dumpsys alarm to examine the scheduled alarms. It may be that you have two alarms scheduled, each going off once per hour.
setInexactRepeating() is the reason why it is not working as you expected. Try following:
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, firstStart, interval, pendingIntent );
In my application I have the functionality to trigger an alarm in 4 scenarios:
Only once for a user-chosen date and time
Daily for the chosen time
Weekly according to chosen date and time
User chosen custom days of the week
I successfully implement the first 3 scenarios by using the following:
Only once:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, Integer.parseInt(date[0]));
calendar.set(Calendar.MONTH, (Integer.parseInt(date[1])) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(date[2]));
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
For daily scheduling:
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
calendar.set(Calendar.SECOND, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
For weekly scheduling (as per system date):
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(time[0]));
calendar.set(Calendar.MINUTE, Integer.parseInt(time[1]));
calendar.set(Calendar.SECOND, 0);
//long interval = calendar.getTimeInMillis() + 604800000L;
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, pendingIntent);
How do I implement weekly alarm scheduling for custom days of the week?
private void scheduleAlarm(int dayOfWeek) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
// Check we aren't setting it in the past which would trigger it to fire instantly
if(calendar.getTimeInMillis() < System.currentTimeMillis()) {
calendar.add(Calendar.DAY_OF_YEAR, 7);
}
// Set this to whatever you were planning to do at the given time
PendingIntent yourIntent;
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, yourIntent);
}
private void setUpAlarms() {
scheduleAlarm(Calendar.MONDAY);
scheduleAlarm(Calendar.FRIDAY);
}
Attribution
Source: https://microeducate.tech/repeating-alarm-for-specific-days-of-week-android/ ,
Question Author : Dhruvil Patel(https://stackoverflow.com/users/1367157/dhruvil-patel) , Answer Author : MBH(https://stackoverflow.com/users/2296787/mbh)
i created alarm demo . In that demo i am repeating an alarm . I have one problem in my demo . My alarm called service even if time passed . I am setting 16:08:00 time and called that alarm so it called my alarm service after passed that time.Please help me to stop this criteria.
AlarmManager alarmManager = (AlarmManager)ctx.getSystemService(ctx.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 16);
calendar.set(Calendar.MINUTE, 8);
calendar.set(Calendar.SECOND, 0);
PendingIntent pi = createPendingIntent(ctx);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24*60*60*1000, pi);
CreatePendingIntent Method
private static PendingIntent createPendingIntent(Context context)
{
Intent myIntent = new Intent(context, MyAlarmService.class);
return PendingIntent.getService(context,0, myIntent, 0);
}
When setting an alarm to past time, the alarm immediately pops up.
Simply check if the current time is bigger than the alarm time. If so, add 24 hours to the alarm time and set the alarm.:
long timeToAlarm = calendar.getTimeInMillis();
if (calendar.getTimeInMillis() < System.currentTimeMillis())
{
timeToAlarm += (24*60*60*1000);
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, timeToAlarm, 24*60*60*1000, pi);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24*60*60*1000, pi);
if you used the above code the alarm repeats at the 24*60*60*1000 interval time.If you don't want to repeat the alarm then use the bellow code
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
the above code will cal the alarm only onetime.