Chapter     18

Broadcast Receivers: Android Inter-Application Communication

In this chapter, wewill take a close look at Android’s Broadcast Receiver classes. This class is used specifically for communications between Android components, each of which will be in the form of a subclass of the primary Android class (Activity, Service, BroadcastReceiver, etc.) as we have seen in our Java coding experiences within this book.

This can include communication between your own application components, but is more widely used for communications between unrelated application components. This would mean communication with other applications. In fact it is even more commonly used to communicate between your application and the components that are included with the Android operating system.

If you think about it, the most used components (applications) on anyone’s Android phone are the components that come included with the phone and are thus an integrated part of the Android OS. No one can argue that folks use their Android device’s phone dialer, calendar, alarm clock, timers, e-mail client, browser, screen savers, wallpapers, ringtones, and so on to a very large extent in their day to day use of their Android device, whether that is a smartphone, tablet, e-Reader, watch, set-top box or iTV set.

In this chapter, I am going to try and show you the various ways that you can implement Broadcast Receivers, often called simply Receivers, in your Android application, and in this case in our Hello World app. That said, this particular Android topic travels somewhat outside of the contained systems (Eclipse IDE and its emulator) that we have needed to stay within to make sure that each of our readers can follow along in lock-step.

This is because each of our readers has different Android device hardware, and are working with different developers and applications once we start getting into broadcasting (using BroadcastReceivers) between different Android device features and different external applications.

For this reason, I have to choose my Java code examples for this chapter very carefully, as they will need to support device features that every type and model of Android device on the market is guaranteed to support.

Luckily, this is an introductory book on Android, and so I can cover the theory and rules of the BroadcastReceiver class in this chapter.

We will learn how to implement Broadcast Receiver methods (Java) and tags (XML) in such as way that you will get a general idea regarding how these work, and where to start, in implementing Broadcast Receivers within your own Android applications.

Android BroadcastReceivers: Basic Concepts and Types

Android’s BroadcastReceiver class is a direct subclass of java.lang.Object, which means that it is at the top of the Android class hierarchy, as might be expected from a major operating system function.

It is a part of the android.content package, so its full path for usage in an import statement would be android.content.BroadcastReceiver as we see in our Java coding later on in the chapter.

Just like there are two different types of Android Services (started and bound) there are also different types of Broadcasts which can be received: Normal Broadcasts and Ordered Broadcasts.

Normal Broadcasts are asynchronous and are thus free floating and not tied down (synced) to anything else in the operating system environment. Any of your receiver methods that subscribe to a normal broadcast is thus free to run in any undefined order.

Because Android is a multi-threaded and thus multi-tasking operating system, this also means that Normal Broadcasts can be processed via their receiver methods at exactly same time (in parallel).

This means that normal broadcasts are inherently more efficient, because they are not predicated upon any other system event, and the operating system has the latitude to process them in the most optimal fashion.

However, this also means that normal broadcasts cannot utilize any returned results (returned values of any type), or terminate any API or components.

Normal Broadcasts are sent by using the Context.sendBroadcast( ) method, as we will see later on in the chapter, when we get into Java coding for the Broadcast Receivers we add to our Hello World application infrastructure.

Ordered Broadcasts, on the other hand, are delivered in order, to a single receiver at a time. As each receiver executes an Ordered Broadcast, it can propagate a result to the next receiver. Alternatively, it can also choose to abort the broadcast at any given receiver object, so that the broadcast won’t be passed over to any of the other receivers. As programmers you may see a parallel in this as to how events “bubble” up the processing chain.

The order that Broadcast Receivers process in can be controlled using the android:priority attribute of the <intent-filter> inside that <receiver> tag in your AndroidManifest.xml where you will define your Broadcast Receivers. At this point that is probably no surprise to you, as most component critical application infrastructure will be defined in your AndroidManifest so that the Android OS can set up those processes and memory spaces when it starts up your application.

It is important to note that <receiver> tags and <intent-filter> tags that specify the exact same priority levels will be run in an arbitrary order.

Ordered Broadcasts are sent by using the Context.sendOrderedBroadcast( ) method.

It is important to note that even in certain scenarios involving normal broadcasts that the Android operating system might revert to delivering your normal broadcast one receiver at a time, as if it were an ordered broadcast. This could happen if the Android OS decides that this method of broadcasting will provide a more processing or memory optimized result to or within the current operating environment configuration.

Another important consideration is Broadcast Receivers that may require the creation of a process. Only one of these Broadcast Receivers should be run at one time, so that the OS can avoid overloading the operating system with new processes, each of which takes memory and processing resources.

In this situation, those non-ordered (normal receiver) broadcast semantics will always hold true; these process-creating Broadcast Receivers will not be able to return any results, or to abort their broadcast components.

In summary, your BroadcastReceiver class, after it is launched as an app component through your AndroidManifest.xml <receiver> tag, will become an important part of your Android application’s overall lifecycle.

If you need to review this basic Android application lifecycle and related information at any time (which is a great idea to do every once in a while when you are learning the Android OS and how it operates), you can always find this information on the Android Developer site, at the following URL:

http://developer.android.com/guide/components/fundamentals.html

Next we’ll review why we need to keep our Activity Intent objects and our BroadcastReceiver Intent objects separated, and then, we’ll get into the issues of security, Broadcast Receiver lifecycles, and Broadcast Receiver processing (processes) within the Android Operating System infrastructure. Once we have learned about all these things we can start coding!

Broadcasting Your Intent: Activity versus Broadcast Receiver Intents

We are using the Intent class and Intent objects to send and receive these broadcasts. As I mentioned in Chapter 16 on Intents, the Intent Broadcast Receiver engine is completely separate from Intents that are used to start your Activities using the Context.startActivity( ) method.

Thus there is no way for a BroadcastReceiver to process an Intent that is utilized with a .startActivity( ) method. In fact, your Broadcast Receiver does not even perceive that an Activity Intent exists! Similarly, when you broadcast your BroadcastReceiver Intents, those Intent objects will never encounter, and thus will never be able to start, any Activity subclasses.

The primary reason that the Android OS needs to keep these types of Intents so far apart is because these two types of components and the operations that they invoke utilize two very different types of Android processes.

Starting an Activity with an Intent is, as we know, a foreground process operation that takes place in the primary or main UI process and thread. That type of Android process directly modifies what the user is currently interacting with in real-time.

Broadcast receiving an Intent, on the other hand, is a background process operation, which the user is not aware of, and which is thus not as high a priority within the process priority ranking that we learned about in the previous chapter. As you can see I had a good reason for getting into all that technical information on processes and threads as it applies to more than just utilizing Services in Android.

Secure Broadcasts: BroadcastReceiver Security Considerations

BroadcastReceivers as you may have noticed in the previous sections are used via the Android Context Class API, for instance to call a Broadcast Receiver you would use their method calls off the Context object/class as follows: Context.sendBroadcast( ) or Context.sendOrderedBroadcast( ).

Therefore Broadcast Receivers are by their core access a cross-application implementation, and as such, you would be very wise to consider how other applications external to your own can abuse your implementation of Android Broadcast Receivers. This section effectively outlines some of the primary issues that you may want to keep in mind while working with Broadcast Receivers inside your Android applications.

First of all, the Android Intent namespace is global. For this reason, you will want to assure that your Intent action names, as well as other string constants, are encapsulated inside namespaces which you own. If you do not follow this rule, you may inadvertently conflict with other applications.

Whenever implementing a .registerReceiver(BroadcastReceiver, IntentFilter) method, be aware that any other Android application could send broadcasts to that registered BroadcastReceiver. You can, in fact, control exactly who can send broadcasts to your registered Receiver object through the use of BroadcastReceiver permissions, which we will be covering soon.

When you publish a <receiver> in your application AndroidManifest.xml file definition and then additionally specify <intent-filter> structures in it, you need to realize that any other Android application can send broadcasts into this structure, regardless of the <intent-filter> constructs which you might specify.

There is a way to prevent other applications from sending broadcasts into your application’s <intent-filter> structure in your <receiver> tag. The way to do this is to make your BroadcastReceiver unavailable to them by using an android:exported=“false” parameter in your <receiver> tag. Note that this parameter can also be utilized in <service> and <activity> tags.

If you decide to utilize the .sendBroadcast(Intent) method, or its related methods, be aware that any other application can receive these broadcasts.

You can control who can receive a broadcast by using permissions. If you are using Android 4 (Ice Cream Sandwich) or later, you can also restrict your broadcast to any single application by using the Intent.setPackage( ) method call.

It is important to note here that none of these security issues exist when you are using the LocalBroadcastManager, which we are covering in a future section of this chapter, since an Intent broadcast using this class never travels outside of your current process.

Broadcast access permissions can be enforced on either the sender side or on the receiver side of that broadcast. The way to enforce permissions on the sending side of the equation is that you supply a non-null permission argument using .sendBroadcast(Intent, String) or, if you are using ordered broadcasts, by using the following: .sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle) method call.

Only Broadcast Receivers who have been granted this permission constant by requesting it via the <uses-permission> tag in their AndroidManifest.xml file will be able to receive your secure permissioned broadcast.

The way that you enforce permissions when you are receiving a broadcast is that you again supply a non-null permission when registering the receiver.

This is done when you call your Java .registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler) method, or alternatively, in the static <receiver> tag in your AndroidManifest.xml file.

Only BroadcastReceivers that have been previously granted this permission can send an Intent object to that receiver object. Permissions may be granted by requesting those permissions using the <uses-permission> tag option in the AndroidManifest.xml file for that Android application.

The BroadcastReceiver Lifecycle: Rules and Regulations

A BroadcastReceiver object is only valid for the duration of that receiver call to the .onReceive(Context, Intent) method. Once the Java code returns from this .onReceive( ) method functionality the operating system will then consider that object to be finished, and it will no longer be active.

This Broadcast Receiver processing cycle has important implications as to what exactly you can do inside your .onReceive(Context, Intent) method call implementation.

Any Java code that you write that would require asynchronous operation is not allowed. This is because you would need to return from the function to handle that asynchronous operation. However, at that point, your BroadcastReceiver would no longer be active, and thus the system would be free to terminate the process before the asynchronous operation completed.

Additionally, you will not be able to display any dialogs, and you will not be able to bind to any Service class from within a BroadcastReceiver.

If you need to display a dialog in this situation you can still accomplish this objective by using the Android NotificationManager class from the android.app package. The android.app.NotificationManager is a subclass of java.lang.Object and this class notifies your user of events that happen in the background. Notifications can take three different formats: one is a persistent icon that lives in the status bar, and is accessible through your launcher; the next is by turning on or flashing an LED on your user’s Android device; or finally, alerting your users by flashing the backlight, or by playing a sound, or even by vibrating a device. More information on the Android Notification Manager class can be found at the following URL:

http://developer.android.com/reference/android/app/NotificationManager.html

If you need to start a Service class, as we saw in the previous chapter, you must utilize the Context.startService( ) method call to send a command to the Service subclass.

Processing Broadcasts: How a Broadcast Affects an Android Process

An Android process that is currently executing a BroadcastReceiver object is going to be running the Java code inside that BroadcastReceiver’s .onReceive(Context, Intent) method. This is considered by the Android operating system to be a high-priority foreground process, and thus it will be kept active and processing by the operating system except possibly under the case of extreme memory resource shortages.

Once your Java code returns from completing the .onReceive( ) method call, that Broadcast Receiver is then no longer active, and its hosting process rank is recalibrated so that it is as important as the other application components that are running in that process, but not more important.

This is especially notable because if that process was only created for the purpose of hosting your BroadcastReceiver, which is usually the case, for applications which the user has never interacted with, or has not even recently interacted with, then upon returning from the .onReceive( ) method execution, the operating system will consider that process to be an empty process priority.

As we learned about the empty process priority in the previous chapter, this means that the Android OS will most likely aggressively terminate that process, so that the operating system resources are available for other more important processes.

What this means is that for long-running operations, you should oftentimes utilize a Service in conjunction with a BroadcastReceiver to keep that containing process active for the entire duration of your function’s operation.

Broadcasting Inside Your Application: The LocalBroadcastManager

If you don’t need to send BroadcastReceivers between two different Android applications, you might be better off utilizing the BroadcastReceiver function using the LocalBroadcastManager class, instead of using the global approach described in the preceding sections. Note that if you need to support the Android OSes prior to 3.0 (such as 2.3.7 for the original Amazon Kindle Fire) that these do not support the LocalBroadcastManager class.

The LocalBroadcastManager class gives a more efficient local broadcast implementation, as no inter-process communications is required. This also relieves you from considering all the various security issues that are related to other Android applications receiving or sending your broadcasts.

The reason for this is that by utilizing this LocalBroadcastManager class you will know that the data which you are broadcasting inside your app will not leave the confines of your application, and as such, you will not need to be concerned about the leaking of any of your private data.

Secondly, by using LocalBroadcastManager it becomes impossible for other applications to send any broadcasts into your app, so you also don’t need to worry about having any security windows in your application which other programmers can exploit.

Finally, using the LocalBroadcastManager class is far more efficient, as far as memory and processing is concerned, than sending a global broadcast throughout the Android operating system.

Registering a Broadcast Receiver: Dynamic versus Static Registration

There are two completely different ways to register your Android BroadcastReceiver object for use within your Android application.

One form of registration is called a static method of BroadcastReceiver registration, and this method is the format that you are most familiar with, and involves using the <receiver> tag to register the Broadcast Receiver “up-front” for use (which is why it is termed static registration) inside your AndroidManifest.xml file.

The other way is called dynamic BroadcastReceiver registration, and this is done using Java code rather than XML mark-up. The reason it is called dynamic is because it is done in your Java code at the same time as you are doing everything else in regards to the BroadcastReceiver class that you are implementing, and not up-front (static) in the AndroidManifest.xml application bootstrap file.

If you wanted to utilize dynamic BroadcastReceiver registration, the way in which you would dynamically register an instance of a BroadcastReceiver class is by utilizing the Context.registerReceiver( ) method call.

It is important to note that if you are registering a BroadcastReceiver in your Activity.onResume( ) method code, you should remember to unregister it in your Activity.onPause( ) method code as well.

The reason for this is to reduce wasted system resources because you don’t want to receive any Intent objects when your Activity is paused, so you add an onPause( ) method and unregister the receiver so you don’t have the operating system trying to send Intent objects to an Activity that is not actively being used.

Be sure not to make the common mistake of unregistering BroadcastReceivers inside of the Activity.onSaveInstanceState( ) method, because this method will not be called if the user moves backward within the history stack.

Now it’s about time to try our hand at implementing the BroadcastReceiver class and methods within our very own Hello World Android application.

Implementing a Broadcast Receiver in Our Application

The first thing we need to do is to lay some groundwork for implementing a BroadcastReceiver in our Hello World application, such as: creating string constants, XML user interface design, AndroidManifest entries, and so on.

Our BroadcastReceiver will send a message when an Alarm function which we will add to our TimePlanet.java Activity is triggered and the alarm goes off. Because a Timer is time-related we will add this functionality to the UI screen where it is most logical to add itour Planet Time UI screen!

Let’s add our new string constants now, so that we can label our Button UI element that will start the Alarm countdown and our TextEdit field so that it has a hint inside of it that will tell our end-users exactly what type of information we want them to enter into this data field.

We’ll label the Button object: Start Timer Countdown, and we’ll make our hint say: Enter Number of Seconds, by writing the following XML mark-up:

<string name="timer_hint_value">Enter Number of Seconds</string>
<string name="timer_button_value">Start Timer Countdown</string>

These two new string constants go into our strings.xml file, which is in the /res/values folder under our project folder, shown in Figure 18-1.

9781430257462_Fig18-01.jpg

Figure 18-1. Adding our Button UI element label string constant and EditText UI element hint string constant

Now that we can reference these string constants in our new UI Design for our TimePlanet.java Activity, it is time to add these new UI elements to our activity_time.xml file.

Designing Our Alarm Broadcast Receiver User Interface Using XML

Open up the activity_time.xml file in an editing pane in the central area of Eclipse, by right-clicking the filename in the /res/layout folder, and selecting Open (or use the F3 function key if you prefer).

We will put our setAlarm EditText user interface widget right underneath our Analog Clock so that all our Button UI elements on the screen will stay grouped together. Add an <EditText> tag under the <AnalogClock> tag and add in parameters that will configure it similarly to the EditText fields that we created for our activity_config.xml user interface screen.

Let’s use an alpha value of 0.75 transparency, a text size of 12 ems, a background color of white or #FFFFFF, and textStyle of a bold font.

Use the android:layout_gravity=“center” to center the data entry field in the UI Design and android:layout_marginTop=“10dp” to space our data field away from the AnalogClock UI element a bit.

Finally, let’s specify our android:typeface parameter to be monospace, and an android:inputType of numberDecimal for the number of seconds to count down for our Timer.

The final EditText XML mark-up should contain the following parameters:

<EditText      android:id="@+id/setAlarm"
               android:hint="@string/timer_hint_value"
               android:inputType="numberDecimal"
               android:ems="12"
               android:alpha="0.75"
               android:layout_marginTop="10dp"
               android:background="#FFFFFF"
               android:textStyle="bold"
               android:layout_gravity="center"
               android:typeface="monospace"
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
/>

In the Eclipse XML editor we put two to three parameters on each line to save space, so we could see all our XML code for our user interface screen definition on one screen, as shown in Figure 18-2.

9781430257462_Fig18-02.jpg

Figure 18-2. Adding our Button and EditText tags and configuring their parameters fo use in the UI design

Next we need to add our startCounter Button object underneath our setAlarm EditText element, so that the Button element that our user clicks to start our timer running once they add the duration value is right underneath it.

Add a <Button> tag under the <EditText> tag and add in the parameters that will configure this Button similar to the three Button fields that we have already created right underneath it for our current user interface screen.

Let’s set the android:id parameter to startCounter that we will reference in our Java code and set the android:text parameter to reference the string constant that we created earlier, named timer_button_value.

Let’s use a background color of yellow or #FFFFAA and centering parameter of android:layout_gravity=“center” to center the data entry field in the UI Design and make sure that the required android:layout_width and the android:layout_height parameters are included and set to wrap_content.

The final Button tag XML mark-up should contain the following parameters:

<Button	android:id="@+id/startCounter"
        android:text="@string/timer_button_value"
        android:textColor="#FFFFAA"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
/>

Now that we have implemented the XML mark-up for our Timer user interface elements, let’s also implement the XML tags that we will need to declare our BroadcastReceiver component subclass for use in our application. This, as you know, is done in an AndroidManifest.xml file, so let’s do that now.

Adding Our AlarmReceiver BroadcastReceiver Android Manifest XML

Open up your Androidmanifest.xml file in an editing pane in the central area of Eclipse by right-clicking the filename in the bottom of your Hello_World project folder, and selecting the Open menu option (or use the F3 function key, if you prefer).

Let’s add a line under the <service> tag at the bottom of our Manifest right above the closing </application> tag for our application components definition block of XML mark-up.

Add a <receiver> tag for our new BroadcastReceiver subclass, which we are about to code in Java next, and use a name parameter to reference the full pathname to the application component name, using the following mark-up:

<receiver name="chapter.two.hello_world.AlarmReceiver" />

The completed AndroidManifest.xml file, declaring our latest Hello World application components, including six Activity components, as well as a Service and a BroadcastReceiver component, is shown in Figure 18-3.

9781430257462_Fig18-03.jpg

Figure 18-3. Adding a <receiver> tag for our AlarmReceiver BroadcastReceiver subclass to AndroidManifest.xml

Now that we have our Alarm user interface elements designed and our Broadcast Receiver declared in our Manifest the time has come to code our Alarm Control user interface elements and methods using Java code in our TimePlanet.java Activity subclass where they will be displayed.

Coding Our startTimerButton and startTimer( ) Method Using Java

Let’s take a programmer’s short-cut, and implement our startTimerButton Button UI object the easy way! Copy and paste the startMusicServiceButton lines of code (all six of them) again underneath themselves to start with.

Next change the startMusicServiceButton name to startTimerButton, and the UI XML ID reference from R.id.startServiceButton to R.id.startCounter, and finally, change the startService(new Intent(this,class)) method call to be a startTimer(view); method call.

For now, Eclipse is going to red error highlight this new method name we are using, at least until we code this new method, which we are going to do next, at the bottom of our Activity. The new event handling code for the startTimerButton Button user interface element is shown in Figure 18-4, along with the public void startTimer(View view) method Java code, which we are about to go over in great detail next. The startTimerButton Java code block should look like the following:

startTimerButton.setOnClickListener(new View.OnClickListener() {
      public void onClick(View view) {
            startTimer(view);
      }
}

9781430257462_Fig18-04.jpg

Figure 18-4. Coding our user interface button and startTimer( ) method in our TimePlanet.java Activity subclass

We will declare our startTimer( ) method with public access, so it is available for public usage, and with a void return value as it returns nothing to the calling entity, in this case, a click on the startTimerButton UI object.

Coding Our startTimer( ) Java Method

Next, we will declare our EditText user interface element for usage, and we will name it alarmText and use the findViewById( ) method to reference it to point to our setAlarm EditText tag XML definition via R.id.setAlarm.

Notice that if you have not imported the EditText class for use, that this code will have red underline highlighting, and that you can mouse-over it, and have Eclipse write this import statement Java code for you.

Next we declare an integer variable named i and set it equal to an Integer object, off of which we call the .parseInt( ) method. This method parses an integer value, by calling the .toString( ) conversion method, off of the .getText( ) method, which is called off of the alarmText EditText object to retrieve the text value that the user has entered into the data field. This is all done in a line of Java code that is written as follows:

int i = Integer.parseInt(alarmText.getText().toString());

Next, we declare an Intent object named intent, and construct a new Intent object, using the new keyword, using the current context this and a target component of the AlarmReceiver.class that we are going to code in the next section. For now, Eclipse red underline highlights this reference, as we have not as of yet created and coded this BroadcastReceiver subclass.

Next, we are going to create an Android PendingIntent object which we will name alarmIntent, and load with the Android alarm function, by calling the .getBroadcast( ) method off of the pendingIntent class using the parameters which configure our alarmIntent with the current context, an alarm request code, our intent Intent object that we just created in a previous line of code, and a zero value for the flags parameter, because at this time we are passing no flag values to this particular .getBroadcast( ) method call.

Notice that if you have not imported the PendingIntent class for use, that this code will have red underline highlighting, and that you should mouse-over it, and have Eclipse write the import statement Java code for you. If you want to research this PendingIntent class in further detail, you can find information on the Android Developer website, at the following URL:

http://developer.android.com/reference/android/app/PendingIntent.html

Next, we are going to create an Android AlarmManager object, which we will name alarmManager, and load this object using a getSystemService( ) method, which is called off of the AlarmManager class and passed the ALARM_SERVICE constant value as a parameter. This sets up an alarm function for us to use that is one of the many Android operating system functions that we can call, in that case by using the AlarmManager API.

Notice that if you have not imported the AlarmManager class for use, that this code will have red underline highlighting, and that you should mouse-over it, and have Eclipse write the import statement Java code for you. If you want to research this AlarmManager class in further detail, you can find information on the Android Developer website, at the following URL:

http://developer.android.com/reference/android/app/AlarmManager.html

Next we need to configure the alarmManager object we just created by using the AlarmManager class’s .set( ) method. We will pass the .set( ) method the three parameters it requires, an Integer (in this case a system constant), which represents the type of Alarm, a trigger time in milliseconds, which is represented by a long value, and a PendingIntent operation, in our case the alarmIntent that we created two lines of Java code previous to this.

AlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (I * 1000), alarmIntent);

Notice that we calculate the alarm trigger time in milliseconds inside the .set( ) method call, using the System.currentTimeMillis( ) method, which obtains a current system time in milliseconds, and adds that to the number of seconds, which the user entered in our EditText UI element, times 1000, to convert that seconds value to milliseconds, giving us the trigger time!

The final line of Java code in our startTimer( ) method uses an Android Toast object and a .makeText( ) method call to post our alarm setting confirmation message to the Activity screen using the following Java code:

Toast.makeText(this, "Alarm set in " + i + "seconds", Toast.LENGTH_SHORT).show();

Again we are using string value concatenation with our integer value i to display a Toast message that tells the user Alarm set in X seconds with the value that they entered, and then using method chaining at the end to append a .show( ) method call to the .makeText( ) method call to have the entire Toast object construct use only a single line of Java code.

We’re ready to create and code our AlarmReceiver class that will implement our onReceive( ) BroadcastReceiver method to make everything work together.

Creating Our AlarmReceiver BroadcastReceiver Subclass

Place your mouse over the red wavy underline error highlighting shown in Figure 18-4, and then select the Create AlarmReceiver Class option to have Eclipse create the New Java Class dialogs shown in Figure 18-5.

9781430257462_Fig18-05.jpg

Figure 18-5.  Having Eclipse create a New Java Class called AlarmReceiver using a Superclass Selection dialog

Because the Source folder:, Package:, and Name: data fields have already been filled in for us, simply click the Browse button, and type a “b” in the Choose a type: field located at the top of the Superclass Selection dialog and then scroll down to the BroadcastReceiver - android.content selection, found in the Matching items: section of the dialog, and select it as shown in Figure 18-5.

Finally, click the OK button, to return to the New Java Class dialog, and then click the Finish button in order to create your AlarmReceiver BroadcastReceiver subclass, which is shown in Figure 18-6.

9781430257462_Fig18-06.jpg

Figure 18-6.  Our AlarmReceiver.java BroadcastReceiver subclass infrastructure showing an onReceive( ) method

Notice that the onReceive( ) BroadcastReceiver method has been created for us, complete with access control and parameters in place and ready for us to write our Java code which will implement our BroadcastReceiver method’s alarm related functions.

Next we’ll replace the TODO Auto-generated method stub shown in Figure 18-6 with our code to send a message to the screen once our Broadcast is received.

Coding Our AlarmReceiver BroadcastReceiver Sublass

Let’s use the Android Toast class to send a message to the screen when our onReceive( ) method is called and received the Intent object that is broadcast over to it.

Use the Toast .makeText( ), method using the Context object that is passed into the onReceive( ) method as its first parameter and then specify the text message ALARM NOTIFICATION and finally a Toast.LENGTH_SHORT duration constant for the method parameters, then chain a .show( ) method call at the end of the Java code statement using the following single line of java code:

Toast.makeText(arg0, "ALARM NOTIFICATION", Toast.LENGTH_SHORT).show();

The completed AlarmReceiver BroadcastReceiver subclass and its onReceive( ) method is shown in Figure 18-7.

9781430257462_Fig18-07.jpg

Figure 18-7.  Coding our onReceive( ) method to display our Alarm Message in the AlarmReceiver.java class

The Java code for the AlarmReceiver BroadcastReceiver subclass looks like this:

package chapter.two.hello_world;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver  {
      @Override
      public void onReceive(Context arg0, Intent arg1) {
          Toast.makeText(arg0, "ALARM NOTIFICATION", Toast.LENGTH_SHORT).show();
      }
}

Now it is time to test our Broadcast Receiver implementation inside the Android Nexus S emulator, to see if all this XML and Java code that we wrote over the course of this chapter is working properly together.

Right-click the Hello_World project folder and select the Run As Android Application menu sequence to start up the Nexus S emulator so we can test our latest application revision.

When the Home Screen appears, click the Menu button to launch the Options Menu, and then select the Configure a Planet menu option to launch the Configure a Planet Activity screen.

At the bottom right of the screen, click the Atomic Clock button to launch your TimePlanet.java Activity user interface screen, and enter a timer duration value in seconds into the text data field under the Planet Earth Analog Clock user interface element.

Next, click the Start Timer Countdown button, which is located underneath the Enter Number of Seconds data entry field to send the Broadcast and start the AlarmManager object. The user interface for this screen is shown in Figure 18-8.

9781430257462_Fig18-08.jpg

Figure 18-8.  Testing our AlarmReceiver BroadcastReceiver subclass running in the Nexus S emulator

As you see, the BroadcastReceiver application component that we have now implemented works perfectly, and after that Toast message specifying our number of seconds to countdown appears, our ALARM NOTIFICATION Toast message subsequently appears on-screen after the number of seconds that we specified for our Alarm function have transpired, of course.

Congratulations! You have successfully implemented the three primary types of Android components: Activities, Services, and Broadcast Receivers! Cool! Take a break and grab a cool drink, and kick back for a bit and relax!

Now we have successfully implemented a Broadcast Receiver in our Android application, and the only type of component that we need to learn how to implement is a Content Provider, which we will learn about in the next chapter when we add content provider capabilities to our Hello World Android application!

Summary

In this chapter, we took a close look at the Android BroadcastReceiver Class and its onReceive( ) method.

We looked at the two different types of Broadcast Receiver broadcasts, normal broadcasts and ordered broadcasts, and we learned the difference between them, and when you would want to implement each type of broadcast.

Next we looked at the security considerations for Broadcast Receivers that stem from the fact that Broadcast Receivers are sent outside of your application and also allow other developer’s code inside of your application by their very nature.

Then we looked at the BroadcastReceiver lifecycle, and the basic rules and regulations regarding how you are allowed to use your onReceive( ) method call and Java code functions to process various types of Java programming objectives.

Next, we took a closer look at how the Android operating system processes Broadcast Receivers and how your use of them will affect your application process priority levels, which we learned about in Chapter 17.

We took a close look at the LocalBroadcastManager class used for localized broadcasting within an enclosed application environment, as well as how to dynamically (in Java method calls) and statically (in our Android Manifest XML mark-up) register broadcasts inside the Android operating system.

Finally, we took the plunge and implemented a Broadcast Receiver in our own Hello World application to implement a Timer function in our TimePlanet Activity. We added UI elements to our activity_time.xml file, added a new <receiver> tag to our AndroidMainfest.xml file, and finally implemented an AlarmReceiver BroadcastReceiver subclass and an onReceive( ) method.

In the next chapter we will learn all about Content Providers in Android, as well as the SQLite database engine. We saved the most complicated subjects for last so that you would have the maximum experience with Android before we dove into something as complex as building a DBMS engine using Android’s Content Provider APIs. Hold on to your hats! Here we go!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset