Since version 1.5, the Android SDK includes the AppWidget framework, a framework that allows developers to write “widgets” that people can drop onto their home screen and interact with. The use of widgets is very handy since it allows the user to add their favorite applications into their home screen and interact with them quickly and without having to launch the whole application. Before continuing, I suggest taking a look at the article “Introducing home screen widgets and the AppWidget framework” posted at the official Android developers blog. An example of a widget is shown in the next image. It is the one built for the purposes of the article and it gives updates on the “Word of the day”. The source code for that can be found here.

For our application, we are going to create a widget which periodically provides updates on the latest movie created in the TMDb database. As I have mentioned in the past, we have been using the very cool TMDb API for movie/actors search and various other related functions.

The first step to creating the app widget is to provide a declaration for it as well as some XML metadata that describe it. This is done by adding a special XML file in the “res/xml” folder of our project. Through that file, we provide information regarding the widget’s dimensions, its update interval etc. The corresponding class is named AppWidgetProviderInfo and its fields correspond to the fields in the XML tag we are going to see below. For the height and width of the widget, Google recommends using a specific formula:

Minimum size in dip = (Number of cells * 74dip) – 2dip

Since we wish our widget to occupy 2 cells in width and 1 cell in height, the sizes in dip are going to be 146 and 72 respectively. The update interval is defined in milliseconds and for demonstration purposes we are using only 10 seconds (10000 millis). However, please note that short interval are discouraged. More specifically, updating more frequently than every hour can quickly eat up battery and bandwidth.

UPDATE: For this very reason of avoiding battery exhaustion, Google has changed its API after version 1.6 so that the refresh rate can not be less than 30 minutes. If you wish to achieve more frequent updates, the alarm mechanism has to be used in order to send intent broadcast to your widget receiver. You can find an example of this approach in the post “App Widget using Alarm Manager“.

Last but not least, a layout has to be used so that we can handle how the widget will be rendered. This will be done by referencing an other XML file, named “widget_layout.xml”.

The XML widget declaration file is named “movie_search_widget.xml” and it is the following:

The layout is pretty simple. We are using RelativeLayout, where the positions of the children can be described in relation to each other or to the parent, and a couple of TextViews. Note that the style used is actually defined in a different file (“res/values/styles.xml”) in order to gather all style related attributes in one place. The style declarations are the following:

The next step is to register a special BroadcastReceiver in the AndroidManifest.xml file. This receiver will process any app widget updates that will be triggered by the system when the time comes. Let’s see the corresponding manifest file snippet:

The receiver class is the “com.javacodegeeks.android.apps.moviesearchapp.widget.MovieSearchWidget” which will actually use an inner service class (“UpdateService”) in order to perform the updates. Note that the actions handled by that receiver are of kind APPWIDGET_UPDATE, which is sent when it is time for the AppWidget update. In the metadata section, the widget declaration XML file location is defined.

Now let’s write the class that will receive the AppWidget requests and provide the application updates. To do so, we extend the AppWidgetProvider class, which in its turn extends the BroadcastReceiver class. Actually, the AppWidgetProvider is just a convenience class to aid in implementing an AppWidget provider and its whole functionality could be achieved by a regular BroadcastReceiver.

There are five basic methods that can be overriden in order to handle the various action requests:

onEnabled: Called when the first App Widget is created. Global initialization should take place here, if any.

onDisabled: Called when the last App Widget handled by this definition is deleted. Global cleanup should take place here, if any.

onUpdate: Called when the App Widget needs to update its View, which could be when the user first creates the widget. This is the most commonly used method.

onDeleted: Called when one or more instances of this App Widget are deleted. Cleanup for the specific instances should occur here.

onReceive: Handles the BroadcastReceiver actions and dispatches the requests to the methods above.

As mentioned, we override the onUpdate method and inside that, we just start a new Service that will actually provide the updates. This is done in order to perform the time consuming actions (open network connections, downloading data etc.) in an other thread, thus avoiding any ANR timeouts. In our service, we implement the onStart method. Note that this method is now deprecated and the onStartCommand should be used. Since I am using the Android 1.5 SDK, I am going to stick with the onStart method.

For our application, I use a new method from the MovieSeeker class, which has been enhanced in order to also provide the latest movie (we will see that later). Next, we construct a RemoteViews object which will describe the view that will be displayed in another process (i.e. by the home screen). In its constructor, we provide the package name (taken by the relevant Context) and the ID of the layout that the view uses (in our case “widget_layout”). Note that we cannot directly manipulate any child views of the layout, for example by setting the view’s text or registering listeners. For that reason, we are going to use the setTextViewText method in order to provide the TextView‘s text and the setOnClickPendingIntent method in order to provide a handler for the click events.

We want to launch the browser and point to the movie’s IMDB page every time the user clicks on the widget. In order to achieve this, we first create an Intent of action ACTION_VIEW and the page’s URL as data. That intent is then encapsulated inside a PendingIntent and it is the pending intent that is used as the click handler.

Before launching the application, let’s see how the latest movie is retrieved. Recall that the MovieSeeker class is used for movies search. We have added a method named “findLatest” to that class which uses the Movie.getLatest API call of the TMDb API. Since the response from that call does not match the format of the existing movie search responses, we have to create an additional XML handler, called “SingleMovieHandler”. You can find the full changes in the project available for downloading at the end of this article.

Now launch the corresponding Eclipse project configuration. The emulator will probably take you straight to the application itself. Rather, hit the back button in order to return to the home screen. Check the article on how to add and remove app widgets. For the emulator, you basically have to click on an empty area and not release the mouse button. Then, the following dialog will pop-up:

Choose “Widgets” and then select the “MovieSearchAppWidget”:

When the widget gets inserted in the home screen, the relevant update method will be executed and the latest movie will be fetched. This is how the home screen will look like:

Finally, if you double click on the movie’s name, the pending intent will be fired and the Android browser will launch directed to the movies IMDB page (note that some movies will not have an associated IMDB ID and page. In that case the browser will take you to a broken IMDB page).

That’s it. AppWidget for your application. You can download here the Eclipse project created so far.

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial3>

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

and many more ....

10 comments

my question is that when i open the emulator the google and music widget is by default already on home screen…so i also want that same thing for my widget that when i open my emulator i can see my widget like google and music… plzzz help me and reply… i searched every where but i found nothing…

@Devendra Chouksey : You must have seen your app icon inside menu click the icon [LONG press] it automatically gives you option to put that on home screen and then onwards all the time you start ur emulator you can see your app icon to start with

Newsletter

Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

Email address:

Recent Jobs

No job listings found.

Join Us

With 1,240,600 monthly unique visitors and over 500 authors we are placed among the top Java related sites around. Constantly being on the lookout for partners; we encourage you to join us. So If you have a blog with unique and interesting content then you should check out our JCG partners program. You can also be a guest writer for Java Code Geeks and hone your writing skills!

Disclaimer

All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners. Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. Examples Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.