Listening in with broadcast receivers

Another way to use an Intent involves sending a broadcast to any interested receiver. There are many reasons an application may want to broadcast an event; for example, when an incoming phone call or text message is received. In this section we will take a look at how events are broadcast and how they are captured using a BroadcastReceiver.

Here we will continue working through the WeatherReporter sample application we began in the previous section. One of the most important parts of the Weather-Reporter application will be its ability to display alerts to the user when severe weather is in the forecast for a location where the user has indicated interest. We will need a background process that checks the weather and sends any needed alerts. This is where the Android Service concept will come into play. We won't be creating the actual Service class until section 4.3, but we need a way to get the platform running the Service as soon as it boots up, and this is where we will use an Intent broadcast.

4.2.1 Overloading the Intent concept

As you have seen, Intent objects are used to go from Activity to Activity in an Android application. While this is the main use of intents in Android, it is not the only one. Intents are also used to broadcast events to any configured receiver using one of several methods available from the Context class, as shown in table 4.3.

Table 4.3 Methods for broadcasting intents

Method

Description

sendBroadcast(Intent intent)

sendBroadcast(Intent intent, String receiverPermission)

Simple form for broadcasting an Intent.

Broadcasts an Intent with a permission String that receivers must declare to receive the broadcast.

Table 4.3 Methods for broadcasting intents (continued)

Method

Description

sendStickyBroadcast(Intent intent)

sendOrderedBroadcast(Intent intent, String receiverPermission)

sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)

Broadcasts an Intent that hangs around a short time after it is sent so that receivers can retrieve data. Applications using this must declare the BROADCAST_STICKY permission.

Broadcasts an Intent call to the receivers one-by-one serially.

Broadcasts an Intent and gets a response back by implementing your own BroadcastReceiver for the broadcast (and passing it in). All receivers can append data that will be returned in the BroadcastReceiver. When using this method, the receivers are called serially.

When broadcasting intents you are basically reusing the Intent concept to send an event in the background. Though the Intent class is used, it is used differently than when invoking foreground Activity paths. A broadcast Intent does not invoke an Activity (though a BroadcastReceiver can do so after the event is received, if necessary).

Another important aspect with Intent broadcasts is how permissions are handled. When you broadcast an Intent, you can optionally specify a permission. Permissions are something we addressed in chapter 1. They basically are String declarations that can be used when making a broadcast that require receivers to declare the same permission.

Broadcasting an Intent itself is fairly straightforward; you use the Context object to throw it on the wire, and interested receivers will catch it. Android provides a set of platform-related Intent broadcasts that use this approach. When the time zone on the platform changes, when the device completes booting, or when a package is added or removed, for example, the system broadcasts an event using an Intent. Some of the specific Intent broadcasts the platform provides are shown in table 4.4.

Table 4.4 Provided Android platform broadcast actions

Action

Description

ACTION_TIME_TICK

ACTION_TIME_CHANGED

ACTION_TIMEZONE_CHANGED

ACTION_BOOT_COMPLETED

ACTION_PACKAGE_ADDED

ACTION_PACKAGE_REMOVED

ACTION_BATTERY_CHANGED

Sent every minute to indicate that time is ticking

Sent when the user changes the time on the device

Sent when the user changes the time zone on the device

Sent when the platform completes booting

Sent when a package is added to the platform

Sent when a package is removed from the platform

Sent when the battery charge level or charging state changes

The other half of broadcasting events is the receiving end. To register to receive an Intent broadcast, you implement a BroadcastReceiver. This is where we are going to implement a receiver that will catch the platform-provided BOOT_COMPLETED Intent in order to start the weather alert service we will create for the Weather-Reporter application.

4.2.2 Creating a receiver

Because the weather alert Service we want to create needs to be running in the background whenever the platform itself is running, we need a way to start it when the platform boots. To do this, we will create a BroadcastReceiver that listens for the BOOT_COMPLETED Intent broadcast.

The BroadcastReceiver base class provides a series of methods that allow for getting and setting a result code, result data (in the form of a String), and an extras Bundle. In addition, there are a series of lifecycle-related methods that correspond to the lifecycle events of a receiver; you will learn more about these as we progress through this section.

Associating a BroadcastReceiver with an IntentFilter can be done in code or in the manifest XML file. Once again the XML usage is often easier and thus more common. This is the way we did it for WeatherReporter in listing 4.3, where we associated the BOOT_COMPLETED broadcast with the WeatherAlertServiceReceiver class. This class is shown in listing 4.5.

Listing 4.5 The WeatherAlertServiceReceiver BroadcastReceiver class public class WeatherAlertServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { <

if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {

context.startService(new Intent(context, „

Override

WeatherAlertService. class)) ; <1-1 onReceive

} Start WeatherAlertService D Extend BroadcastReceiver O

When creating your own Intent broadcast receiver you extend the BroadcastReceiver class Android provides O and implement the abstract onReceive(Context c, Intent i) method ©. Within this method we are starting the WeatherAlertService. This Service class, which we will create next, is started using the Context.start-Service(Intent i, Bundle b) method G.

Keep in mind that receiver class instances have a very short, specific lifecycle. When the onReceive(Context c, Intent i) method is complete, the instance and process that invoked the receiver are no longer needed and may be killed by the system. Because of this, you can't perform any asynchronous operations in a BroadcastReceiver, such as binding to a Service or showing a dialog. Alternatively, you can start a Service, as we have done here, and leave it running in the background. (Binding to a Service is different than starting one; we will cover this distinction in the next section.)

Now that our receiver is starting the WeatherAlertService, which will run in the background and warn users of severe weather in the forecast with a Notification-based alert, we need to delve into the realm of the Android Service concept itself.

0 0

Post a comment