I want to cancel an alarm created from other activity in Android - android

I have the problem removing the alarm which I already set. I used two activities to "ADD" or "EDIT" alarms. When I delete an alarm, I want to use the activity which is made to show list of alarms. However, It doesn't delete the PendingIntent I set.
Here's the part of my source code in List Activity.
private void removeAlarm(int number)
{
final int alarmCode = AlarmCodeCreator.CreateNum(1, clickedPosition, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(ListMainActivity.this,
PushMainActivity.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), alarmCode, intent, 0);
alarmManager.cancel(pendingIntent);
System.out.println(alarmCode);
}

You should use the PendingIntent.FLAG_UPDATE_CURRENT flag and make sure to create the PendingIntent the same way it was originally created.
Same answer here.

Related

AlarmManager can't cancel an alarm

Let's see if someone found this problem and can help me to solve the mistery. I have the following situation. The app is a simple to-do list:
public class NewToDo extends Activity {
private PendingIntent pendingIntent;
private AlarmManager manager;
...
When the user creates a to-do with a notification, I create it in one of the methods of this class like this:
int interval = 30000;
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
/*Let's let the putExtras apart, as documentation says they're not considered when comparing intents, but I add some of them*/
manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast(getBaseContext(), _id, alarmIntent, alarmIntent.FILL_IN_DATA);
/*Printing _id we see 3, for instance, but is a unique identifier to associate the notification with this to-do item*/
/*I use the flag alarmIntent.FILL_IN_DATA because I want to send extras to create a custom notification*/
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + interval, interval,
pendingIntent);
I quit from the app (but no difference if I don't quit).Then the notification arrives correctly each 30 seconds, and selecting it the app launchs on the detailed view of the item. An actionbar button allows editting it, calling again the same class, NewToDo.
While editting I can cancel the notifications associated with the to-do, and my code makes that like this -in the NewToDo class-:
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent i = new Intent(this, AlarmReceiver.class); //creating a matching Intent
Log.v(getString(R.string.app_name), "_id: " + _id); //the 3 aforementioned
PendingIntent displayIntent = PendingIntent.getActivity(getBaseContext(), _id, i, alarmIntent.FILL_IN_DATA);
alarmManager.cancel(displayIntent);
But the notifications keeps appearing each 30 seconds, so they're not cancelled.
I saw the following suggestion in another post:
"Intent intentYouWantToCancel = new Intent(this, AlarmReceive.class);
intentYouWantToCancel.setAction("aRelevantString");
when you set the alarmmanager as well as when you want to delete it. "
So I put in both intents as 'aRelevantString' a cast to String of the unique identifier. But same problem.
Also changed the getBaseContext() for this, just in case, but no difference.
No errors, just the notifications keep repeating ignoring my cancel. Any idea?
PS: I restart the AVD each time I run it. I realised that the way I was using the print of the filterEquals had no sense at all (too many hours with this), but that doesn't affect the rest of the question.
I finally solved it like this. To create the alarm:
public class NewToDo extends Activity {
private PendingIntent pendingIntent;
private AlarmManager manager;
...
int interval = 30000;
manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(this, AlarmReceiver.class);
alarmIntent.putExtra("id", _id);
pendingIntent = PendingIntent.getBroadcast(this, _id, alarmIntent,0);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + interval, interval,
pendingIntent);
To cancel that concrete alarm:
manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(getBaseContext(), AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getApplicationContext(), _id, i, 0);
manager.cancel(pendingIntent);
pendingIntent.cancel();

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);

Canceling AlarmManager event with cancel

The PendingIntent cancel() API doc says:
Cancel a currently active PendingIntent. Only the original application owning a PendingIntent can cancel it.
I not sure about the meaning of this. If I set the AlarmManager event from activity x like this:
PendingIntent pendingIntent;
Intent myIntent = new Intent(x.this, AlarmReciever.class);
myIntent.putExtra("task_uuid", task_uuid);
pendingIntent = PendingIntent.getBroadcast(x.this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, dateTime.getTimeInMillis(), pendingIntent);
My question is: can I cancel the pending intent from activity y using:
PendingIntent pendingIntent;
Intent myIntent = new Intent(y.this, AlarmReciever.class);
myIntent.putExtra("task_uuid", task_uuid);
pendingIntent = PendingIntent.getBroadcast(y.this, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
When you set alarm you need to pass one key value in PendingIntent it will differentiate no of alarms, should be like this
pendingIntent = PendingIntent.getBroadcast(x.this, key_value, myIntent,0);
SharedPreferences settings = context.getSharedPreferences("alarm", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean(key, false);
editor.commit();
to cancel same alarm you need to save that key_values some where, you can use Shared preferences. get the same key and then cancel alarm like this
SharedPreferences settings = context.getSharedPreferences("alarm", 0);
Map<String,?> allNotifyIdsMap = settings.getAll();
if(allNotifyIdsMap!=null&&allNotifyIdsMap.isEmpty()==false)
{
for(String notifyId: allNotifyIdsMap.keySet())
{
boolean isCleared = settings.getBoolean(notifyId, false);
if(isCleared==false)
{
pendingIntent = PendingIntent.getBroadcast(y.this, key_value, myIntent,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
}
}
Brief Overview
AlarmManager basically schedules a time based operation by invoking the PendingIntent at the scheduled time. So inorder to cancel the Scheduled Alarm you need access to that PendingIntent.
Always note the two parameters while creating a Pending Intent- Request Code and Flag
PendingIntent.getBroadcast(context,REQUEST_CODE,intent, PendingIntent.FLAG_UPDATE_CURRENT);
Request Code - Acts as the unique identifier
Flag - Defines the behavior of PendingIntent
This brief overview is not enough to understand AlarmManager. Read more about working of AlarmManager and PendingIntent here
Solution
You can cancel the scheduled Alarm from anywhere inside your Application even if dont have access to the same PendingIntent object used while scheduling the Alarm. You can create a new pending intent with the same request code and FLAG_NO_CREATE and it will return the same PendingIntent object.
/*
With FLAG_NO_CREATE it will return null if the PendingIntent doesnt already
exist. If it already exists it returns
reference to the existing PendingIntent
*/
PendingIntent pendingIntent=PendingIntent.getBroadcast(this,REQUEST_CODE,intent,PendingIntent.FLAG_NO_CREATE);
if (pendingIntent!=null)
alarmManager.cancel(pendingIntent);

Why wont this work android canceling Alarm?

This is what sets the alarm
public void setSilent(Long taskId, Calendar when){
Intent i = new Intent(mContext, SilentReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 1 , i, PendingIntent.FLAG_ONE_SHOT);
mAlarmManager.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pi);
It takes in an id and date to use with the intent.
I am canceling it in another file when the user clicks delete. using
Intent i = new Intent(null, SilentReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(null, 1 , i, PendingIntent.FLAG_ONE_SHOT);
should this work because it has the same request code as the first one or am I doing something wrong?
You have to save a reference to your first PendingIntent. This way you can use:
mAlarmManager.cancel(pi);
And the alarm should be cancelled.
This answer has been repeated many times. Please search before asking.
Be careful to send a PendingIntent to stop the alarm with the same data than the Intent to create the alarm: problem with cancel the alarm manager pending intent

Starting service with an initial value

I am trying to get a reminder/alarm Service` working in my note/todo app. I am able to set a reminder for a particular item and the alarm triggers and displays a notification successfully.
My problem is how can my Service know which note/todo item set that particular reminder. I'd like for the user to be able to click on the notificaiton in the status bar and have the item which trigger it come up. But I have no way of passing that information to the Service as they don't accept Bundles from the PendingIntent.
I currently set the alarm with the following:
private void createAlarm() {
Intent i = new Intent(this, AlarmService.class);
PendingIntent sender = PendingIntent.getService(this, 0, i, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, mReminderCal.getTimeInMillis(), sender);
}
I just need a way to send along the _id of the item in my database so my Service can launch the item with that same _id when the notification is clicked.
I hope my question isn't too confusing.
Thanks!
Why don't you put all your need into Intent data? Something like this:
final Intent intent = new Intent(context, UpdatesActivity.class);
intent.putExtra(ID, "foo");
final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
Then on receiving end you do
String id = getIntent().getStringExtra(ID);

Categories

Resources