I have created a form where user specify date and time and adds alarm. I take these date and time and creates Alarm using AlarmManager.
The problem is that as soon as I click on CreateRemainder button, Alarm is fired
I am using following method to pass date, time values to AlarmManager class.
int year= Integer.parseInt(splitDate[0]);
int month= Integer.parseInt(splitDate[1]);
int day= Integer.parseInt(splitDate[2]);
int hour= Integer.parseInt(splitTime[0]);
int minute= Integer.parseInt(splitTime[1]);
int second= 0;
Calendar cal = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
cal.set(Calendar.DATE,day); //1-31
cal.set(Calendar.MONTH,month-1); //first month is 0!!! January is zero!!!
cal.set(Calendar.YEAR,year);//year...
cal.set(Calendar.HOUR_OF_DAY, hour); //HOUR
cal.set(Calendar.MINUTE, minute); //MIN
cal.set(Calendar.SECOND, second);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
I debug this and its getting the correct values, but it starts alarm immediately.
If i change the AlarmManager time to hard codded 10 seconds time, it starts remainder after 10 seconds.
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (10 * 1000), pendingIntent);
But if i add 10 Seconds to the Calender, it still start displaying alarm instantly after setting it.
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+10000, pendingIntent);
Usually, if the alarm is being fired as soon as you set it, it means that scheduled time is behind current time... So, AlarmManager fires it imediatelly
I suggest to add debug messages to debug. Something like:
Log.d("DEBUG", "Time from device: " + Calendar.getInstance().getTimeInMillis() + " Time passed to alarm: " + cal.getTimeInMillis());
Then, you can check Current Millis website and check if both times are correct.. Check if cal is really a future date
Also, if you want to add a time to calendar, use as follows Calendar.add() method:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 10);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Use this:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC, cal.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC, cal.getTimeInMillis(), pendingIntent);
}
If your alarm is getting called instantly than my guess is your cal's date is before today.
Related
I need to set alarm in my app to specific day that has been choosen from calendar ? As I have noticed Alarm doesn't have such method. I understnad that I can do this usign calendar and setting the time amount left for this date. But for example if user changes date,what happens ?
Maybe this question is stupid,sorry, I am newbie.
By using the AlarmManager class, you should be able to do this:
http://developer.android.com/reference/android/app/AlarmManager.html
Use public void set (int type, long triggerAtTime, PendingIntent operation) to set the time to fire it.
Use void setRepeating(int type, long triggerAtTime, long interval, PendingIntent operation) to schedule a repeating alarm.
Here's how you can do this with your specified (date, hoursOfDay, minute, seconds and even millis):
AlarmManager mAlarmManager = (AlarmMAnager) Context.getSystemService(Context.ALARM_SERVICE);
Calendar mCal = Calendar.getInstance();
Calendar mCalSet = (Calendar) mCal.clone();
mCalSet.set(Calendar.HOUR_OF_DAY, hourOfDay);
mCalSet.set(Calendar.MINUTE, minute);
mCalSet.set(Calendar.SECOND, second);
mCalSet.set(Calendar.MILLISECOND, millis);
if(calSet.compareTo(calNow) <= 0){
//Today Set time passed, count to tomorrow
mCalSet.add(Calendar.DATE, 1);
}
mAlarmManager.set(AlarmManager.RTC_WAKEUP, mCalSet.getTimeInMillis(), yourOperation);
I want to set and cancel an Alarm for a particular time. I am doing the same using the TimePicker using the following code.
public void setRecurringAlarm(int randomTimer,long mills, int i){
Intent intent = new Intent(CreateAlarmActivity.this, AlarmReceiver.class);
intent.setData(Uri.parse("timer:" + i));
PendingIntent pendingIntent = PendingIntent.getBroadcast(CreateAlarmActivity.this, 1253, intent, PendingIntent.FLAG_CANCEL_CURRENT| Intent.FILL_IN_DATA);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP,mills,
pendingIntent);
Toast.makeText(CreateAlarmActivity.this, "Alarm "+i+" isSet", Toast.LENGTH_LONG).show();
}
Note:-Suppose I set the alarm for 10:00 PM. It works fine for 10:00 PM. But when I again run the same code (after 10 PM) i.e once the time has been passed on which the alarm has been set and I recall that code (to reset the alarm), it starts running immediately. Why it is so ? I am unable to get where I am a wrong.
You can check if the alarm time is before the current time or not. If so, then set the alert time for the next day (if you want to fire alarm at least once, or want to set Repeating alarm).
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, 0);
if (System.currentTimeMillis() > cal.getTimeInMillis()) {
calendar.add(Calendar.DATE, 1);
}
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
public void scheduleAlarm() {
// time at which alarm will be scheduled here alarm is scheduled at 1
// day from current time,
// we fetch the current time in milliseconds and added 1 day time
// i.e. 24*60*60*1000= 86,400,000 milliseconds in a day
// Long time = new GregorianCalendar().getTimeInMillis()+24*60*60*1000;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR_OF_DAY, 20);
cal.add(Calendar.MINUTE, 00);
cal.add(Calendar.SECOND, 00);
Intent intent = new Intent(CreateAlarmActivity.this, AlarmReceiver.class);
// create the object
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
// set the alarm for particular time
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
PendingIntent.getBroadcast(this, 1, intentAlarm,
PendingIntent.FLAG_UPDATE_CURRENT));
Toast.makeText(this, "Alarm Scheduled ", Toast.LENGTH_LONG)
.show();
}
Hope this will help you
2 things:
If you are "recalling that code" by calling setRecurringAlarm(randomTimer, mills, i) using the same value for the mills parameter, then the time for the alarm will be in the past and it will trigger immediately (if you schedule an alarm with a trigger time in the past, the alarm triggers immediately).
Please remove | Intent.FILL_IN_DATA from the call to PendingIntent.getBroadcast(). It doesn't belong there as this parameter should contain only PendingIntent flags and it may do some damage.
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 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 .
I have this code
Calendar c = new GregorianCalendar();
c.add(Calendar.DAY_OF_YEAR, 1);
c.set(Calendar.HOUR_OF_DAY, 23);
c.set(Calendar.MINUTE, 22);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
// We want the alarm to go off 30 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
firstTime += 30*1000;
long a=c.getTimeInMillis();
// Schedule the alarm!
AlarmManager am = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
c.getTimeInMillis(), 1*60*60*1000, sender);
It is not executed at 23:22h
What I am doing wrong? I noticed firstTime and c.getTimeInMillis() differs a lot in size and length. When I use firstTime, so when set to 30 seconds, the alarm is executed well.
You are using the AlarmManager.ELAPSED_REALTIME_WAKEUP flag, but you are using a Calendar object. These two things don't go together.
You need to use AlarmManager.RTC or AlarmManager.RTC_WAKEUP if you are specifying the alarm time using a Calendar or Date object (milliseconds since 1970).
You use AlarmManager.ELAPSED_REALTIME or AlarmManager.ELAPSED_REALTIME_WAKEUP when you are specifying the alarm time via SystemClock.elapsedRealtime() (milliseconds since the phone booted).
I had success with the following code, if you only want to set the alarm for the next occurance of hh:mm
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(System.currentTimeMillis());
cal.set(Calendar.HOUR_OF_DAY, 22);
cal.set(Calendar.MINUTE, 19);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
//check if we want to wake up tomorrow
if (System.currentTimeMillis() > cal.getTimeInMillis()){
cal.setTimeInMillis(cal.getTimeInMillis()+ 24*60*60*1000);// Okay, then tomorrow ...
}
To get the alarm to go off 30 seconds from now, use
Calendar cal = Calendar.getInstance();
to get the current time, and then
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis()+30000, sender);
Edit:
I think the problem is the ELAPSED_REALTIME_WAKEUP. This tells the AlarmManager that the time you are giving it is based on time since system startup. This is fine for 30 seconds from now, but if you want it to be based on real time you should use RTC, or RTC_WAKEUP. See javadoc for full explanation of those types.