diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs index 5367cb2e7ec55..a044ceaecd3b9 100644 --- a/docs/html/guide/guide_toc.cs +++ b/docs/html/guide/guide_toc.cs @@ -95,7 +95,7 @@ --> -
AppWidgets are miniature application views that can be embedded in other applications -(e.g., the Home). These views are called "widgets" and you can publish one with -an "AppWidget provider." An application component that is able to hold other widgets is -called an "AppWidget host."
+ +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.
+To create an App Widget, you need the following:
+ +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.
-Any application can publish widgets. All an application needs to do to publish a widget is -to have a {@link android.content.BroadcastReceiver} that receives the {@link -android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} intent, -and provide some meta-data about the widget. Android provides the -{@link android.appwidget.AppWidgetProvider} class, which extends BroadcastReceiver, as a convenience -class to aid in handling the broadcasts. +
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> +-
First, declare the {@link android.content.BroadcastReceiver} in your application's
-AndroidManifest.xml file.
+
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 <receiver> element has the following attributes:
+
The <meta-data> element specifies the
+{@link android.appwidget.AppWidgetProviderInfo} resource and requires the
+following attributes:
android:name - specifies the
- {@link android.content.BroadcastReceiver} or {@link android.appwidget.AppWidgetProvider}
- class.android:label - specifies the string resource that
- will be shown by the widget picker as the label.android:icon - specifies the drawable resource that
- will be shown by the widget picker as the icon.
-The <intent-filter> element tells the {@link android.content.pm.PackageManager}
-that this {@link android.content.BroadcastReceiver} receives the {@link
-android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} broadcast.
-The widget manager will send other broadcasts directly to your widget provider as required.
-It is only necessary to explicitly declare that you accept the {@link
-android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} broadcast.
-
-
-The <meta-data> element tells the widget manager which xml resource to
-read to find the {@link android.appwidget.AppWidgetProviderInfo} for your widget provider. It has the following
-attributes:
-
android:name="android.appwidget.provider" - identifies this meta-data
- as the {@link android.appwidget.AppWidgetProviderInfo} descriptor.android:resource - is the xml resource to use as that descriptor.android:name - Specifies the metadata name. Use android.appwidget.provider
+ to identify the data as the {@link android.appwidget.AppWidgetProviderInfo} descriptor.android:resource - Specifies the {@link android.appwidget.AppWidgetProviderInfo}
+ resource location.For a widget, the values in the {@link android.appwidget.AppWidgetProviderInfo} structure are supplied
-in an XML resource. In the example above, the xml resource is referenced with
-android:resource="@xml/appwidget_info". That XML file would go in your application's
-directory at res/xml/appwidget_info.xml. Here is a simple example.
+
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:
-The attributes are as documented in the -{@link android.appwidget.AppWidgetProviderInfo} class. +
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" + android:minWidth="294dp" <!-- density-independent pixels --> + android:minHeight="72dp" + android:updatePeriodMillis="86400000" <!-- once per day --> + android:initialLayout="@layout/example_appwidget" + android:configure="com.example.android.ExampleAppWidgetConfigure" > +</appwidget-provider> ++ +
Here's a summary of the <appwidget-provider> attributes:
minWidth and minHeight attributes specify the minimum
+ area required by the App Widget's layout.
+ The default Home screen positions App Widgets in its window based on a grid of + cells that have a defined height and width. If the values for an App Widget's minimum width + or height don't match the dimensions of the cells, + then the App Widget dimensions round up to the nearest cell size. + (See the App Widget Design + Guidelines for more information on the Home screen cell sizes.)
+Because the Home screen's layout orientation (and thus, the cell sizes) can change,
+ as a rule of thumb, you should assume the worst-case cell size of 74 pixels for the height
+ and width of a cell. However, you must subtract 2 from the final dimension to account
+ for any integer rounding errors that occur in the pixel count. To find your minimum width
+ and height in density-independent pixels (dp), use this formula:
+ (number of cells * 74) - 2
+ Following this formula, you should use 72 dp for a height of one cell, 294 dp and for a width of four cells.
updatePerdiodMillis attribute defines how often the App Widget framework should
+ request an update from the {@link android.appwidget.AppWidgetProvider} by calling the
+ {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
+ onUpdate()} method. The actual update is not guaranteed to occur exactly on time with this value
+ and we suggest updating as infrequently as possible—perhaps no more than once an hour to
+ conserve the battery. You might also allow the user to adjust the frequency in a
+ configuration—some people might want a stock ticker to update every 15 minutes, or maybe
+ only four times a day.initialLayout attribute points to the layout resource that defines the
+ App Widget layout.configure attribute defines the {@link android.app.Activity} to launch when
+ the user adds the App Widget, in order for him or her to configure App Widget properties. This is optional
+ (read Creating an App Widget Configuration Activity below).See the {@link android.appwidget.AppWidgetProviderInfo} class for more information on the
+attributes accepted by the <appwidget-provider> element.
The AppWidgetProvider class is the easiest way to handle the widget provider intent broadcasts.
-See the src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.java
-sample class in ApiDemos for an example.
+
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.
Keep in mind that since the 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. +
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.
+You must declare your AppWidgetProvider class implementation as a broadcast receiver
+ using the <receiver> element in the AndroidManifest (see
+ Declaring an App Widget in the Manifest above).
-Widget hosts have the ability to start a configuration activity when a widget is instantiated.
-The activity should be declared as normal in AndroidManifest.xml, and it should be listed in
-the AppWidgetProviderInfo XML file in the android:configure attribute.
+
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:
-The activity you specified will be launched with the {@link -android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE} action. See the documentation for that -action for more info. +
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.)See the src/com/example/android/apis/appwidget/ExampleAppWidgetConfigure.java
-sample class in ApiDemos for an example.
+
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.
- -{@link android.appwidget.AppWidgetProvider} is just a convenience class. If you would like -to receive the widget broadcasts directly, you can. The four intents you need to care about are: +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:
By way of example, the implementation of -{@link android.appwidget.AppWidgetProvider#onReceive} is quite simple:
- -{@sample frameworks/base/core/java/android/appwidget/AppWidgetProvider.java onReceive} -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 AppWidgetProvierInfo 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.
+ + +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:
+ +
+Intent intent = getIntent();
+Bundle extras = intent.getExtras();
+if (extras != null) {
+ mAppWidgetId = extras.getInt(
+ AppWidgetManager.EXTRA_APPWIDGET_ID,
+ AppWidgetManager.INVALID_APPWIDGET_ID);
+}
+
+ +AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); ++
+RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget); +appWidgetManager.updateAppWidget(mAppWidgetId, views); ++
+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.
+ + -Widget hosts are the containers in which widgets can be placed. Most of the look and feel -details are left up to the widget hosts. For example, the home screen has one way of viewing -widgets, but the lock screen could also contain widgets, and it would have a different way of -adding, removing and otherwise managing widgets.
-For more information on implementing your own widget host, see the -{@link android.appwidget.AppWidgetHost AppWidgetHost} class.
diff --git a/docs/html/images/appwidget.png b/docs/html/images/appwidget.png new file mode 100644 index 0000000000000..b72b80b1d332b Binary files /dev/null and b/docs/html/images/appwidget.png differ