Android AlarmManager send Broadcast not on time - android

I use AlarmManager to set two action on time,
First action set on 10:00:00, and second action set on 10:15:00.
I can get two action broadcast,
and get first action broadcast on 10:00:03 (is OK),
but get second action broadcast on 10:29:15,14 minutes late!
How let AlarmManager can send broadcast on time ??
Set AlarmManager code:
#Override
public void onCreate() {
setSchedule();
}
private void setSchedule(){
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar offCal = Calendar.getInstance();
offCal.set(Calendar.HOUR_OF_DAY, 10);
offCal.set(Calendar.MINUTE, 15);
offCal.set(Calendar.SECOND, 00);
Intent offIntent = new Intent(this, AlarmReceiver.class);
offIntent.setAction(AlarmReceiver.ALUM_SCREEN_OFF);
PendingIntent offPending = PendingIntent.getBroadcast(this, 1,
offIntent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC, offCal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, offPending);
Intent onIntent = new Intent(this, AlarmReceiver.class);
onIntent.setAction(AlarmReceiver.ALUM_SCREEN_ON);
Calendar onCal = Calendar.getInstance();
onCal.set(Calendar.HOUR_OF_DAY, 10);
onCal.set(Calendar.MINUTE, 00);
onCal.set(Calendar.SECOND, 00);
PendingIntent onPending = PendingIntent.getBroadcast(this, 2,
onIntent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, onCal.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, onPending);
}
Receiver code:
public class AlarmReceiver extends BroadcastReceiver {
public static final String ALUM_SCREEN_ON = "screenOn";
public static final String ALUM_SCREEN_OFF = "screenOff";
private static final String TAG = "AlarmReceiver";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d(TAG, "get braodcast action:"+intent.getAction());
}

Hi you are using setRepeating method which wont give alarm at exact time.Alarm manager will strongly discourage other apps apart from system apps to trigger alarm accurately for the better battery optimization.so if u want to trigger alarm at a particular time means you can use setExact() method This also wont give you complete gaurantee but it will give you the most accuracy one .While setting multiple alarms at a single time make sure you are giving different ids in `
PendingIntent onPending = PendingIntent.getBroadcast(this, 2,
onIntent, PendingIntent.FLAG_UPDATE_CURRENT);
here you gave 2 as id and it should be different for different alarms.

Since KitKat the set and setRepeating APIs are not exact. If you absolutely need the alarm to run at a specific time, use setExact. Consider using setWindow instead if the alarm time is not critical.
There is no setExactRepeating, so if you need that, you need to use setExact and them re-arm your alarm. But unless your are doing time critical stuff, that's not recommended.

Related

Cant get AlarmManager and broadcast working

No matter how I try, I cannot get the alarmManager and receiver to work - there seem to be SO many different ways to do it from what i've searched, but nothing seems to work.
I have in Manifest:
<receiver android:name="AlarmReceiver" />
I am using inner class for broadcastReceiver:
private class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("ALARM","TRIGGERED");
Notification(filteredList.get(0).getTitle());
}
}
I call function SetAlarm to start the manager:
private void SetAlarm(long time) {
AlarmManager alarm_mgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
//PendingIntent pi = PendingIntent.getService(MainActivity.this, 0, intent, 0);
PendingIntent pi = PendingIntent.getBroadcast(this, 111, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarm_mgr.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
Log.d("ALARMSET", "Alarm " + calendar.getTime().toString());
}
As you can see, in the receiver I have a notification call - I won't post because I know this works, but there is also a log that is not working.
For testing purposes I've set time to current time using the Calendar function.
You can see the pendingIntent, i have tried both getService and getBroadcast, I can't figure out which I need, but neither works anyway.
I'm sure I'm missing something, i don't know what, and I can't seem to find any answers at Google.
Is the AlarmReceiver ok as an inner class ? I have put it there because I need access to my "filteredList" List object.
thx
I am using inner class for broadcastReceiver:
This will not work. Android has to be able to create an instance of your BroadcastReceiver, and it cannot do so. At best, your BroadcastReceiver could be a static nested class, but then you would have to fix your manifest entry to refer to the outer class:
<receiver android:name="OuterClass$AlarmReceiver" />
No, actually the BroadcastReceiver needs to be public.Only then you can register it in manifest and access them. Place the AlarmReceiver code in a separate .java file. You will see the log inside the BroadcastReceiver.
try this
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, alarmIntent);
For more details.. Look this
I stucked 1 day for this problem, and finally solved this.
AlarmManager is used to generate a broadcast every 30 seconds, and a broadcast receiver is used to receive the message and execute ...
So the main problem is the following 2 steps
1. In the AndroidManifist.xml a action filter needed.
<receiver android:name="com.istep.gps.straight.MyTimerReceiver">
<intent-filter>
<action android:name="com.istep.gps.straight.MyTimerReceiver.Action"/>
</intent-filter>
</receiver>
2. The most important is the Intent need to be empty, no AAA.class
private void initTimer(Context context) {
Intent intent = new Intent().setAction("com.istep.gps.straight.MyTimerReceiver.Action")
.putExtra("id",UniqueID.getID(context));
PendingIntent sender = PendingIntent.getBroadcast(context, 18, intent, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 30, sender);
}
When you use calendar, you should setTimeInMillis
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());

Android, how to set alarm service to the predefined date time and run notification

I would like to add into my application background service which takes given datetime and ID pointing to the table row with additional informations and in given time displays status Bar notification.
Could somebody give me a simple example how can I do it?
Many Thanks for any advice.
Have you looked at using AlarmManager to schedule whatever process you wanted to do? (https://developer.android.com/training/scheduling/alarms.html)
UPDATE: pass parameter to the intent
For example (copied):
// create Intent
PendingIntent alarmIntent;
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("ID", "ABX1000"); // your ID
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
And in your receiver, get the intent....
#Override
public void onReceive(Context context, Intent intent) {
// Implement code here to be performed when
// broadcast is detected
String myID= intent.getStringExtra("ID");
}
You can trigger a notification or intent using pending intent.
example is here

Create alarm service in android for multiple times

in my task application, i want to create alarm service for multiple items. Here is the code i followed to create service. Lets assume, if there are more than 5 items present in list. then we will sent alarm service for 5 different times.
What if the user comes and edits the time?, how to update the system and make sure it triggers at new instance?. What if the user delete the task, how to quickly removes the registered alram for the deleted task?
What about uninstalling the app?, how to clear all the entries?, what if the system re-boots?
This is the code i'm following to register the task in alram services
Calendar Calendar_Object = Calendar.getInstance();
Calendar_Object.set(Calendar.MONTH, 8);
Calendar_Object.set(Calendar.YEAR, 2012);
Calendar_Object.set(Calendar.DAY_OF_MONTH, 6);
Calendar_Object.set(Calendar.HOUR_OF_DAY, 14);
Calendar_Object.set(Calendar.MINUTE, 25);
Calendar_Object.set(Calendar.SECOND, 0);
Step 2:
We need to create an alarm which help us to invoke the BroadCastReceiver on our specified time.
// MyView is my current Activity, and AlarmReceiver is the BoradCastReceiver
Intent myIntent = new Intent(MyView.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MyView.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
/*
The following sets the Alarm in the specific time by getting the long value of the alarm date time which is in calendar object by calling the getTimeInMillis(). Since Alarm supports only long value , we're using this method.
*/
alarmManager.set(AlarmManager.RTC, Calendar_Object.getTimeInMillis(),
pendingIntent);
Use this method to set Alarm :
public static void startAlarm(Context context, int alarm_code, String time) {
String[] arrTime = time.split(":");
intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("CODE", alarm_code);
PendingIntent mAlarmSender = PendingIntent.getBroadcast(context,
alarm_code, intent, 0);
Calendar cal_alarm = Calendar.getInstance();
cal_alarm.setTimeZone(TimeZone.getDefault());
cal_alarm.set(Calendar.HOUR_OF_DAY, Integer.parseInt(arrTime[0]));
cal_alarm.set(Calendar.MINUTE, Integer.parseInt(arrTime[1]));
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal_alarm.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, mAlarmSender);
}
Here,"int alarm_code" is your unique code for particular item.
And for update alarm first cancel the existing alarm and set new alarm for new time.For that use this method :
public static void cancelAlarm(Context context, int alarm_code) {
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra("CODE", alarm_code);
am.cancel(PendingIntent.getBroadcast(context, alarm_code, intent, 0));
}
Here,"int alarm_code" will be your unique code which you have used to set alarm.So that alarm with particular alarm_id will be cancel.You can also delete alarm with this method.
Same way you can clear all the alarms passing alarm_code to the given function.
You have to register receiver for system reboot and in onReceive of register you have to set all alarms again.
Hope this will help you.

In android, is it possible to use more than one AlarmManager with different repeat values in a single application?

I'm developing an application for mobile and tablet using android 2.3**
I want to do some operations namely Operation-A and Operation-B. Both perform some pocess.
I want to repeat the Operation-A and Operation-B is performed every 1 hour time interval
Operation-A is performed before the 10 minutes of Operation-B
Operation-B is performed when the time is 0.00,1.00,2.00,3.00,....,23.00 (I'm using railway time. So it is not confused for am or pm).
Operation-A is performed when the time is 0.50,1.50,2.50,3.50,....,23.50
The above scenarios is possible in android or not.
All are give your ideas for the above scenarios.
I'm planning to use AlarmManager. AlarmManager is android system service. It is used to notify the application every 1 hour.
I plan to use an AlarmManager for Operation-A and another AlarmManager for Operation-B.
My doubt is ,In android is it possible to use more than one AlarmManager with different repeat values in a single application?
All your ideas are welcome.
Yes this task will done with help of AlarmManager with reperating functionality. First you need to create two receiver class which will receive events . and then need to setup repeating alarm .
private void setAlarm1()
{
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.HOUR, 1);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000*60*60, pendingIntent);
}
private void setAlarm2()
{
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 50);
Intent intent = new Intent(this, AlarmReceiver_1.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000*60*50, pendingIntent);
}
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
public class AlarmReceiver_1 extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
In menifest, you need to declare the classes as below.
<receiver android:name=".AlarmReceiver" />
<receiver android:name=".AlarmReceiver_1" />

My Recurring Task doesn't get called

I am trying to use AlarmManager to accomplish a recurring task. I am using setInexactRepeating() and have set the interval to every 15 minutes (just for testing purposes) however, it doesn't seem to be working. Any ideas?
Here's my code:
AlarmReceiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.w("CacheCrusader", "Recurring Job: Clearing Cache");
}
}
Setter
private void setRecurringAlarm(Context context) {
Calendar updateTime = Calendar.getInstance();
updateTime.set(Calendar.HOUR_OF_DAY, 20);
updateTime.set(Calendar.MINUTE, 15);
Intent downloader = new Intent(context, AlarmReceiver.class);
PendingIntent recurringDownload = PendingIntent.getBroadcast(context,
0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarms = (AlarmManager) getSystemService(
Context.ALARM_SERVICE);
alarms.setInexactRepeating(AlarmManager.RTC_WAKEUP,
updateTime.getTimeInMillis(),
AlarmManager.INTERVAL_FIFTEEN_MINUTES, recurringDownload);
}
Code that Sets the Setter
Context context = getApplicationContext();
setRecurringAlarm(context);
Android Manifest Declaration
<receiver android:name=".receiver.AlarmReceiver"></receiver>
No errors are generated in the logcat... the alarm just never fires.
Well, it's inexact so... If you set it the interval to 15 mins, you have to wait for at least half an hour to be sure it has/has not fired. After the starting time you have set (20:15). Try it out with something like 1 min interval for testing. And, if you need a more reliable schedule, use setRepeating(), or possibly set() where each alarm invocation registers the next one.

Categories

Resources