I am using alarm to start service at every 15 days once. Alarm is initiated at the first time of installation. Every 15 days once alarm trigger that service properly, but At the time of initiating alarm the service started.I dont want to start the service at the time of installation. how to stop this.
I dont whether i am using wrong format?
Note: Apart from this condition, I am not start service anywhere.
Intent intent = new Intent(context, InitiateService.class);
PendingIntent pIntent = PendingIntent.getService(context, 12345, intent, PendingIntent.FLAG_CANCEL_CURRENT);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 15 * AlarmManager.INTERVAL_DAY, pIntent);
this what i used in manifest file.
<service android:name=".service.InitiateService" />
this is my code of initiating alarm for starting service at every 15days once.
Guys If any one found any wrong in my question, Apologies me and Please correct those mistakes and answer me.
it is because you used System.currentTimeMillis()
try this
System.currentTimeMillis()*(15 * AlarmManager.INTERVAL_DAY)
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()*(15 * AlarmManager.INTERVAL_DAY), 15 * AlarmManager.INTERVAL_DAY, pIntent);
#Mehul Gajjar is correct about System.currentTimeMillis()
so you might wanna replace
System.currentTimeMillis()
with
(15 * 24 * 60 * 60 * 1000 * System.currentTimeMillis())
Explanation :
System.currentTimeMillis() will set Alarm to current time, so your service will start straight away. setting Alarm after 15 days will solve your problem.
15 * 24 * 60 * 60 * 1000 will be equals to 15 days. multiplying it with current time-miles will give you current time after 15 days.
in-short your code would be like
alarm.setRepeating(AlarmManager.RTC_WAKEUP, (15 * 24 * 60 * 60 * 1000 * System.currentTimeMillis()), 15 * AlarmManager.INTERVAL_DAY, pIntent);
I hope this will help you.
Related
I'm creating an alarm using AlarmManager, it works great, but I'd like to test the .setRepeating method, which I setup like this:
Calendar calMon = Calendar.getInstance();
calMon.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calMon.set(Calendar.HOUR_OF_DAY, tPicker.getCurrentHour());
calMon.set(Calendar.MINUTE, tPicker.getCurrentMinute());
calMon.set(Calendar.SECOND, 0);
calMon.set(Calendar.MILLISECOND, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calMon.getTimeInMillis(), 24 * 60 * 60 * 1000, newIntent(this, Calendar.MONDAY));
public static PendingIntent newIntent(Context context, int dayId){
Intent intent = new Intent();
intent.setAction("myApp.intent.action.CLOCK");
return PendingIntent.getBroadcast(context, dayId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Let's say the alarm it setup to repeat every monday at 2pm, the first alarm on monday starts correctly, if I want to test the next week alarm, I go to settings and move the date to the next monday and the time at 1:58pm, to see if it works when it reaches 2pm, however, right after I change the settings, the alarm starts before 2pm.
I'd like to know if there's a more accurate way to test the .setRepeating or if there's something in my configuration that is not working. Thank you!
EDIT:
Thanks to the comments provided, I got it work by adding 7 in the calculation, so I was able to test the alarm by modifying the date and time in the phone in one week:
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calMon.getTimeInMillis(), 7 * 24 * 60 * 60 * 1000, newIntent(this, Calendar.MONDAY));
Thank you!
Im trying to set and run an alarm that run every hour, and is set by a few variables so as it will not run instantly, if the time is greater then the 58th minute
The idea is to set it # X hour and 58 minute, so it will run every hour, at the given minute(58).
Calendar calCurrent = Calendar.getInstance();
int time = 58 ;
Calendar calx = Calendar.getInstance();
calx.set(Calendar.MINUTE, time);
calx.set(Calendar.SECOND, 5);
if (calCurrent.get(Calendar.MINUTE) > time) {
calx.add(Calendar.HOUR, +1);
}
System.out.println("Alarm is set to - " + calx.get(Calendar.HOUR)+":"+
calx.get(Calendar.MINUTE));
alarmSwap = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmSwap.setRepeating(AlarmManager.RTC_WAKEUP,
calx.getTimeInMillis(), 60 * 60 * 1000, pintent);
The code works and runs correctly for the 1st instance, then the alarm will for some reason run # 0 minute the following hour.
Timeline looks like
1:23 - Repeating Alarm Set for 1:58 (1 hour intervals)
1:58 - alarm is triggered
3:00 - alarm is triggered
I have no idea why this alarm is being triggered # :00 for the last alarm. It is not being called from anywhere else.
Any help is greatly appreciated.
All alarms are resetting after the hour clocks over the hour-
Calendar calnew = Calendar.getInstance(); calnew.add(Calendar.SECOND, +5);
alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, calnew.getTimeInMillis(),900000 , pintent);
Timeline-
1:20 triggered
1:35 triggered
1:50 triggered
2:00 triggered
2:15 triggered
2:30 triggered
From android documentation.
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.
repeating alarms are not exact after API 19. This improves androids performance as android groups alarms which are at close interval and wakes system once and finishes all alarms(from other applications also).
If you really want exact alarms the you will have to set normal one time alarm, and then set alarm again in first alarm's call.
Try this code to repeat alarm every hour
alarmSwap.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
calx.getTimeInMillis(),
AlarmManager.INTERVAL_HOUR, pintent);
Hope this will help.You can ask if you have any further queries.
This worked for me to trigger alarm after every 1hour
alarmmgr = (AlarmManager) getSystemService(ALARM_SERVICE);
long interval = 60 * 60 * 1000; // 1 hour
xassert alarmmgr != null;
alarmmgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
I'm using an AlarmManager with an interval of 5 minutes, and I have made some tests for a few days and it seems that the interval of the AlarmManager isn't constant all the time, but it changes some times. This is causing my app not to work as it sould.
Why is this happening? Is there a solution?
The code I am using is:
iHeartBeatService = new Intent(SpyMe.context, HeartBeat.class);
piHeartBeatService = PendingIntent.getService(SpyMe.context, 101010, iHeartBeatService, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 5 * 60 * 1000, piHeartBeatService);
on a Samsung Galaxy 3 I5800 with Android 2.2
You need to post your code for us to help you. I'm going to shoot in the dark here and guess that you're not using RTC_WAKEUP for your alarm.
alarm.set(AlarmManager.RTC_WAKEUP, calander.getTimeInMillis(), pendingIntent);
How to setup service to something (api request) everyday at particular time.
I dont know.
Right now I thing about two options:
1. Setup timer and every hour check the time and if it right, do a request.
2. setup the alarm, by alarmManager, but I dont know how to do it.
Another imported thing is the request must be a little random.
About 3-10 minutes, to prevent blocking the server by too many
request at the same time.
Take a look at this tutorial for scheduling events with an AlarmManager.
For the interval of 3-10 minutes you could just add something like
int rand = (int) (Math.random() * 1000 * 60 * 7 + 3 * 60 * 1000);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis() + rand, sender);
Can someone explain to me the difference between AlarmManager.RTC_WAKEUP and AlarmManager.ELAPSED_REALTIME_WAKEUP? I have read the documentation but still don't really understand the implication of using one over the other.
Example code:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
scheduledAlarmTime,
pendingIntent);
alarmManager.set(AlarmManager.RTC_WAKEUP,
scheduledAlarmTime,
pendingIntent);
How different will the two lines of code execute? When will those two lines of code execute relative to each other?
I appreciate your help.
AlarmManager.ELAPSED_REALTIME_WAKEUP type is used to trigger the alarm since boot time:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 600000, pendingIntent);
will actually make the alarm go off 10 min after the device boots.
There is a timer that starts running when the device boots up to measure the uptime of the device and this is the type that triggers your alarm according to the uptime of the device.
Whereas, AlarmManager.RTC_WAKEUP will trigger the alarm according to the time of the clock. For example if you do:
long thirtySecondsFromNow = System.currentTimeMillis() + 30 * 1000;
alarmManager.set(AlarmManager.RTC_WAKEUP, thirtySecondsFromNow , pendingIntent);
this, on the other hand, will trigger the alarm 30 seconds from now.
AlarmManager.ELAPSED_REALTIME_WAKEUP type is rarely used compared to AlarmManager.RTC_WAKEUP.
Despite the currently accepted and up-voted answer, AlarmManager.ELAPSED_REALTIME* types along with SystemClock.elapsedRealtime() has always been more reliable than the RTC clocks for alarms and timing.
Using ELAPSED_REALTIME_WAKEUP with AlarmManager will rely on a monotonic clock starting from boot time "and continues to tick even when the CPU is in power saving modes, so is the recommend basis for general purpose interval timing". So,
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()
+ 60*1000, pendingIntent);
will make your PendingIntent fire in 1 min (60*1000 milliseconds).
Whereas, AlarmManager.RTC_WAKEUP is for the the standard "wall" time in milliseconds since the epoch. So,
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ 60*10000, pendingIntent);
may also trigger the alarm 60 seconds from now, but not reliably, because as noted in the SystemClock documentation:
The wall clock can be set by the user or the phone network (see
setCurrentTimeMillis(long)), so the time may jump backwards or
forwards unpredictably. This clock should only be used when
correspondence with real-world dates and times is important, such as
in a calendar or alarm clock application. Interval or elapsed time
measurements should use a different clock. If you are using
System.currentTimeMillis(), consider listening to the
ACTION_TIME_TICK, ACTION_TIME_CHANGED and ACTION_TIMEZONE_CHANGED
Intent broadcasts to find out when the time changes.
Also, the question only referenced only the *_WAKEUP alarms but see also the AlarmManager documentation on that to make sure you understand what the wakeup vs non-wakeup alarms provide.
Just a note. You can get the uptime millis calling:
long uptimeMillis = SystemClock.elapsedRealtime();
So if you want to fire the alarm 30 seconds from now, and you want to use the uptime clock instead of the normal clock, you can do:
long thirtySecondsFromNow = SystemClock.elapsedRealtime() + 30 * 1000;
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, thirtySecondsFromNow, pendingIntent);
Whenever you want to check for some elapsed time instead of a specific date/time, it's best to use the uptime. That's because the current time set by the user in the device can change if the user changes it using the settings.
I programmed this problem in my own project this way. in below code i am using
AlarmManager.ELAPSED_REALTIME_WAKEUP
to set alarm at a specific time.
the variable 'intentName' is used in the intentFilter to receiver this alarm. because i am firing many alarms of this type. when i cancel all alarms. i use the method cancel. given at bottom.
//to hold alarms and cancel when needed
public static ArrayList<String> alarmIntens = new ArrayList<String>();
//
public static String setAlarm(int hour, int minutes, long repeatInterval,
final Context c) {
/*
* to use elapsed realTime monotonic clock, and fire alarm at a specific time
* we need to know the span between current time and the time of alarm.
* then we can add this span to 'elapsedRealTime' to fire the alarm at that time
* this way we can get alarms even when device is in sleep mood
*/
Time nowTime = new Time();
nowTime.setToNow();
Time startTime = new Time(nowTime);
startTime.hour = hour;
startTime.minute = minutes;
//get the span from current time to alarm time 'startTime'
long spanToStart = TimeUtils.spanInMillis(nowTime, startTime);
//
intentName = "AlarmBroadcast_" + nowTime.toString();
Intent intent = new Intent(intentName);
alarmIntens.add(intentName);
PendingIntent pi = PendingIntent.getBroadcast(c, alarms++, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
//
AlarmManager am = (AlarmManager) c
.getSystemService(Context.ALARM_SERVICE);
//adding span to elapsedRealTime
long elapsedRealTime = SystemClock.elapsedRealtime();
Time t1 = new Time();
t1.set(elapsedRealTime);
t1.second=0;//cut inexact timings, seconds etc
elapsedRealTime = t1.toMillis(true);
if (!(repeatInterval == -1))
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
elapsedRealTime + spanToStart, repeatInterval, pi);
else
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, elapsedRealTime
+ spanToStart, pi);
where span function is this:
public static long spanInMillis(Time startTime, Time endTime) {
long diff = endTime.toMillis(true) - startTime.toMillis(true);
if (diff >= 0)
return diff;
else
return AlarmManager.INTERVAL_DAY - Math.abs(diff);
}
alarm cancel function is this.
public static void cancel(Context c) {
AlarmManager am = (AlarmManager) c
.getSystemService(Context.ALARM_SERVICE);
// cancel all alarms
for (Iterator<String> iterator = alarmIntens.iterator(); iterator
.hasNext();) {
String intentName = (String) iterator.next();
// cancel
Intent intent = new Intent(intentName);
PendingIntent pi = PendingIntent.getBroadcast(c, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.cancel(pi);
//
iterator.remove();
}
}
Some important notes when choosing which alarm to use:(for whom who already read the upvoted votes)
The RTC_WAKEUP death valley - time change:
If the user has manually change time to the past the alarm won't go off, and future will cause the alarm to go off immediately if it past the RTC timestamp. Do not use this alarm to do any client side verification / important jobs because it have a chance to fail.
The WAKEUP meaning (Marshmallow and above)
In general - not much. Will not wakeup the device when idle or while in doze, for that alarmManager.setExactAndAllowWhileIdle or alarmManager.setAndAllowWhileIdle (Doze & Idle)