As I describe in the previous section, the AppWidgetProvider is essentially a translator. It receives a message from the Home screen app widget and responds with a result you specified. The AppWidgetProvider does not work with just any message, though. If you want to receive input from your app widget, you need to use a PendingIntent.
To understand what a PendingIntent is, you need to fully grasp the basic concept of intents and how they work.
An Intent object in Android is, well, exactly that: an intent. The best way to think about intents is to envision turning on a light with a light switch. Your intent is to turn on the light, and to do so, you perform the action of flipping the switch to the On position. In Android, this correlates to creating an instance of the Intent class with an Action in it specifying that the light is to be turned on, as shown here:
Intent turnLightOn = new Intent(“TURN_LIGHT_ON”);
You fire this intent into the Android messaging system, where an activity (or various different Activity objects) responds appropriately. (In the event many activities respond, Android lets the user choose which one to use.) In the case of your turnLightOn intent, you could provide code in the form of an activity (named TurnLightOnActivity, which is where the code executes) to respond by turning on the light.
As I mention in Chapter 3, an intent is a message that can carry a wide variety of data describing an operation that needs to be performed — that is, an Activity. Intents can be addressed to a specific activity or background service or — as I show you in this chapter — broadcast to a generic category of receivers known as BroadcastReceivers. When broadcast, the intent will be received only by BroadcastReceiver objects that understand how to respond to that intent. In this way, the Intent, Activity, and BroadcastReceiver system is like the well-known messaging structure called message bus architecture, in which a message is placed onto a “message bus” and one (or many) of the endpoints on the bus respond to the message if and only if they know how to. If each endpoint has no idea how to respond to the message, or if the message was not addressed to the endpoint, the message is ignored.
An intent can be launched in the following ways:
An activity can be thought of as the glue between various components of the application because it provides a late-binding mechanism that allows inter/intra-application communication.
An intent's primary data is as follows:
Table 8-1 demonstrates a few action and data parameters for Intent objects and their simple data structure.
For a list of some of the predefined intents in the Android system, see http://developer.android.com/guide/topics/intents/intents-filters.html.
Intents can also carry an array of other data that include the following:
Intents are evaluated in the Android system in one of two ways:
An example of this is setting up an e-mail intent that contains e-mail fields (To, CC, Subject, and Body) and an e-mail MIME type. Android interprets the intent as an e-mail intent and gives the user of the device the opportunity to choose which application should handle the intent — Gmail, Exchange, or a POP e-mail account that are all enabled on the device. This allows the user to determine from where the e-mail should originate. Android's feature of identifying the possible matches for the given intent is known as intent resolution.
On one level, a PendingIntent acts just like a regular intent. However, a PendingIntent allows the intent to be performed by another application.
A PendingIntent is created by your application and given to another completely different application. By giving another application a PendingIntent, you grant the other application the right to perform the specified operation as if the application was your own. In other words, a PendingIntent allows your application to perform work on another application's behalf. When an application executes the PendingIntent, it instructs the Android messaging system to inform your application to perform the necessary work.
For our purposes, to obtain a pending intent instance, I use the PendingIntent.getBroadcast() call. This call returns a PendingIntent that is used for broadcasts throughout the system. The call takes four parameters:
Wait a second — this looks a bit funky. This code uses an Intent as well as a PendingIntent. Why? The Intent object is wrapped inside a PendingIntent because a PendingIntent is used for cross-process communication. When the PendingIntent is fired off, the real work that needs to be done is wrapped up in the child Intent object.
When a user taps the button on the Home screen, the Home screen “app” sends a PendingIntent to the AppWidgetProvider in your application. At that time your app responds according to the instructions contained in the Intent that is part of the PendingIntent (Brighten screen, dim, and so on). The app then brightens the screen and sends instructions to the app widget via the AppWidgetManager to update its icon. The AppWidgetManager updates the icon via a RemoteView, which also contains a new PendingIntent (which contains a regular Intent) that will be executed the next time the user taps the Home screen widget.
Whoa, that was a lot of information! Now that you understand the basics of the Android intent system, you can implement the guts of the application inside this app widget.
13.59.145.158