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
Related
I am currently writing an app that uses the Google's Activity Recognition API, however in my onHandleIntent method when I put a break point in there to examine the intent being passed in from the service, it is showing me stale data. The activity is returning as STILL even though I am on the road and even on the freeway. [FYI I am not driving but in a moving vehicle :) ] is there anyway to flush the results? even when I disconnect and reconnect I am still getting this STILL reading.
I thought I would share this on the off chance that it is a partial solution to the issue I described in my question. I have tweaked my code and it appears to not be having this issue at the moment. What I am doing to the intent being passed to the activity recognition is giving it a dynamic id, my theory is if i disconnect and reconnect it will is getting the same code to it maybe be caching the stale state. Now with my dynamic id, which really shouldn't hurt anything b/c the id only changes after the remove updates is called, I am hoping this will prevent the cached state.
private static void intentID(){
if(intentID == 0)
intentID = (int)(System.currentTimeMillis());
return intentID;
}
PendingIntent pendingIntent = PendingIntent.getService(mContext, intentID(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
//the modified pendingIntent being used
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(getActivityRecognitionClient(), 1000*10, pendingIntent)
hope this helps!
I have a Service that first creates a new Intent, and calls setAction('foo') on it. After this I call putExtra("key","value123"). Then I call PendingIntent.getService(this,999,intent,0) (no flags passed), and pass the pending intent to the AlarmManager.
But then before the alarm fires (or even after, it seems) I create another Intent and again call setAction('foo') on it, but don't set any extras.
Then I again pass it to PendingIntent.getService(this,999,intent,0). However, this time I call send() on the PendingIntent so as to receive the intent immediately.
What I observe is that the original extras are delivered with the new Intent. I appear to be able to do this over and over, and even if my app is killed, when I restart it, the extras are still there.
However, I don't see anything specifically in the documentation which says whether or not this is actually expected behavior. Is this a reliable method by which I can persist a small amount of data in RAM (only!) in case my app gets terminated? Currently I'm using file on a RAMdisk, but some devices apparently don't have such a thing.
This is the way PendingIntent works ;-)
The first call to PendingIntent.getService() creates a new PendingIntent with the requestCode set to 999 and the Intent set to ACTION="foo".
The second call to PendingIntent.getService) doesn't create a new PendingIntent. It just returns a token (reference) to the first PendingIntent. When you call send() on it, the original PendingIntent is sent.
The reason is that when you call PendingIntent.getService(), Android first tries to find a PendingIntent that matches the one you've specified. To determine if the Intent matches, it checks the ACTION, COMPONENT, DATA and it also checks for matching requestCode arguments. In your case, both calls to PendingIntent.getService() have the same requestCode and the Intents have the same ACTION. NOTE: "extras" in the Intent are not considered when determining if the Intents match.
If you always want to (re)use a single PendingIntent and just override the "extras" every time you use it, you can add the flag PendingIntent.FLAG_UPDATE_CURRENT to the call to PendingIntent.getService().
If you need to create several PendingIntents in parallel, with different "extras", you need to make sure to use a unique requestCode every time you call PendingIntent.getService().
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 want show Activity when device enter the fixed zone. I have startActivity in recivier(GpsAlarmRecivier). Code below works, but when I close Activity, it crash. I know it' s because i must unregister recivier.
But I want use addProximityAlart for all application, even after close my activity(for example, move to previous). Is it possible ?
Intent myIntent = new Intent("gpsup.namespace.ProximityAlert");
PendingIntent proximityIntent = PendingIntent.getBroadcast(cxt, 0, myIntent, 0);
locationManager.addProximityAlert(records.get(pos).x, records.get(pos).y, records.get(pos).r,
-1, proximityIntent);
IntentFilter filter = new IntentFilter("gpsup.namespace.ProximityAlert");
actv.getApplicationContext().registerReceiver(new GpsAlarmReceiver(), filter);
I want use addProximityAlert, even if I close activity, when i created recivier. Thanks for any advices.
I don't believe that there is a way to directly register a system GPSBroadcastReceiver in your application. If that was the case you could just put it in your manifest and it'll get resolved when an update comes out and then you can fire off you custom intent after performing your checks.
I believe that is actually the reason why they don't allow it (I may be wrong). It would be problematic if every application was woken up when a GPS update came out. They would be spanking the battery in the background.
A suggestion that I can give is to create a Service that listens for your GPS updates and then Broadcasts your intents. While you can have it running in the background forever, it certainly has a longer life cycle than an Activity does.
I have a service that does database calls. The service receives a request with an intent, and when the database call is complete, it broadcasts an "update complete" intent indicating the completion of the call.
Sometimes the database is already populated with cached data, in which case I would like to immediately broadcast an "update complete" intent, indicating the activity should display the cached data, and then once the database has been updated fire another "update complete" intent indicating the activity should load the updated data.
The problem is that the second broadcast is never received by the activity. Is this because I'm re-using the same intent object that has already been fired?
Here's the code:
if (scheduleDatabase.populated()) {
intent.putExtra("fromCache", true);
getApplicationContext().sendBroadcast(intent);
}
scheduleDatabase.update();
intent.putExtra("fromCache", false);
getApplicationContext().sendBroadcast(intent);
An update:
If I comment out one of the intent broadcasts, the other one always fires and is received.
Also, if I create two intent objects with the same action string and fire them separately, only the first one is ever received by the activity. I'm not clear yet on whether the other gets fired but not received, or if it never fires at all.
It turns out that the problems I had with the intents were a symptom of a larger problem in a different area of my code. After fixing that problem, the intents began firing and receiving as I expected. So, to answer my own original question, yes it is possible to fire a single intent multiple times.
I ran into a similar problem. Yes the second intent is overwriting the first one. My workaround was to create a new Intent in my BroadcastReceiver. You have access to the same context, and can pass data in the extras.