I am newbie in android programming. I like to create a widget to update network status such as signal level, operator details. Can i update these data on an interval of a second. It is possible in widget. If yes kindly provide a solution to do it.
thanks
You can't do this natively because android:updatePeriodMillis is restricted to a minimum period of 30 minutes.
You can bypass this limit by adding a service that will update your widget to the AlarmManager(which does support intervals less than 30 minutes):
final Intent _intent = new Intent(context, MyUpdateService.class);
final PendingIntent pending = PendingIntent.getService(context, 0, _intent, 0);
final AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pending);
long interval = 60000;
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),interval, pending)
Related
I need to run a task to collect some data 4 times per hour. I guess best way to do it is using AlarmManager. I managed to get following code working and it runs for every 10 sec.
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
int interval = 10000;
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
Toast.makeText(this, "Alarm Set", Toast.LENGTH_SHORT).show();
But I want my task to run 4 times per hour. Exactly at XX.00, XX.15, XX.30, XX.45. This is to generate some data graphs.
Can somebody tell me how to archive this? Should I use Calendar class? I could not find any clear method.
Thanks!
Try this:
put interval=15*60*1000 and instead of System.currentTimeMillis() put the milliseconds of XX:00.If you want this time from user then You can use using TimePicker dialog to do so.
This is a code that i'm using for running a service once a day .
the problem is this , after 24h , the service keeps calling every 10 to 15 min .
Intent myIntent = new Intent(this, MyService.class);
pendingIntent = PendingIntent.getService(this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.HOUR, 24);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 86400, pendingIntent);
I think I'm using a bad code .Could you give me a better code for runnig a service once or twice a day
thanks you
The interval parameter to setRepeating represents millis. It should be 86400000 to get it right.
You are now programming an alarm to start first execution 24h past the current time, but with a period of 86400 millis (less than two minutes).
Morale of the story:
Always read the docs before using an API.
Use AlarmManager.INTERVAL_DAY instead of your own magic numbers
I am developing an application that needs to fire an alarm after each 5 days, for that i am using setRepeating method,for example : today date is 16 so alarm should fire on 21 but for testing purpose, i changed my device date 16 to 17 and suddenly it fires alarm , however it should start alarm after 5 days, i am not able to find out what i am doing wrong. Please help me . Thanks in advance.
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
long check = 86400000; // no. of millisecond in days
int days = Integer.parseInt(strDays);
Intent intent = new Intent(getBaseContext(), AlarmReciever.class);
intent.putExtra("Item", "Time To Pick Up " + strItemName);
intent.putExtra("Id", 1);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getBaseContext(), RQS_1, intent, 0);
long time =check*2; // for 2 days
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),time,pendingIntent);
Read documentation of setRepeating
http://developer.android.com/reference/android/app/AlarmManager.html#setRepeating(int, long, long, android.app.PendingIntent)
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),time,pendingIntent);
Here System.currentTimeMillis() suggests that alarm should first go off instantaneously and then after 5 days.
triggerAtMillis time in milliseconds that the alarm should first go
off, using the appropriate clock (depending on the alarm type).
I want to set notifications/alarms everyday at specific times. Please note that these times could be different for everyday. For example I have a Database from which I get 5 different entries/times for a day e.g 6am, 1.30pm, 4.30pm, 7.30pm, 10.00 pm. I want to set an alarm for these times. For the next day these times could be different. They could be off by 2-5 minutes or more.
Basically I cannot set a recurring alarm for the same time everyday. I need to check the entry in my Database to know what time I should schedule it.
What is a good and efficient way of doing this. I looked at some stack overflow questions for setting multiple alarms. But here how do I do it? Should I just read the whole weeks database entries i.e 5 times/day for 7 days..And set around 35 alarms together? Or should I just set one alarm at a time. And when that alarm is fired just read the next entry from the Database and schedule an alarm for that time?
Write a service which will pick up the 5 values from the database everyday at a particular time.
Then add multiple entries in the AlarmManger with different unique ID.
Adding alarm at particular time:
Calendar calendar = Calendar.getInstance();
//9 AM
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(context, 0, new Intent(context, YourClass.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Setting Multiple alarm:
AlarmManager[] alarmManager=new AlarmManager[24];
intentArray = new ArrayList<PendingIntent>();
for(f=0;f<arr2.length;f++){
Intent intent = new Intent(AlarmR.this, Riciving.class);
pi=PendingIntent.getBroadcast(AlarmR.this, f,intent, 0);
alarmManager[f] = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager[f].set(AlarmManager.RTC_WAKEUP,arr2[f] ,pi);
intentArray.add(pi);
}
Hope this should work.
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)