Is it possible to create two PendingIntents with the same ID ( let's say 889) and the same intent (but different bundle) and then when I cancel PendingIntent with ID 889 will it cancel it both ?
As far as i know, you cant do that.
The System uses the ID to identify the Intents. So if you get a result you never know which of your Intents being processed.
You have to use different IDs if you want to set a repeating alarm for 2 different days. Because if you'll use the same id for each then the notification you set the latest will override the previous one and hence you'll have lose one notification.
Related
I am running into a weird situation where I previous has created a pending intent for activity recognition updates
PendingIntent pendingIntent = PendingIntent.getService(mContext, getIntentID(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
my getIntentID code is
private static int getIntentID(){
if(intentID == 0)
return intentID = (int)(System.currentTimeMillis());
return intentID;
}
I did this because I wanted to be sure the id was unique everytime I stop and start my service.
However now when I am in my intentService reading the activities that are being sent I am pretty sure it is not my most recent pendingintent calling making the request. I believe it is from a previous one. However I don't know how to cancel it since I don't know the id from the previous one.
1. Why don't I know the previous id? well when I cancelled the updates via the remove updates I did use my getIntentID which I thought was working correctly however when I stopped my app, started it again but didnt launch the update() code for the activity recognition, I noticed I was still getting activities, when I used the debugger.
Here is my update request
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(getActivityRecognitionClient(),
Utility.DETECTION_INTERVAL_TIME, pendingIntent())
Here is my remove code
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(getActivityRecognitionClient(),
pendingIntent())
So my question is, is there a way to cancel all calls period to the activity recog. even if I dont know the pendingintent info?
So my question is, is there a way to cancel all calls period to the
activity recog.
If you refer the API of ActivityRecognitionApi it contains only two methods
https://developers.google.com/android/reference/com/google/android/gms/location/ActivityRecognitionApi
one for requesting updates
requestActivityUpdates(GoogleApiClient client, long detectionIntervalMillis, PendingIntent callbackIntent)
and
second one to remove updates
removeActivityUpdates(GoogleApiClient client, PendingIntent callbackIntent)
both methods need PendingIntent.
So obviously answer is NO.
Hope this will helps you.
Okay there seems to be no way to cancel the pending intents to the activity recog. LIke Nag stated however what I ended up doing was changing the name of my intentservice class and using it instead and keeping track of the pending Id info. Now I don't have any request coming in from previous calls
I am trying to cancel an alarm that was set last time my app was run. This alarm has a PendingIntent that was set with PendingIntent.getBroadcast and an inner Intent that contains some variables set by intent.putExtra. My question is this, I know that alarms can be canceled by calling alarmManager.cancel(pendingIntent) where pendingIntent is the same as the one used to set the alarm. But, if the variables placed into the intent are changed will the alarm still be canceled? For example, I set an alarm with intent.putExtra("Joe") where Joe is a contact name. Later my app is closed and when it is re-run I try and cancel the alarm for "Joe" but the user has changed the name of the contact to "Jones". Can I cancel the alarm without knowing the variables I put into the intent?
Thanks!
I think it should cancel the alaram anyway, even though some data is different. The cancel method says:
Any alarm, of any type, whose Intent matches this one (as defined by filterEquals(Intent)), will be canceled.
And filterEquals says:
Determine if two intents are the same for the purposes of intent resolution (filtering). That is, if their action, data, type, class, and categories are the same. This does not compare any extra data included in the intents.
Anyhow, I'd still test it myself.
According to this question (which references the documentation), anything you add using putExtra is not taken into account when checking if an intent is equal to another one.
It shouldn't matter if the extra data is changed.
I register a broadcastreceiver in AndroidMainfest.xml
And in my app, a function is that User can set a time and at this time the app will send a notification. I get the arguments User set ,and use alarmManager to set a task which will happened at the time user set.
But I find that GOOGLE API said that:
If there is already an alarm for this Intent scheduled (with the equality of two intents being defined by filterEquals(Intent)), then it will be removed and replaced by this one.
So if I want set two or more task,the Intent will be replaced , and at end I can only get one notification,it's not the result I want.
And then I found the intent was identified by action, data, type, class, and categories,
but I can't change action(the intent's action is the intent-filter's action was registred in the AndroidMainfest.xml ),but at the time that I change the other arguments I can't even receive a broadcast.
I thought there are four ways to solve this problem,but I only made one..
create lots of broadcastreceiver and register these in
AndroidMainfest.xml,and in this way I could change the intent's
action
register the broadcastreceiver in the program ,but I didn't
make it
use service + Timer class ..
To make two intent different without change action.
Any help will be appreciated!!
Intent intent = new Intent("aaa"); //there was a broadcastreceiver's intent-filter "aaa"
intent.putExtra("title", title);
intent.putExtra("table", "计划");
PendingIntent pi = PendingIntent.getBroadcast(Alarm.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager)getSystemService(Alarm.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+time, pi);
The code is in onClickListener{onClick(){}}
Instead of Broadcasting which is not letting you to set repeat alarm you can use the calendar Object and set the alarm at whatever desired time. Once the alarm gets ON, your code will run automatically and as many times you have set the alarm.
You can also take a help of the following tutorial. I am sure it will help you out somehow.
http://blog.mikesir87.io/2013/04/android-creating-an-alarm-with-alarmmanager/
I have a widget that sets up a number of pendingIntents. All is working just fine on the widget as long as I only have a single widget on the home screen.
For the time being I decided that I was going to limit the user to only one of my home screen widgets. If one is already in use the ConfigureActivity gives the user an alertDialog box telling them they can't add a second one and then sets setResult(RESULT_CANCELED, null) and then finish().
This works just fine and keeps the user from being able to setup any further home screen widgets but for the one that is already in place most of my pendingIntents won't fire. Logcat tells me "Cannot send pending intent:"
Each of the pendingIntents is set to start up a service that is used to update the widget. If I remove the widget and reset it up it works just fine again, until I try to add a second widget. It is a bit baffling to me at this point. Anyone have any ideas as to why starting to add the 2nd widget but not completing it would cancel out my previous pendingIntents?
Incase it matters, the pendingIntents where setup with FLAG_CANCEL_CURRENT.
Here is the code used to set my intent and pendingIntents.
Intent intentDialog = new Intent(getBaseContext(), ScheduleActionsActivity.class);
intentDialog.putExtra("Action", ACTION_ENTER_SCHEDULE);
intentDialog.setAction("abc.hwRowOne");
intentDialog.putExtra("scheduleId", sch.getId());
intentDialog.putExtra("scheduleDescription", sch.getDescription());
PendingIntent pendingIntentDialog1 = PendingIntent.getActivity(getBaseContext(), 0, intentDialog, PendingIntent.FLAG_CANCEL_CURRENT);
views.setOnClickPendingIntent(R.id.hwRowOne, pendingIntentDialog1);
The line where intentDialog.setAction() changes to be unique for each row of the widget, so I thought that was making my pendingIntent unique as well.
I saw this answer last night after posting my question but I am not sure why/how it works and I am unsure where to put it in my area. It appears to set a unique data for each intent, but that is what I thought my .setAction() was doing. Multiple Instances Of Widget Only Updating Last widget
So to answer your question, no I am not using the appWidgetId at all in my intents, do I just need to pass it along as a putExtra() then on the intentDialog?
The answer to this question solved my issues:
Multiple Instances Of Widget Only Updating Last widget
I have no idea why adding the setData(uri) works but it did allow me to have more than one widget on the home screen now and the pendingIntents are unique and firing as I would expect them.
On the safe side I am also adding the appWidgetId to the intent and might need it later if I decide to allow more than one widget per device.
I am scheduling multiple intents to be send to a BroadcastReceiver.
The difference between every intent is the time when it will be received and extra data it contains.
Now I need to allow user to cancel specific alarms. According to AlarmManager.cancel() javadoc, it compares intents using filterEquals method:
http://developer.android.com/reference/android/content/Intent.html#filterEquals(android.content.Intent)
Now the problem is that according to filterEquals, all my intents are the same. Method checks against "action, data, type, class, and categories".
And unique data is either in intent extra bundle or as a time in AlarmManager.
I tried changing any of these parameters - for example using:
intent.setData(Uri.withAppendedPath(Uri.EMPTY, "some_unique_data"));
That would make every intent unique according to filterEquals method, but after changing Data to something like this, my intent does not reach BroadcastReceiver anymore.
What specific bit of data can I change to make every intent unique according to filterEquals and still receivable to my simple BroadcastReceiver?
Maybe I can modify my receiver in any way?
Ok, so I figured it out. As my every alarm has unique time and object ID, this is how I create my PendingIntent:
return PendingIntent.getBroadcast(context, time*100000+o.getId(), toFire, 0);
Now time is either 24 or 15 (24 hours before or 15 minutes before event I fire my alarm) and alarm data object contains unique ID. So I add both and specify it as a "requestCode" parameter in getBroadcast. That is enough to make unique intents based on same data.
Hope this helps anyone who has the same problem!
I ran across a similar problem for my app.
In my app, I used the SQLite DB to store details about each alarm, along with a unique ROW_ID.
So in my alarm listview, each row had a corresponding ROW_ID associated with it.
If the user clicks on a particular row, I just pass this ROW_ID to the method that performs the delete operation
Now, all my alarms were created with Intents which had their data part set as:
Uri.parse(Constants.INTENT_PRE + ROW_ID);
so in order to delete them, I create an Intent that has same data (as above, along with the unique ROW_ID) that was used while creating it.
Needless to say, from "action, data, type, class, and categories", only the "data" part is different for each of my existing PendingIntents.
Hope this helps!