Android SDK - Set multiple alarms with same Intent different extras - android

I'm trying to have to have 2 repeating alarms triggering same Intent but with different extras:
// first alarm # 2AM
Calendar calendar1 = Calendar.getInstance();
calendar1.set(Calendar.HOUR_OF_DAY, 2);
calendar1.set(Calendar.MINUTE, 0);
calendar1.set(Calendar.SECOND, 0);
// second alarm # 3AM
Calendar calendar2 = Calendar.getInstance();
calendar2.set(Calendar.HOUR_OF_DAY, 3);
calendar2.set(Calendar.MINUTE, 0);
calendar2.set(Calendar.SECOND, 0);
// Set both intents with differing extras
Intent intent1 = new Intent(context, Receiver.class);
intent1.putExtra("status", true);
Intent intent2 = new Intent(context, Receiver.class);
intent2.putExtra("status", false);
// Set both pending Intents with differint ids
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 1, intent1, 0);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 2, intent2, 0);
AlarmManager alarm1 = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm1.setRepeating(AlarmManager.RTC_WAKEUP, calendar1.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent1);
AlarmManager alarm2 = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm2.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent2);
And here is what is triggered by the Intent
public class Receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("MyApp", "Received intent with status : " + intent.getBooleanExtra("status", false));
}
.....
}
But for a strange reason both intents are triggered at approximately 3AM :
Received intent with status : false
Received intent with status : true
What am I doing wrong?

Problem is that AlarmManager.setRepeative is not accurate as written in the official doc.
I was starting my program at 2:50AM so with the above code, first alarm should have been started 50 minutes beforeso it needs to be triggered but since another alarm is scheduled at 31M, the Android OS decides to wait for the 3AM alarm to trigger both (to lower battery consumption I guess).
Solution is to add 24h to the alarms if needed in order to be sure they are scheduled in the future and not in the past and to use AlarmManager.setExact which is exact but not repeative. Then Reschedule a new AlarmManager.setExact every day.
I would suggest to never use AlarmManager.setRepeative if you need better accuracy than 1 hour.

Related

Alarm Manager Android

private void startAlarm() {
AlarmManager alarmMgr;
PendingIntent alarmIntent;
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 52);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, alarmIntent);
}
startAlarm() method is in the MainActivity class.
The following code should display a toast (declared in onReceive() method of the AlarmReceiver class) at 23:52 and every 20 minutes thereafter
AlarmReceiver extends BroadcastReceiver.
The code compiles without errors but for some reason it is not displaying the toast.
NOTE : The code worked fine with ELAPSED_REALTIME_WAKEUP. I am having problem with RTC_WAKEUP only. So everything else has to be correct. There is something wrong inside the startAlarm() method only.
I have tried your code with some modification as below .
private void startAlarm() {
AlarmManager alarmMgr;
PendingIntent alarmIntent;
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 2);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 20, alarmIntent);
}
This code works fine with AlarmManager.RTC_WAKEUP. If it does not work for you, please reboot your device after installing it. After reboot completed, start your app. Then it should fire the alarm and every 20 sec interval the alarm fires repeatedly.
You can also check the difference between RTC_WAKEUP and ELAPSED_REALTIME_WAKEUP. From android docs, elapsedRealtime means, Returns milliseconds since boot, including time spent in sleep and RTC means, time in System.currentTimeMillis() (wall clock time in UTC).
Looks like You need to set an action to the intent:
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
intent.setAction("YourPackageName.YourAction");
alarmIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
And in the manifest:
<receiver android:name=".AlarmReciever">
<intent-filter>
<action android:name="YourPackageName.YourAction" />
</intent-filter>
</receiver>
This should fix the issue. You must have a unique action in the intent for use it with broadcast receiver.

Alarm not able to stop

I know this is very simple and can do anyone but i m stuck in this plz help where i did mistake
one think very important i start from one.class and stop in second.class and i can do stop after 3rd or 4th day of start.
i start alarm like this
//set Alarm method
private void SetAutoCleanningService()
{
long when= System.currentTimeMillis() + 1000*20;
long repeattime =Constant.NOTIFICATION_TimeDiff;
if(Constant.IsDebug)
System.out.println("time to trigger is ="+getDate(when, "dd/MM/yyyy hh:mm:ss.SSS"));
Intent intent = new Intent(this, AutoCleaningBroadCast.class);
intent.setAction("systweak.AutoCleanningBroadCast");
PendingIntent pendingIntent = PendingIntent.getBroadcast(ApplicationSetting.this,1234567, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, when, repeattime,pendingIntent);
}
And stop like this
//close Alarm method
private void StopEarlierAlarm() {
// TODO Auto-generated method stub
AlarmManager aManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getBaseContext(), AutoCleaningBroadCast.class);
PendingIntent pIntent = PendingIntent.getBroadcast(ApplicationSetting.this, 1234567, intent,0);
aManager.cancel(pIntent);
}
i use same request code but cant able to stop and on every alarm i show one notification that will be repeat in every alarm calling
You can cancel the alarm like this:
Intent intent = new Intent(this, Mote.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1352, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Also, you should remove Intent.FILL_IN_DATA from your call to getBroadcast() in the code where you set the alarm.
Cancel your PendingIntent too.
pIntent.cancel();
Make sure context used in creating intent is same.
If not possible to use same Context, then create intent as a global Static variable and use later.
Check this, it may help you
Step 1:initialize the alarm manager.
AlarmManager alarmManager1;
Step 2:
// for Notification Process
Intent myIntent1 = new Intent(Settings.this,MyNotificationService.class);
pendingintent2 = PendingIntent.getService(SettingsPage.this, 2, myIntent1, 2);
alarmManager1 = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar1Notify = Calendar.getInstance();
calendar1Notify.setTimeInMillis(System.currentTimeMillis());
calendar1Notify.set(Calendar.HOUR_OF_DAY, 8);
calendar1Notify.set(Calendar.MINUTE, 15);
alarmManager1.set(AlarmManager.RTC_WAKEUP,calendar1Notify.getTimeInMillis(), pendingintent2);
long time24h = 24 * 60 * 60 * 1000;
alarmManager1.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar1Notify.getTimeInMillis(), time24h,pendingintent2);
Step 3-Stop alarm manager:
alarmManager1.cancel(pendingintent2);

Android set Exact Repeating Alarms WorkAround

I am trying to set repeating alarms in an exact fashion by manually setting an alarm to the next day the moment I receive it in a broadcast. However, I might be missing something and somehow its not working.
The Logic:
When I select the time from a time chooser, I set an exact alarm to the time given and start a pending intent which calls MyBroadCastReceiver.java (extends BroadcastReceiver) when its time. I then forward the intent with another pending intent to AlarmFireActivity. (AlarmFireActivity also has snooze which simply sets a pendingIntent to itself to fire after 5 mins.)
The MyBroadCastReceiver component hence only receives the actual alarms (not snoozes). And its functions are :
a) Get the non-repeating pending intent cancel it, then create another pending intent from the intent and then set it with the milliseconds set to the next day at the same time.
b) Start the AlarmFireActivity and show the alarm.
In AddAlarmActivity
Intent intent = new Intent(context, MyBroadcastReceiver.class);
intent.putExtra(DBHelper.COLUMN_ID,alarm.getId());
AlarmManager alarmManager = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, reminder.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, reminder.getHourOfDay());
calendar.set(Calendar.MINUTE, reminder.getMinuteOfHour());
calendar.set(Calendar.SECOND,0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pendingIntent);
BLog("Pending intent added at " + new SimpleDateFormat(utilFunctions.timeFormat).format(calendar.getTime()));
}
Snippet MyBroadCastReceiver.java TaskOne
Logic
Get the intent which MyBroadCastReceiver receives. Reuse the same intent in a new PendingIntent set to the next day at the same time.
Code
AlarmManager alarmManager = (AlarmManager) context.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
PendingIntent p1 = PendingIntent.getBroadcast(context, alarmCurrent.getReminderId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
if(p1!=null){
alarmManager.cancel(p1);
}
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, alarmCurrent.getReminderId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
//for test
calendar.add(Calendar.MINUTE,1);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pendingIntent1);
}
MyBroadCastReceiver.java TaskTwo
Logic
If the time when the alarm was set was after the time the alarm is due, do not forward the pending intent to the AlarmFireActivity.
Else forward it to the AlarmFireActivity which shows the screen to dismiss/snooze the alarm.
Code
Calendar timeSet = alarmCurrent.getAlarmReminderSetTime();
Calendar alarmTime = Calendar.getInstance();
if(timeSet!=null && alarmTime.getTimeInMillis() > timeSet.getTimeInMillis()){
Intent intent1 = new Intent(context, AlarmFireActivity.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent1.putExtra(DBHelper.COLUMN_ID,id);
String ext = extras.getString(DBHelper.TASK_TITLE);
if(ext!=null){
intent1.putExtra(DBHelper.TASK_TITLE,ext);
}
context.startActivity(intent1);
}else{
}
The BroadCastReceiver is doing the second task just fine. However, not the task one. Its not repeating/ resetting a new pending intent. I am guessing I must have messed up the intent/pendingIntent somewhere. I dont know which. Please help/
The solution is restart the phone. I have seen somewhere that there is a bug in a one of the os' 4.3 or so. A pending intent with a request id of 0 might fail at times. And once I restarted the phone it worked. However, there is a more standard solution which is :
Replacing
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, reminder.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
with
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, A_NUMBER_GREATER_THAN_ZERO + reminder.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
so that you are avoiding a pending intent with 0 at all times. Thanks all!

How to start a service at a specific time

Am creating an application that fetch data from webservice. I have been while(true) and sleeping the loop at a specific milliseconds.. i had like to make the service action(fetching data from webservice) to always start at a specific time.. instead on being on always and pausing by Thread.sleep(milli)... Thanks
this is what have been using
while(true)
{
///pullDataFromWebservice();
Thread.sleep(600000);
}
Use the Alarm API. It is way safer than having a sleep & poll service.
Why?
Because Android is very likely to reclaim such a long running services when resources turn low, resulting
in your delayed logic never being called!
An example for activating a callback in 1 hour from now:
private PendingIntent pIntent;
AlarmManager manager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, MyDelayedReceiver.class); <------- the receiver to be activated
pIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() +
60*60*1000, pIntent); <---------- activation interval
Try using AlarmManager - A bit battery eater though
AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, YourClass.class);
PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar cal= Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 19);
cal.set(Calendar.MINUTE, 20);
cal.set(Calendar.SECOND, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pIntent);
//RTC_WAKEUP to enable this alarm even in switched off mode.

android multiple alarm setting

I want to set a multiple alarm in android. please help me in achieving this task.
Thanks &Regards
Pawan Pathak
You probably need to use multiple intents.
In this example I set 2 alarms, one after 10 seconds and another one after 15 seconds.
Hope it helps.
// set first alarm
Calendar time1 = Calendar.getInstance();
time1.add(Calendar.SECOND, 10);
// set intent to be fired
PendingIntent sender1 = PendingIntent.getBroadcast(this, 1, new Intent(this, AlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
// set alarm manager
AlarmManager alarm1 = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm1.set(AlarmManager.RTC_WAKEUP, time1.getTimeInMillis(), sender1);
// set second alarm
Calendar time2 = Calendar.getInstance();
time2.add(Calendar.SECOND, 15);
// set intent to be fired
PendingIntent sender2 = PendingIntent.getBroadcast(this, 2, new Intent(this, AlarmReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
// set alarm manager
AlarmManager alarm2 = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm2.set(AlarmManager.RTC_WAKEUP, time2.getTimeInMillis(), sender2);

Categories

Resources