This simple application shows how to setup a Home screen widget using a simple hello world like host application. The widget will display the default application icon with a clickable button next to it. When the button is pressed, the host application will be launched and a greeting appears.
There are four things that we must do to create a widget.
Create a layout resource that defines the UI for our widget.
Create an XML file that describes the metadata of our widget.
Create an Intent Receiver or AppWidgetProvider that maintains and controls our widget
Declare your application widget in the application manifest.
Click here to download the source file. Steps 1, 2, and 4 are already implemented. You will implement step 3. First we will take a look at steps 1 and 2.
Open up the simple_widget.xml file located in res/layout. This is the UI layout for our widget. You will notice that we have in our LinearLayout an ImageView with an image source that points to drawable/icon. This is the default app icon. You’ll also notice that we have a button.
Notice the id for our button and root layout. We will be referencing these later.
If you click on the layouts tab right above the console in Eclipse IDE, you will see a preview of what the widget will look like.
Open up the simple_widget_info.xml file in res/xml. This file defines the metadata of our widget.
minWidth and minHeight specifies the minimum area required by our widget layout.
updatePeriodMillis specifies the time interval that our widget will be updating itself. For this app, we won’t be doing any updating. However, when an update occurs the onUpdate method will be called from our custom SimpleWidgetProvider class that you will be impelementing.
initialLayout specifies the layout that we will be using for our widget. As you can see, it points to simple_widget which is the UI layout we just made in step 1!
Now open the SimpleWidgetProvider.java file located in the src folder. The SimpleWidgetProvider class is an Intent Receiver that has been simplified by extending the AppWidgetProvider class. This class includes several callbacks to handle widget events, but for this app. we will only override onUpdate. The other callbacks are:
onUpdate: this is called to update the widget in time intervals defined by “updatePeriodMillis” in the simple_widget_info.xml file we made in step 2.
onDeleted: this is called whenever a widget is deleted from the home screen or host view.
onEnabled: this is called ONCE when a widget is created for the first time.
onDisabled: this is called when the last instance of the widget is deleted. Do clean up stuff here.
onReceive: this is called before each of the above methods and for every broadcast intent.
First you’ll notice that inside the onUpdate method is a for loop. It loops through all the widget IDs returned so that if more than one widget is open on the home screen, we can update all of them.
Inside the for loop:
Set an integer value equal to the i-th index of appWidgetIds. This saves the current widget ID we're iterating on.
Create a new Intent to launch SimpleWidget Activity. Use onUpdate's context parameter and SimpleWidget.class as parameters to this new Intent.
Create a new PendingIntent. Set it equal to a call to PendingIntent.getActivity. Use onUpdate's context parameter for the first parameter, 0 for the second parameter, the intent we just created as the third, and 0 for the last parameter.
Get the layout for the App Widget and attach an on-click listener to the button. To do that you need to create a new RemoteView with the package name from the context passed by onUpdate and the layout for our widget (R.layout.simple_widget) as parameters. To get the package name from the context, make a call to getPackageName with the context from onUpdate's context parameter.
Have our new RemoteViews call setOnClickPendingIntent with the first parameter specifying the resource id for our widget button (R.id.widget_button) and the second parameter being the PendingIntent we just made. This sets the click listener for our widget button.
Make a call to updateAppWidget with the appWidgetManager parameter from onUpdate. Pass in the widget ID we saved at the beginning of the loop, and set the second parameter to the RemoteViews we just created. This tells the AppWidgetManager to perform an update on the current App Widget.
Open the AndroidManigest.xml file. You’ll notice that there is a receiver element with an intent-filter and metadata element specified within it.
The receiver needs an android:name. This specifies the SimpleWidgetProvider we just implemented.
The intent filter specifies that our SimpleWidgetProvider will accept the ACTION_APPWIDGET_UPDATE broadcast.
The meta-data element specifies the metadata name/descriptor and it’s location and appropriately points to simple_widget_info.xml.
To add a widget to the home screen:
Long click on the home screen and a menu will appear with the Widget option.
Click on the Widget option and a list of available widgets will appear.
Scroll to the bottom of the widgets list and you should see “Simple Widget”.
Click on “Simple Widget” and the widget should appear. The widget should look similar to the image below.
If you look further in the src folder, you’ll notice the SimpleWidget.java file. This Activity class does nothing and is essentially the entry point into your application. Feel free to tinker around with it as well as the layout and interfaces of the Widget.
For more information on Widgets, check out the Android developers guide on it.
Android Developers: App Widgets
Also check out the Widget design Guidelines.