5 - 3 - BroadcastReceiver - Part 1 (13-48)

6
[BLANK_AUDIO] Hi. I'm Adam Porter, and this is Programming Mobile Applications for Android Handheld Systems. In this lesson, we're going to talk about another fundamental Android component: the BroadcastReceiver class. I'll begin by discussing the BroadcastReceiver class, and the basic workflow that you'll follow when you're using it. Next, I'll discuss how broadcast receivers are registered with the Android system. After that, I'll talk about the different ways that events can be broadcast to those broadcast receivers. And lastly, I'll finish up with a short discussion of how broadcast receivers are notified and how they handle the broadcasts they receive. The BroadcastReceiver is a base class for components whose purpose is to wait for certain events to occur, to receive those events, and then to react to them. And the way this all works is that individual broadcast receivers register to receive the specific events in which they're interested. For example, there's a broadcast receiver in Android whose job is to listen for outgoing MMS messages. Now, somewhere else at a later time, a component does something that it wants to inform broadcast receivers about. So it creates an intent that represents that event, and then it broadcasts that intent. So, there are other components in android that prepare MMS messages so that they can be later sent out over the network. Once the MMS message is ready, then there's a component that creates an action_send_message intent, and then broadcasts that intent. Android then takes the intent that was just broadcast and delivers it to that component we talked about before that has registered to receive action underscore send underscore message intents. And that component finally receives the intent by getting a call to its onReceive method, with that intent as one of the parameters to the method.

Transcript of 5 - 3 - BroadcastReceiver - Part 1 (13-48)

Page 1: 5 - 3 - BroadcastReceiver - Part 1 (13-48)

[BLANK_AUDIO]Hi.I'm Adam Porter, and this isProgramming Mobile Applications forAndroid Handheld Systems.In this lesson, we're going to talk aboutanother fundamental Android component: theBroadcastReceiver class.I'll begin by discussing theBroadcastReceiver class, and thebasic workflow that you'll follow whenyou're using it.Next, I'll discuss how broadcast receiversare registered with the Android system.After that,I'll talk about the different ways thatevents can be broadcast to those broadcastreceivers.And lastly, I'll finish up with a shortdiscussion of howbroadcast receivers are notified and howthey handle the broadcasts they receive.The BroadcastReceiver is a base class forcomponents whose purpose is to wait forcertain events to occur, to receive thoseevents, and then to react to them.And the way this all works is thatindividual broadcastreceivers register to receive the specificevents in which they're interested.For example, there's a broadcast receiverin Androidwhose job is to listen for outgoing MMSmessages.Now, somewhere else at a later time, acomponentdoes something that it wants to informbroadcast receivers about.So it creates an intent that representsthat event, and then itbroadcasts that intent.So, there are other components in androidthat prepare MMS messages so that they canbe later sent out over the network.Once the MMS message is ready, thenthere'sa component that creates anaction_send_message intent, andthen broadcasts that intent.Android then takes the intent that wasjust broadcast and delivers it to thatcomponentwe talked about before that has registeredto receive action underscore sendunderscore message intents.And that component finally receives theintent by gettinga call to its onReceive method, with thatintent asone of the parameters to the method.

Page 2: 5 - 3 - BroadcastReceiver - Part 1 (13-48)

Now for our MMS example, thecomponent receives the action_send_messageintent andeventually sets off a service to deliverthe MMS message.So to recap, the basic workflow isone, broadcast receivers register toreceive specific intents.Two, some component generates an intentand then broadcasts it to the system.Three, Android delivers that intent to thebroadcast receivers that registered toreceive it.And four, the broadcast receivers then geta call to their onReceive method duringwhich they handle the incoming event.So, let's talk abouteach of these steps one at a time.So in order to register a broadcastreceiver developers have two options.One, they can register the broadcastreceiver statically by putting someinformationin the AndroidManifest.XML file of theapplication to which the broadcastreceiver belongs.Or two, they can register the broadcastreceiverdynamically by in invoking some methods atrun time.So to register a broadcast receiverstatically you add a receiver tagin your applications AndroidManifest.XMLfile, and thenwithin that receiver tag you put at leastone intent filter tag.And the information there tells Androidthat whenan intent matching this intent filter isbroadcast,this broadcast receiver wants to knowabout it.And the format for a receiver tag lookssomething like this.You start with the receiver keyword, andthen you add some of the followingattributes.And some of those attributes, includeAndroid enabled, whichallows you to enable or disable aparticular receiver.Another is android:exported.If set to true, then this receivercan receive broadcasts from outside itsapplication.While if it's set to false,then the receiver can only receive intentsthat are broadcast by other componentswithin this application.Another attribute in android:name.

Page 3: 5 - 3 - BroadcastReceiver - Part 1 (13-48)

Which gives the name of the class thatimplements this receiver.There's also android:permission.Which defines a permission string that thesender of an intent must have inorder for this receiver to receive anintent from them.And as I said, you'll also have to specifyat least oneintent filter tag, which we covered backin our lesson on intents.Now, once you've created the receiver tag,you insert an intent filtertag as one of its children, and just likewith intent filters that are used to startactivities these intent filter tags canspecify things like anaction, data, and categories.Now if you do register a receiverstatically, that information will be readandprocessed when the system boots up.Or, when the application package is addedif that happens while the system isrunning.So, let's take a look at an applicationthat's statically registers a singlebroadcast receiver to receive a customintentthat I'll call the show toast intent.Here's my device.AndI'll start up the single broadcast staticregistrationapplication.This application displays a single buttonlabeled Broadcast Intent.Pressing this button causes anintent to be broadcast and then routed toand received bya broadcast receiver, which then displaysa toast message.Now I'll press the button.And there you see the toast messageindicating that the receiver got theintent.Now here I've opened up the application inthe IDE.Now I'll open the main activity.And this code first defines an intentaction string that will beused to identify this intent.And scrolling downthere's a button listener that calls thecontext.sendbroadcast method, passing in an intent anda permission string.The intent will be matched againstregistered intent filters.While the permission string indicates that

Page 4: 5 - 3 - BroadcastReceiver - Part 1 (13-48)

this intent can onlybe delivered to broadcast receivers thathave this particular permission.You can also register broadcast receiversprogrammatically at run time.For instance, if you want your broadcastreceiver to respondto intents only while your activity is inthe foreground,well then you can dynamically register andunregister them inyour activities on resume and on pausemethods for example.And to do this, you'll first create anintent filter object, specify the intentsthat you want to register for.Next, you create the BroadcastReceiver andthenyou register it by calling aregisterReceiver method.And there are different implementations ofthis method.One is in the LocalBroadcastManager class.And this one is for broadcaststhat are meant only for this application.And therefore, they don't need to bebroadcast system wide.The other implementation is in the Contextclass and this one broadcasts intentssystemwide so these intents can potentially bereceived by any application on yourdevice.And finally, as necessary,you can call an unRegisterReceiver methodto unregister thesebroadcast receivers.Let's look at the source code for thesingle broadcast dynamic registrationapplication.This application looks exactly like theprevious application.There's a broadcast intent button, andwhen you press it an intent is broadcast,a broadcast receiver receives the intent,and then displays a toast message.Internally however, its implementation isa little bit different.So, this code starts off by creating anintent action string, and nextit creates an intent filter object withthe just created action string.After that, it creates a broadcastreceiver instance called receiver.And then, down in the on create method,the code gets and instanceof the localBroadcastManager, which as Isaid is used tobroadcast and receive intents only withinthis application.

Page 5: 5 - 3 - BroadcastReceiver - Part 1 (13-48)

Next, the code uses thelocalBroadcastManagerto register the receiver object for theshow toast intent.And after that if the broadcast intentbutton is pressed, the listenercalls localBroadcastManager.sendBroadcastpassing in the intent.When the button is pushed, thelocalBroadcastMangerwill send the intent to the receiverobject which operates just as it did inthe last application, creating anddisplaying a toast message.Now in my example so far, simply broadcasta single intent to a single receiver, butAndroid supports a variety of differentways in which intents can be broadcast.For example, intents can be broadcastnormally or in order.Normal broadcasts are delivered tosubscribedbroadcast receivers in an undefined order.So if you have two broadcast receiversthat should receive a single intent it'spossible that both broadcast receiverscould beprocessing the intent at the same time.Ordered broadcasts on the other handdeliver the intent to multiplebroadcast receivers one at a time inpriority order,and broadcasts can also be sticky ornon-sticky.A sticky intent sticks around after itsinitial broadcast,so a broadcast receiver that is registeredafter the initial broadcastof an intent, may still be able to receiveit eventhough it wasn't around when the intentwas actually broadcast.And this feature is useful, for example,to record system statechanges such as changes in the batterylevel or charging status.In these cases it doesn't matter to thereceiver when the state changed.Right?They just want to know what the currentstate is.Non-sticky broadcastsin contrast are discarded after theirinitial broadcast.And these broadcasts are more suited,therefore,to reporting that a certain event hasoccurred.In these cases, if the receiver isn'tregistered to receive

Page 6: 5 - 3 - BroadcastReceiver - Part 1 (13-48)

the broadcast when it happens, then theywon't get it.And lastly, as we saw in the examples,some broadcastmethods also take a permission string,which limits thebroadcast to those broadcast receiversthat have the specified permission.Now, if you find yourself having troublegetting broadcasts to theright broadcast receivers, there are a fewthings that you can do.One, is to have Android log extrainformation about itsintent resolution process.And you can do this by setting theflag_debug_log_resolution flag in theintent that you're going to broadcast.Another is to use the ADB tool tofind out what broadcast receivers havebeen registered.And you can use the dumpsys command, likethis,to show broadcast receivers that aredynamically registered, and you canuse it like this to show those that arestatically registered.