Discussion:
PendingIntent Flag and AlarmManager behavior ?
Derek
2009-08-04 21:22:55 UTC
Permalink
Hi all,

The PendingIntent documentation describes flags.
http://developer.android.com/reference/android/app/PendingIntent.html

public static PendingIntent getService (Context context, int
requestCode, Intent intent, int flags)
Flags values could be:
FLAG_CANCEL_CURRENT:268435456
FLAG_NO_CREATE:536870912
FLAG_ONE_SHOT:1073741824
FLAG_UPDATE_CURRENT:134217728

I'm using the following code:
PendingIntent pendingIntent = PendingIntent.getService(this, 0,
updateIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService
(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, nextUpdate, pendingIntent);

I'm passing zero as flag value. What flag is used then ?

Whatever number of calls to alarmManager.set() with different time,
only the last pending intent instance is taken into account. All
previous ones seem ignored. Is this behavior related to PendingIntent
flag ? Documentation says that requestcode is not used?

Thanks.
SR
2009-08-07 01:03:49 UTC
Permalink
I actually have the same problem with PendingIntent.getBroadcast
(...). Only the last call to AlarmManager.set() actually triggers the
broadcast to the receiver. It seems like PendingIntent.FLAG_ONE_SHOT
is the right one to use, and I am getting different PendingIntents
(judging by pointer values anyway), so I am not clear where the
problem is.

Can someone help us figure it out?

Thanks!

Stan
Post by Derek
Hi all,
ThePendingIntentdocumentation describes flags.http://developer.android.com/reference/android/app/PendingIntent.html
public staticPendingIntentgetService (Context context, int
requestCode, Intent intent, int flags)
FLAG_CANCEL_CURRENT:268435456
FLAG_NO_CREATE:536870912
FLAG_ONE_SHOT:1073741824
FLAG_UPDATE_CURRENT:134217728
I'm using the following code:PendingIntentpendingIntent=PendingIntent.getService(this, 0,
updateIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService
(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, nextUpdate,pendingIntent);
I'm passing zero as flag value. What flag is used then ?
Whatever number of calls to alarmManager.set() with different time,
only the last pending intent instance is taken into account. All
previous ones seem ignored. Is this behavior related toPendingIntent
flag ? Documentation says that requestcode is not used?
Thanks.
Dianne Hackborn
2009-08-07 01:48:47 UTC
Permalink
Different pointers doesn't mean they are different; use .equals() to compare
them. You need to have something unique in the intent action, type, data,
or categories to get different pending intent objects.
Post by SR
I actually have the same problem with PendingIntent.getBroadcast
(...). Only the last call to AlarmManager.set() actually triggers the
broadcast to the receiver. It seems like PendingIntent.FLAG_ONE_SHOT
is the right one to use, and I am getting different PendingIntents
(judging by pointer values anyway), so I am not clear where the
problem is.
Can someone help us figure it out?
Thanks!
Stan
Post by Derek
Hi all,
ThePendingIntentdocumentation describes flags.
http://developer.android.com/reference/android/app/PendingIntent.html
Post by Derek
public staticPendingIntentgetService (Context context, int
requestCode, Intent intent, int flags)
FLAG_CANCEL_CURRENT:268435456
FLAG_NO_CREATE:536870912
FLAG_ONE_SHOT:1073741824
FLAG_UPDATE_CURRENT:134217728
I'm using the following
code:PendingIntentpendingIntent=PendingIntent.getService(this, 0,
Post by Derek
updateIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService
(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, nextUpdate,pendingIntent);
I'm passing zero as flag value. What flag is used then ?
Whatever number of calls to alarmManager.set() with different time,
only the last pending intent instance is taken into account. All
previous ones seem ignored. Is this behavior related toPendingIntent
flag ? Documentation says that requestcode is not used?
Thanks.
--
Dianne Hackborn
Android framework engineer
***@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails. All such
questions should be posted on public forums, where I and others can see and
answer them.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
SR
2009-08-07 02:18:21 UTC
Permalink
Dianne,

Thanks! I think I figured it out about 30 minutes ago. In the
AlarmManager.set(..) documentation, it says that intents are compared
using Intent.filterEquals(Intent otherIntent), which, of course, does
not compare the extras.

One quick (and dirty) workaround would be to extend Intent with your
own class that goes something like this:

public class AlarmManagerIntent extends android.content.Intent {
// Add other requisite constructors here

AlarmManagerIntent(Context ctx, Class<?> c) {
super(ctx, c);
}

@Override
public boolean filterEquals(Intent i) {
return (i == this);
}
}

Use it only when certain that your scheduled Intents will be unique!

Let me test this and see if it works...

Stan
SR
2009-08-07 04:10:00 UTC
Permalink
No, that doesn't seem to be it :(

I'm still getting only one broadcast from multiple closely scheduled
events with AlarmManager.

Moreover, neither the filterEquals() nor equals() methods of
AlarmManagerIntent get invoked -- I'm not getting any printouts from
overridden versions of these methods, even if
PendingIntent.FLAG_CANCEL_CURRENT or PendingIntent.FLAG_UPDATE_CURRENT
are passed to the PendingIntent constructor.

Any other ideas? I've been trying to track down the source code for
the Alarm Manager service, but it seems to be implemented
natively ...would appreciate a pointer.

Stan
SR
2009-08-07 19:16:36 UTC
Permalink
Ultimately, the only way I could get different intents to be scheduled
with AlarmManager is to set different data URIs in the Intents that I
was wrapping in PendingIntents and scheduling with AlarmManager.set().

I filed an issue about this here:
http://code.google.com/p/android/issues/detail?id=3498

Stan
Dianne Hackborn
2009-08-07 19:27:17 UTC
Permalink
Thanks. I closed the bug with a description of why this is so. Having data
(action, type, Uri, categories, component) that is unique within the intent
is the way to do this. You can also use the request code to disambiguate
them.
Post by SR
Ultimately, the only way I could get different intents to be scheduled
with AlarmManager is to set different data URIs in the Intents that I
was wrapping in PendingIntents and scheduling with AlarmManager.set().
http://code.google.com/p/android/issues/detail?id=3498
Stan
--
Dianne Hackborn
Android framework engineer
***@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails. All such
questions should be posted on public forums, where I and others can see and
answer them.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
SR
2009-08-07 19:53:36 UTC
Permalink
Ok, then the documentation should not imply that AlarmManager.set(...)
uses filterEquals(...) to compare the intents. It should say instead
that (action, type, Uri, categories, component) are used for
comparison of intents.

Also, the documentation for PendingIntent currently explicitly says
that the request code is ignored. If it is not ignored by
AlarmManager, the documentation must say that too.

Stan
Thanks.  I closed the bug with a description of why this is so.  Having data
(action, type, Uri, categories, component) that is unique within the intent
is the way to do this.  You can also use the request code to disambiguate
them.
Dianne Hackborn
2009-08-07 20:02:28 UTC
Permalink
Post by SR
Ok, then the documentation should not imply that AlarmManager.set(...)
uses filterEquals(...) to compare the intents. It should say instead
that (action, type, Uri, categories, component) are used for
comparison of intents.
It does use filterEquals().
Post by SR
Also, the documentation for PendingIntent currently explicitly says
that the request code is ignored. If it is not ignored by
AlarmManager, the documentation must say that too.
It depends on what you mean by ignored. It is ignored as far as delivering
the pending intent goes, because broadcasts don't (currently) have requests
codes. It is not ignored for intent matching, but taken as another
identifying part of the pending intent. And none of this has anything
specifically to do with the alarm manager, which just gets pending intents,
and calls equals() and send() on them.

Anyway, I do agree the documentation needs to be improved; the identity of
pending intents is one of the more common issues I see people having.
--
Dianne Hackborn
Android framework engineer
***@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails. All such
questions should be posted on public forums, where I and others can see and
answer them.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
SR
2009-08-07 20:12:14 UTC
Permalink
Dianne,

Thank you for your explanations and time. I think the issue is clear
now, and just a little bit more discussion remains on how to clarify
it to others.
Post by Dianne Hackborn
It does use filterEquals().
Agreed, but filterEquals() of the Intent class proper. Maybe making
Intent.filterEquals() *final* would help get the point across.
Post by Dianne Hackborn
Post by SR
Also, the documentation for PendingIntent currently explicitly says
that the request code is ignored.
It depends on what you mean by ignored.  
The only meaning I was equipped with was one given by the
documentation of PendingIntent. I think adding a little paragraph to
the top of that class's documentation talking about the role of
requestCode would help.

S
Dianne Hackborn
2009-08-07 21:20:36 UTC
Permalink
Post by SR
The only meaning I was equipped with was one given by the
documentation of PendingIntent. I think adding a little paragraph to
the top of that class's documentation talking about the role of
requestCode would help.
This is actually just a general Intent thing -- if you make a subclass of
Intent and pass it to pretty much any system API, your subclass is going to
be lost as it moves across processes. One could argue that Intent itself
should be final, but I am loath to make things final when they don't
absolutely have to be, and end up in annoying situations like String. (And
anyway, the SDK is published, so it is too late to make any of these APIs
final anyway.)
--
Dianne Hackborn
Android framework engineer
***@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails. All such
questions should be posted on public forums, where I and others can see and
answer them.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-***@googlegroups.com
To unsubscribe from this group, send email to
android-developers-***@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---
Loading...