page.title=App Widgets @jd:body

Quickview

In this document

  1. The Basics
  2. Declaring an App Widget in the Manifest
  3. Adding the AppWidgetProviderInfo Metadata
  4. Creating the App Widget Layout
  5. Using the AppWidgetProvider Class
    1. Receiving App Widget broadcast Intents
  6. Creating an App Widget Configuration Activity
    1. Updating the App Widget from the configuration Activity

Key classes

  1. {@link android.appwidget.AppWidgetProvider}
  2. {@link android.appwidget.AppWidgetProviderInfo}
  3. {@link android.appwidget.AppWidgetManager}

See also

  1. App Widget Design Guidelines
  2. Introducing home screen widgets and the AppWidget framework »

App Widgets are miniature application views that can be embedded in other applications (such as the Home screen) and receive periodic updates. These views are referred to as Widgets in the user interface, and you can publish one with an App Widget provider. An application component that is able to hold other App Widgets is called an App Widget host. The screenshot below shows the Music App Widget.

This document describes how to publish an App Widget using an App Widget provider.

The Basics

To create an App Widget, you need the following:

{@link android.appwidget.AppWidgetProviderInfo} object
Describes the metadata for an App Widget, such as the App Widget's layout, update frequency, and the AppWidgetProvider class. This should be defined in XML.
{@link android.appwidget.AppWidgetProvider} class implementation
Defines the basic methods that allow you to programmatically interface with the App Widget, based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated, enabled, disabled and deleted.
View layout
Defines the initial layout for the App Widget, defined in XML.

Additionally, you can implement an App Widget configuration Activity. This is an optional {@link android.app.Activity} that launches when the user adds your App Widget and allows him or her to modify App Widget settings at create-time.

The following sections describe how to setup each of these components.

Declaring an App Widget in the Manifest

First, declare the {@link android.appwidget.AppWidgetProvider} class in your application's AndroidManifest.xml file. For example:

<receiver android:name="ExampleAppWidgetProvider" >
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/example_appwidget_info" />
</receiver>

The <receiver> element requires the android:name attribute, which specifies the {@link android.appwidget.AppWidgetProvider} used by the App Widget.

The <intent-filter> element must include an <action> element with the android:name attribute. This attribute specifies that the {@link android.appwidget.AppWidgetProvider} accepts the {@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE ACTION_APPWIDGET_UPDATE} broadcast. This is the only broadcast that you must explicitly declare. The {@link android.appwidget.AppWidgetManager} automatically sends all other App Widget broadcasts to the AppWidgetProvider as necessary.

The <meta-data> element specifies the {@link android.appwidget.AppWidgetProviderInfo} resource and requires the following attributes:

Adding the AppWidgetProviderInfo Metadata

The {@link android.appwidget.AppWidgetProviderInfo} defines the essential qualities of an App Widget, such as its minimum layout dimensions, its initial layout resource, how often to update the App Widget, and (optionally) a configuration Activity to launch at create-time. Define the AppWidgetProviderInfo object in an XML resource using a single <appwidget-provider> element and save it in the project's res/xml/ folder.

For example:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="86400000"
    android:initialLayout="@layout/example_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigure" >
</appwidget-provider>

Here's a summary of the <appwidget-provider> attributes:

See the {@link android.appwidget.AppWidgetProviderInfo} class for more information on the attributes accepted by the <appwidget-provider> element.

Creating the App Widget Layout

You must define an initial layout for your App Widget in XML and save it in the project's res/layout/ directory. You can design your App Widget using the View objects listed below, but before you begin designing your App Widget, please read and understand the App Widget Design Guidelines.

Creating the App Widget layout is simple if you're familiar with Declaring Layout in XML. However, you must be aware that App Widget layouts are based on {@link android.widget.RemoteViews}, which do not support every kind of layout or view widget.

A RemoteViews object (and, consequently, an App Widget) can support the following layout classes:

And the following widget classes:

Descendants of these classes are not supported.

Using the AppWidgetProvider Class

The {@link android.appwidget.AppWidgetProvider} class extends BroadcastReceiver as a convenience class to handle the App Widget broadcasts. The AppWidgetProvider receives only the event broadcasts that are relevant to the App Widget, such as when the App Widget is updated, deleted, enabled, and disabled. When these broadcast events occur, the AppWidgetProvider receives the following method calls:

{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])}
This is called to update the App Widget at intervals defined by the updatePeriodMillis attribute in the AppWidgetProviderInfo (see Adding the AppWidgetProviderInfo Metadata above). This method is also called when the user adds the App Widget, so it should perform the essential setup, such as define event handlers for Views and start a temporary {@link android.app.Service}, if necessary. However, if you have declared a configuration Activity, this method is not called when the user adds the App Widget, but is called for the subsequent updates. It is the responsibility of the configuration Activity to perform the first update when configuration is done. (See Creating an App Widget Configuration Activity below.)
{@link android.appwidget.AppWidgetProvider#onDeleted(Context,int[])}
This is called every time an App Widget is deleted from the App Widget host.
{@link android.appwidget.AppWidgetProvider#onEnabled(Context)}
This is called when an instance the App Widget is created for the first time. For example, if the user adds two instances of your App Widget, this is only called the first time. If you need to open a new database or perform other setup that only needs to occur once for all App Widget instances, then this is a good place to do it.
{@link android.appwidget.AppWidgetProvider#onDisabled(Context)}
This is called when the last instance of your App Widget is deleted from the App Widget host. This is where you should clean up any work done in {@link android.appwidget.AppWidgetProvider#onEnabled(Context)}, such as delete a temporary database.
{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)}
This is called for every broadcast and before each of the above callback methods. You normally don't need to implement this method because the default AppWidgetProvider implementation filters all App Widget broadcasts and calls the above methods as appropriate.

Note: In Android 1.5, there is a known issue in which the onDeleted() method will not be called when it should be. To work around this issue, you can implement {@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent) onReceive()} as described in this Group post to receive the onDeleted() callback.

The most important AppWidgetProvider callback is {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[]) onUpdated()} because it is called when each App Widget is added to a host (unless you use a configuration Activity). If your App Widget accepts any user interaction events, then you need to register the event handlers in this callback. If your App Widget doesn't create temporary files or databases, or perform other work that requires clean-up, then {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[]) onUpdated()} may be the only callback method you need to define. For example, if you want an App Widget with a button that launches an Activity when clicked, you could use the following implementation of AppWidgetProvider:

public class ExampleAppWidgetProvider extends AppWidgetProvider {

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;

        // Perform this loop procedure for each App Widget that belongs to this provider
        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];

            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, ExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

            // Get the layout for the App Widget and attach an on-click listener to the button
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);

            // Tell the AppWidgetManager to perform an update on the current App Widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }
}

This AppWidgetProvider defines only the {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[]) onUpdated()} method for the purpose of defining a {@link android.app.PendingIntent} that launches an {@link android.app.Activity} and attaching it to the App Widget's button with {@link android.widget.RemoteViews#setOnClickPendingIntent(int,PendingIntent)}. Notice that it includes a loop that iterates through each entry in appWidgetIds, which is an array of IDs that identify each App Widget created by this provider. In this way, if the user creates more than one instance of the App Widget, then they are all updated simultaneously. However, only one updatePeriodMillis schedule will be managed for all instances of the App Widget. For example, if the update schedule is defined to be every two hours, and a second instance of the App Widget is added one hour after the first one, then they will both be updated on the period defined by the first one and the second update period will be ignored (they'll both be updated every two hours, not every hour).

Note: Because the AppWidgetProvider is a BroadcastReceiver, your process is not guaranteed to keep running after the callback methods return (see Application Fundamentals > Broadcast Receiver Lifecycle for more information). If your App Widget setup process can take several seconds (perhaps while performing web requests) and you require that your process continues, consider starting a {@link android.app.Service} in the {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[]) onUpdated()} method. From within the Service, you can perform your own updates to the App Widget without worrying about the AppWidgetProvider closing down due to an Application Not Responding (ANR) error. See the Wiktionary sample's AppWidgetProvider for an example of an App Widget running a {@link android.app.Service}.

Also see the ExampleAppWidgetProvider.java sample class.

Receiving App Widget broadcast Intents

{@link android.appwidget.AppWidgetProvider} is just a convenience class. If you would like to receive the App Widget broadcasts directly, you can implement your own {@link android.content.BroadcastReceiver} or override the {@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)} callback. The four Intents you need to care about are:

Creating an App Widget Configuration Activity

If you would like the user to configure settings when he or she adds a new App Widget, you can create an App Widget configuration Activity. This {@link android.app.Activity} will be automatically launched by the App Widget host and allows the user to configure available settings for the App Widget at create-time, such as the App Widget color, size, update period or other functionality settings.

The configuration Activity should be declared as a normal Activity in the Android manifest file. However, it will be launched by the App Widget host with the {@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE ACTION_APPWIDGET_CONFIGURE} action, so the Activity needs to accept this Intent. For example:

<activity android:name=".ExampleAppWidgetConfigure">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
    </intent-filter>
</activity>

Also, the Activity must be declared in the AppWidgetProviderInfo XML file, with the android:configure attribute (see Adding the AppWidgetProviderInfo Metadata above). For example, the configuration Activity can be declared like this:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:configure="com.example.android.ExampleAppWidgetConfigure" 
    ... >
</appwidget-provider>

Notice that the Activity is declared with a fully-qualified namespace, because it will be referenced from outside your package scope.

That's all you need to get started with a configuration Activity. Now all you need is the actual Activity. There are, however, two important things to remember when you implement the Activity:

See the code snippets in the following section for an example of how to return a result from the configuration and update the App Widget.

Updating the App Widget from the configuration Activity

When an App Widget uses a configuration Activity, it is the responsibility of the Activity to update the App Widget when configuration is complete. You can do so by requesting an update directly from the {@link android.appwidget.AppWidgetManager}.

Here's a summary of the procedure to properly update the App Widget and close the configuration Activity:

  1. First, get the App Widget ID from the Intent that launched the Activity:
    Intent intent = getIntent();
    Bundle extras = intent.getExtras();
    if (extras != null) {
        mAppWidgetId = extras.getInt(
                AppWidgetManager.EXTRA_APPWIDGET_ID, 
                AppWidgetManager.INVALID_APPWIDGET_ID);
    }
    
  2. Perform your App Widget configuration.
  3. When the configuration is complete, get an instance of the AppWidgetManager by calling {@link android.appwidget.AppWidgetManager#getInstance(Context)}:
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    
  4. Update the App Widget with a {@link android.widget.RemoteViews} layout by calling {@link android.appwidget.AppWidgetManager#updateAppWidget(int,RemoteViews)}:
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
    appWidgetManager.updateAppWidget(mAppWidgetId, views);
    
  5. Finally, create the return Intent, set it with the Activity result, and finish the Activity:
  6. Intent resultValue = new Intent();
    resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
    setResult(RESULT_OK, resultValue);
    finish();
    

Tip: When your configuration Activity first opens, set the Activity result to RESULT_CANCELED. This way, if the user backs-out of the Activity before reaching the end, the App Widget host is notified that the configuration was cancelled and the App Widget will not be added.

See the ExampleAppWidgetConfigure.java sample class in ApiDemos for an example.