How to Create a Distinct PendingIntents - android

I have an app that allows a user to create a reminder to alert them in the future. The issue I am running into, is that as a user creates more than one reminder, the pending intent only triggers on the latest one created, with the earliest reminder content to display, ie:
Task 1, set for 4pm
Task 2, set for 5pm
Task 3, set for 6pm
No reminder will appear until 6pm, which will display Task 1.
I believe it has to due with the lack of uniqueness of the PendingIntent:
public class ReminderManager {
private Context mContext;
private AlarmManager mAlarmManager;
public ReminderManager(Context context) {
mContext = context;
mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
}
public void setReminder(Long taskId, Calendar when) {
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
}
}
How can I ensure that each reminder is unique and gets its correct time on time?

You need to provide something other than 0 for the requestCode param. Try making it a unique ID for each request.

Related

How to cancel ongoing alarm in Android

I'm making an application in which I want to cancel an alarm(not set by my application) after few seconds.
What is the way to cancel alarm which may be set by any other application?
What I have is, notification posted on Android Notification Center when alarm triggers.
I read from android documentation that I need PendingIntent to cancel the triggered alarm. But how can I get PendingIntent in this case?
I noticed that I can get contentIntent from alarm notification,posted to the Android Notification Center. I tried to cancel alarm from this PendingIntent but did not succeed.
Any way to get PendingIntent of triggered alarm? Or/And to cancel alarm?
This trick is a little bit old, but it saves many developers.
Suppose in ActivityOne we start an AlarmManager like:
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnServiceReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 5290, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 60000, LOCAL_SERVICE_PERIOD, pi);
To cancel this AlarmManager in any other Activity/Broadcastreceiver/Service we have to remember some of its informations.
1: Context: The context used by the AlarmManager followed by its PendingIntent.
2: PendingIntent ID: getBroadcast(context, 5290, i, 0); .It makes the Pi unique which is mostly important.
So we have to save the PendingIntent id in a SharedPreference to confirm at the time of canceling.
Now the Context used by AlarmManager .
In same Activity( ActivityOne) we have to create a global Context which holds the original one. like:
//Define it globaly in ActivityOne
private static Context mContext;
//create a public static method which holds the current context and share
public static Context getActivityOneContext() {
return ActivityOne.mContext;
}
//initialize it by assigning application context in onCreate() method
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.xxx);
mContext = getApplicationContext();
//Or if this is a BroadCastReceiver ..use the current context and do same in onReceive()
//OnBootReceiver.mContext = context.getApplicationContext();
Now you can cancel the AlarmManager anywhere of the application..
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent stopIntent = new Intent(ActivityOne.getActivityOneContext, OnServiceReceiver.class);
PendingIntent stopPI = PendingIntent.getBroadcast(ActivityOne.getActivityOneContext, 5290, stopIntent, 0);
mgr.cancel(stopPI);

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.

Cancel an AlarmManager pendingIntent in another pendingintent

I want cancel AlarmManager which define a service,in this service might start a new AlarmManger or cancel alarm that defined before.And I know the params pendingintent in alarmManager.cancel(PendingIntent),must be the same.compare with filterEquals(Intent other)
but It still not work.cancel failed.
here is my code
public class GetRoundStroe {
private Store[] stores;
private Context mContext;
public GetRoundStroe(Context mContext) {
this.mContext = mContext;
}
public Store[] getStores() {
if (ComCommand.haveInternet(mContext)) {
start_am_normal();
} else {
start_am_silence();
}
return stores;
}
public Store[] start_am_silence() {
long firstTime = SystemClock.elapsedRealtime();
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
if (AlarmHolder.mAlarmNormal != null) {
am.cancel(AlarmHolder.mAlarmNormal);
}
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, TestSwitch.getInstance().getSilence_time(), AlarmHolder.mAlarmSilence);
return null;
}
public Store[] start_am_normal() {
long firstTime = SystemClock.elapsedRealtime();
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
if (AlarmHolder.mAlarmSilence != null) {
MyLog.e(GetRoundStroe.class,"AlarmHolder.mAlarmSilence"+AlarmHolder.mAlarmSilence+"");
am.cancel(AlarmHolder.mAlarmSilence);
}
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, TestSwitch.getInstance().getNormal_time(), AlarmHolder.mAlarmNormal);
return null;
}
private static final class AlarmHolder {
static final PendingIntent mAlarmSilence = PendingIntent.getService(ApplicationContext.getInstance(),
0,
new Intent(ApplicationContext.getInstance(), GetRoundSilenceService.class),
0);
static final PendingIntent mAlarmNormal = PendingIntent.getService(ApplicationContext.getInstance(),
0, new
Intent(ApplicationContext.getInstance(), GetRoundNormalService.class),
0);
}
}
GetRoundSilenceService and GerRoundNormalService invoke start_am_normal() or start_am_silence; Anyone could help me? thanks
myIntent = new Intent(SetActivity.this, AlarmActivity.class);
pendingIntent = PendingIntent.getActivity(CellManageAddShowActivity.this,
id, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
pendingIntent.cancel();
alarmManager.cancel(pendingIntent);
These lines of code surely can help you remove/cancel the pending intent and alarm.
The main thing that you will need is:
Create pending intent with the same id and appropriate intent FLAG.
Cancel that pending intent.
Cancel the alarm using alarm manager.
#MKJParekh answer is correct, however I would like to add more information so that we all know what will work and what will not.
Lets say on activityA you create and set the AlarmManager to open activityC in 30 seconds, then on some other activity which can be any, we want to cancel that AlarmManager. Thus, we would do the following;
in activityA we create and set the AlarmManager;
//activityA
Intent myIntentA = new Intent(actvityA.this, activityB.class)
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent myPendingIntent = PendingIntent.getActivity(activityA.this, 0, myIntentA, PendingIntent.FLAG_ONE_SHOT);
//Calendar with the time we want to fire the Alarm
Calendar calendar = Calendar.getInstance(); // Get Current Time
calendar.add(Calendar.SECOND,30); //Fire Alarm in 30 seconds from Now.
((AlarmManager)getSystemService(ALARM_SERVICE)).setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), myPendingIntent);
in Another Activity some time later we want to cancel such AlarmManager created in activityA which we have no access to. Lets call this current activity activityZ;
//activityZ
Intent myIntentZ = new Intent(activityZ.this, activityB.class);
PendingIntent pendingIntentZ = PendingIntent.getActivity(activityZ.this, 0, myIntentZ, PendingIntent.FLAG_ONE_SHOT);
((AlarmManager)getSystemService(ALARM_SERVICE)).cancel(pendingIntentZ);
Some important points,
The context we provide in activityA in new Intent(context) and getActivity(context) are the same, however they do not have to match the activity from where we are canceling the AlarmManager, in this case activityZ has another context.
The class we want to open with the AlarmManager has to be the same in both activities new Intent (context, activityB.class), the requestCode which is an int must be the same, I used 0 for this example. Finally the flag has to be the same in both activities PendingIntent.FLAG_ONE_SHOT.
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); was used because PendingIntent.getActivity requires it if we are starting an activity outside of a context of an existing activity.

Multiple alarm in android

I am having a reminder application in which i have an alarm manager like this
public class ReminderManager {
private Context mContext;
private AlarmManager mAlarmManager;
public ReminderManager(Context context) {
mContext = context;
mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
}
public void setReminder(Long taskId, Calendar when) {
System.out.println("**********************************remindedrmanager************************" );
Intent i = new Intent(mContext, OnAlarmReceiver.class);
i.putExtra(RemindersDbAdapter.KEY_ROWID, (long)taskId);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
}
}
I am getting only one alram even if I set multiple alarm. Is the problem due to some mistake in the above code or is it because of some other mistake.
You have change argument no 2 in line where you declared pending Intent as per below code. Instead specify (int)System.currentTimeMillis() in place of 0
And also android set multiple alarms simultaneosuly
PendingIntent pi = PendingIntent.getBroadcast(mContext,(int)System.currentTimeMillis(), i, PendingIntent.FLAG_UPDATE_CURRENT);

How to cancel an alarm in android?

I am trying to cancel all alarms other an intent
i am sending stuff in using
new gofile(this).setSilent(mRowId, mCalendar);
that then goes to gofile
public class gofile {
private Context goon
private AlarmManager alarm;
public gofile(Context goon){
mContext = context;
alarm = (AlarmManager)goon.getSystemService(Context.ALARM_SERVICE);
}
public void setSilent(Long Id, Calendar when){
Intent i = new Intent(gon, anohterclass.class);
PendingIntent go = PendingIntent.getBroadcast(goon, 0 , i, PendingIntent.FLAG_ONE_SHOT);
alarm.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), go);
how would i cancel the alarms from another file?
You must use the cancel method, and you must make sure the PendingIntent contains the information than the one you used to set the alarm.

Categories

Resources