Activity or Notification via Ordered Broadcast
I’ve run into the following generalized question a lot recently:
I have an event that occurs in the background. I want to update my activity, if the activity is on the screen. Otherwise, I want to raise a
Notification
.
This seems perfectly reasonable. Every time I hand-waved my way around an answer, I felt like there should be a better solution for this. To quote Commodus, “It vexes me. I’m terribly vexed.”
A few days ago, a solution popped into mind, and based on preliminary experiments, it seems to work well. And, it lets us use an ordered broadcast.
Ordered broadcasts are like regular Intent
broadcasts, except
that they are ordered.
(yes, people pay $40/year for insights like these — you can too!)
Specifically, the broadcast is sent to one BroadcastReceiver
at a time. Each receiver has the ability to abort the broadcast,
meaning that no other receiver after it will get the broadcast.
And, you can prioritize the receivers.
Hence, the recipe for the activity-or-Notification
pattern is:
-
Define an action string you will use when the event occurs that you want to go to the activity or notification (e.g.,
com.commonsware.java.packages.are.fun.EVENT
). -
Dynamically register a
BroadcastReceiever
in your activity, with anIntentFilter
set up for the aforementioned action string and with a positive priority (the default priority for a filter is 0). This receiver should then have the activity do whatever it needs to do to update the UI based on this event. The receiver should also callabortBroadcast()
to prevent others from getting it. Be sure to register the receiver inonStart()
oronResume()
and unregister the receiver in the correspondingonStop
oronPause()
method. -
Register in your manifest a
BroadcastReceiver
, with an<intent-filter>
set up for the aforementioned action string. This receiver should raise theNotification
. -
In your service (e.g., an
IntentService
), when the event occurs, callsendOrderedBroadcast()
.
And that’s it. If the activity is on-screen, its receiver will
be registered, so it will get the event, process it, and cancel
the broadcast. If the activity is not on-screen, its receiver
will not be registered, so the event will go to the default
handler, in the form of your manifest-registered BroadcastReceiver
,
which will raise the Notification
.
I have some code that demonstrates this, though it’s not published
in any of my GitHub repos
at this time. I’ll be adding it to the repo
for The Busy Coder’s Guide to Advanced Android Development
at some point, when I cover the subject. If somebody needs this
code, or has any questions on the technique, please join the
cw-android
Google Group
and ask!