index.jd revision 843ef36f7b96cc19ea7d2996b7c8661b41ec3452
1page.title=App Widgets
2@jd:body
3
4<div id="qv-wrapper">
5  <div id="qv">
6    <h2>Key classes</h2>
7    <ol>
8      <li>{@link android.appwidget.AppWidgetProvider}</li>
9      <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
10      <li>{@link android.appwidget.AppWidgetManager}</li>
11    </ol>
12    <h2>In this document</h2>
13    <ol>
14      <li><a href="#Basics">The Basics</a></li>
15      <li><a href="#Manifest">Declaring an App Widget in the Manifest</a></li>
16      <li><a href="#MetaData">Adding the AppWidgetProviderInfo Metadata</a></li>
17      <li><a href="#CreatingLayout">Creating the App Widget Layout</a></li>
18      <li><a href="#AppWidgetProvider">Using the AppWidgetProvider Class</a>
19        <ol>
20          <li><a href="#ProviderBroadcasts">Receiving App Widget broadcast Intents</a></li>
21        </ol>
22      </li>
23      <li><a href="#Configuring">Creating an App Widget Configuration Activity</a>
24        <ol>
25          <li><a href="#UpdatingFromTheConfiguration">Updating the App Widget from 
26            the configuration Activity</a></li>
27        </ol>
28      </li>
29    </ol>
30
31    <h2>See also</h2>
32    <ol>
33      <li><a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design 
34        Guidelines</a></li>
35      <li><a href="http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html">Introducing
36        home screen widgets and the AppWidget framework &raquo;</a></li>
37    </ol>
38  </div>
39</div>
40
41
42<p>App Widgets are miniature application views that can be embedded in other applications
43(such as the Home screen) and receive periodic updates. These views are referred 
44to as Widgets in the user interface,
45and you can publish one with an App Widget provider. An application component that is 
46able to hold other App Widgets is called an App Widget host. The screenshot below shows
47the Music App Widget.</p>
48
49<img src="{@docRoot}images/appwidget.png" alt="" />
50
51<p>This document describes how to publish an App Widget using an App Widget provider.</p>
52
53
54<h2 id="Basics">The Basics</h2>
55
56<p>To create an App Widget, you need the following:</p>
57
58<dl>
59  <dt>{@link android.appwidget.AppWidgetProviderInfo} object</dt>
60  <dd>Describes the metadata for an App Widget, such as the App Widget's layout, update frequency,
61    and the AppWidgetProvider class. This should be defined in XML.</dd>
62  <dt>{@link android.appwidget.AppWidgetProvider} class implementation</dt>
63  <dd>Defines the basic methods that allow you to programmatically interface with the App Widget,
64    based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated, 
65    enabled, disabled and deleted.</dd>
66  <dt>View layout</dt>
67  <dd>Defines the initial layout for the App Widget, defined in XML.</dd>
68</dl>
69
70<p>Additionally, you can implement an App Widget configuration Activity. This is an optional 
71{@link android.app.Activity} that launches when the user adds your App Widget and allows him or her
72to modify App Widget settings at create-time.</p>
73
74<p>The following sections describe how to setup each of these components.</p>
75
76
77<h2 id="Manifest">Declaring an App Widget in the Manifest</h2>
78
79<p>First, declare the {@link android.appwidget.AppWidgetProvider} class in your application's
80<code>AndroidManifest.xml</code> file. For example:</p>
81
82<pre>
83&lt;receiver android:name="ExampleAppWidgetProvider" >
84    &lt;intent-filter>
85        &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
86    &lt;/intent-filter>
87    &lt;meta-data android:name="android.appwidget.provider"
88               android:resource="@xml/example_appwidget_info" />
89&lt;/receiver>
90</pre>
91
92<p>The <code>&lt;receiver&gt;</code> element requires the <code>android:name</code> 
93attribute, which specifies the {@link android.appwidget.AppWidgetProvider} used
94by the App Widget.</p>
95
96<p>The <code>&lt;intent-filter&gt;</code> element must include an <code>&lt;action></code>
97element with the <code>android:name</code> attribute. This attribute specifies
98that the {@link android.appwidget.AppWidgetProvider} accepts the {@link
99android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE ACTION_APPWIDGET_UPDATE} broadcast.
100This is the only broadcast that you must explicitly declare. The {@link android.appwidget.AppWidgetManager}
101automatically sends all other App Widget broadcasts to the AppWidgetProvider as necessary.</p>
102
103<p>The <code>&lt;meta-data&gt;</code> element specifies the
104{@link android.appwidget.AppWidgetProviderInfo} resource and requires the 
105following attributes:</p>
106<ul>
107  <li><code>android:name</code> - Specifies the metadata name. Use <code>android.appwidget.provider</code>
108    to identify the data as the {@link android.appwidget.AppWidgetProviderInfo} descriptor.</li>
109  <li><code>android:resource</code> - Specifies the {@link android.appwidget.AppWidgetProviderInfo} 
110    resource location.</li>
111</ul>
112
113
114<h2 id="MetaData">Adding the AppWidgetProviderInfo Metadata</h2>
115
116<p>The {@link android.appwidget.AppWidgetProviderInfo} defines the essential 
117qualities of an App Widget, such as its minimum layout dimensions, its initial layout resource,
118how often to update the App Widget, and (optionally) a configuration Activity to launch at create-time.
119Define the AppWidgetProviderInfo object in an XML resource using a single
120<code>&lt;appwidget-provider></code> element and save it in the project's <code>res/xml/</code> 
121folder.</p>
122
123<p>For example:</p>
124
125<pre>
126&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
127    android:minWidth="294dp" &lt;!-- density-independent pixels --&gt;
128    android:minHeight="72dp"
129    android:updatePeriodMillis="86400000" &lt;!-- once per day --&gt;
130    android:initialLayout="@layout/example_appwidget"
131    android:configure="com.example.android.ExampleAppWidgetConfigure" >
132&lt;/appwidget-provider>
133</pre>
134
135<p>Here's a summary of the <code>&lt;appwidget-provider></code> attributes:</p>
136<ul>
137  <li>The values for the <code>minWidth</code> and <code>minHeight</code> attributes specify the minimum
138    area required by the App Widget's layout.
139    <p>The default Home screen positions App Widgets in its window based on a grid of
140    cells that have a defined height and width. If the values for an App Widget's minimum width 
141    or height don't match the dimensions of the cells,
142    then the App Widget dimensions round <em>up</em> to the nearest cell size.
143    (See the <a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design 
144    Guidelines</a> for more information on the Home screen cell sizes.)</p>
145    <p>Because the Home screen's layout orientation (and thus, the cell sizes) can change,
146    as a rule of thumb, you should assume the worst-case cell size of 74 pixels for the height
147    <em>and</em> width of a cell. However, you must subtract 2 from the final dimension to account
148    for any integer rounding errors that occur in the pixel count. To find your minimum width
149    and height in density-independent pixels (dp), use this formula:<br/>
150      <code>(number of cells * 74) - 2</code><br/>
151    Following this formula, you should use 72 dp for a height of one cell, 294 dp and for a width of four cells.</p>
152  </li>
153  <li>The <code>updatePerdiodMillis</code> attribute defines how often the App Widget framework should
154    request an update from the {@link android.appwidget.AppWidgetProvider} by calling the
155    {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
156    onUpdate()} method. The actual update is not guaranteed to occur exactly on time with this value
157    and we suggest updating as infrequently as possible&mdash;perhaps no more than once an hour to 
158    conserve the battery. You might also allow the user to adjust the frequency in a 
159    configuration&mdash;some people might want a stock ticker to update every 15 minutes, or maybe 
160    only four times a day.</li>
161  <li>The <code>initialLayout</code> attribute points to the layout resource that defines the
162    App Widget layout.</li>
163  <li>The <code>configure</code> attribute defines the {@link android.app.Activity} to launch when
164    the user adds the App Widget, in order for him or her to configure App Widget properties. This is optional
165    (read <a href="#Configuring">Creating an App Widget Configuration Activity</a> below).</li>
166</ul>
167
168<p>See the {@link android.appwidget.AppWidgetProviderInfo} class for more information on the
169attributes accepted by the <code>&lt;appwidget-provider></code> element.</p>
170
171
172<h2 id="CreatingLayout">Creating the App Widget Layout</h2>
173
174<p>You must define an initial layout for your App Widget in XML and save it in the project's
175<code>res/layout/</code> directory. You can design your App Widget using the View objects listed
176below, but before you begin designing your App Widget, please read and understand the
177<a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design 
178Guidelines</a>.</p>
179
180<p>Creating the App Widget layout is simple if you're
181familiar with <a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout in XML</a>.
182However, you must be aware that App Widget layouts are based on {@link android.widget.RemoteViews},
183which do not support every kind of layout or view widget.</p>
184
185<p>A RemoteViews object (and, consequently, an App Widget) can support the 
186following layout classes:</p>
187
188<ul class="nolist">
189  <li>{@link android.widget.FrameLayout}</li>
190  <li>{@link android.widget.LinearLayout}</li>
191  <li>{@link android.widget.RelativeLayout}</li>
192</ul>
193
194<p>And the following widget classes:</p>
195<ul class="nolist">
196  <li>{@link android.widget.AnalogClock}</li>
197  <li>{@link android.widget.Button}</li>
198  <li>{@link android.widget.Chronometer}</li>
199  <li>{@link android.widget.ImageButton}</li>
200  <li>{@link android.widget.ImageView}</li>
201  <li>{@link android.widget.ProgressBar}</li>
202  <li>{@link android.widget.TextView}</li>
203</ul>
204
205<p>Descendants of these classes are not supported.</p>
206
207
208<h2 id="AppWidgetProvider">Using the AppWidgetProvider Class</h2>
209
210<div class="sidebox-wrapper">
211  <div class="sidebox-inner">
212    <p>You must declare your AppWidgetProvider class implementation as a broadcast receiver 
213    using the <code>&lt;receiver></code> element in the AndroidManifest (see
214    <a href="#Manifest">Declaring an App Widget in the Manifest</a> above).</p>
215  </div>
216</div>
217
218<p>The {@link android.appwidget.AppWidgetProvider} class extends BroadcastReceiver as a convenience
219class to handle the App Widget broadcasts. The AppWidgetProvider receives only the event broadcasts that
220are relevant to the App Widget, such as when the App Widget is updated, deleted, enabled, and disabled.
221When these broadcast events occur, the AppWidgetProvider receives the following method calls:</p>
222
223<dl>
224  <dt>{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])}</dt>
225    <dd>This is called to update the App Widget at intervals defined by the <code>updatePeriodMillis</code>
226    attribute in the AppWidgetProviderInfo (see <a href="#MetaData">Adding the 
227    AppWidgetProviderInfo Metadata</a> above). This method is also called
228    when the user adds the App Widget, so it should perform the essential setup,
229    such as define event handlers for Views and start a temporary
230    {@link android.app.Service}, if necessary. However, if you have declared a configuration
231    Activity, <strong>this method is not called</strong> when the user adds the App Widget,
232    but is called for the subsequent updates. It is the responsibility of the 
233    configuration Activity to perform the first update when configuration is done.
234    (See <a href="#Configuring">Creating an App Widget Configuration Activity</a> below.)</dd> 
235  <dt>{@link android.appwidget.AppWidgetProvider#onDeleted(Context,int[])}</dt>
236    <dd>This is called every time an App Widget is deleted from the App Widget host.</dd>
237  <dt>{@link android.appwidget.AppWidgetProvider#onEnabled(Context)}</dt>
238    <dd>This is called when an instance the App Widget is created for the first time. For example, if the user 
239    adds two instances of your App Widget, this is only called the first time.
240    If you need to open a new database or perform other setup that only needs to occur once 
241    for all App Widget instances, then this is a good place to do it.</dd> 
242  <dt>{@link android.appwidget.AppWidgetProvider#onDisabled(Context)}</dt>
243    <dd>This is called when the last instance of your App Widget is deleted from the App Widget host. 
244    This is where you should clean up any work done in 
245    {@link android.appwidget.AppWidgetProvider#onEnabled(Context)}, 
246    such as delete a temporary database.</dd> 
247  <dt>{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)}</dt>
248    <dd>This is called for every broadcast and before each of the above callback methods.
249    You normally don't need to implement this method because the default AppWidgetProvider 
250    implementation filters all App Widget broadcasts and calls the above 
251    methods as appropriate.</dd> 
252</dl>
253
254<p class="warning"><strong>Note:</strong> In Android 1.5, there is a known issue in which the
255<code>onDeleted()</code> method will not be called when it should be. To work around this issue, 
256you can implement {@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)
257onReceive()} as described in this 
258<a href="http://groups.google.com/group/android-developers/msg/e405ca19df2170e2">Group post</a>
259to receive the <code>onDeleted()</code> callback.
260</p>
261
262<p>The most important AppWidgetProvider callback is 
263{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
264onUpdated()} because it is called when each App Widget is added to a host (unless you use
265a configuration Activity). If your App Widget accepts any
266user interaction events, then you need to register the event handlers in this callback.
267If your App Widget doesn't create temporary
268files or databases, or perform other work that requires clean-up, then
269{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
270onUpdated()} may be the only callback method you need to define. For example, if you want an App Widget
271with a button that launches an Activity when clicked, you could use the following
272implementation of AppWidgetProvider:</p>
273
274<pre>
275public class ExampleAppWidgetProvider extends AppWidgetProvider {
276
277    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
278        final int N = appWidgetIds.length;
279
280        // Perform this loop procedure for each App Widget that belongs to this provider
281        for (int i=0; i&lt;N; i++) {
282            int appWidgetId = appWidgetIds[i];
283
284            // Create an Intent to launch ExampleActivity
285            Intent intent = new Intent(context, ExampleActivity.class);
286            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
287
288            // Get the layout for the App Widget and attach an on-click listener to the button
289            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
290            views.setOnClickPendingIntent(R.id.button, pendingIntent);
291
292            // Tell the AppWidgetManager to perform an update on the current App Widget
293            appWidgetManager.updateAppWidget(appWidgetId, views);
294        }
295    }
296}
297</pre>
298
299<p>This AppWidgetProvider defines only the 
300{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
301onUpdated()} method for the purpose
302of defining a {@link android.app.PendingIntent} that launches an {@link android.app.Activity}
303and attaching it to the App Widget's button
304with {@link android.widget.RemoteViews#setOnClickPendingIntent(int,PendingIntent)}.
305Notice that it includes a loop that iterates through each entry in <code>appWidgetIds</code>, which
306is an array of IDs that identify each App Widget created by this provider.
307In this way, if the user creates more than one instance of the App Widget, then they are
308all updated simultaneously. However, only one <code>updatePeriodMillis</code> schedule will be 
309managed for all instances of the App Widget. For example, if the update schedule is defined 
310to be every two hours, and a second instance 
311of the App Widget is added one hour after the first one, then they will both be updated 
312on the period defined by the first one and the second update period will be ignored 
313(they'll both be updated every two hours, not every hour).</p>
314
315<p class="note"><strong>Note:</strong> Because the AppWidgetProvider is a BroadcastReceiver,
316your process is not guaranteed to keep running after the callback methods return (see
317<a href="{@docRoot}guide/topics/fundamentals.html#broadlife">Application Fundamentals &gt;
318Broadcast Receiver Lifecycle</a> for more information). If your App Widget setup process can take several
319seconds (perhaps while performing web requests) and you require that your process continues, 
320consider starting a {@link android.app.Service} 
321in the {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
322onUpdated()} method. From within the Service, you can perform your own updates to the App Widget
323without worrying about the AppWidgetProvider closing down due to an 
324<a href="{@docRoot}guide/practices/design/responsiveness.html">Application Not Responding</a> 
325(ANR) error. See the
326<a href="http://code.google.com/p/wiktionary-android/source/browse/trunk/Wiktionary/src/com/example/android/wiktionary/WordWidget.java">Wiktionary
327sample's AppWidgetProvider</a> for an example of an App Widget running a {@link android.app.Service}.</p>
328
329<p>Also see the <a 
330href="{@docRoot}guide/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.html">
331ExampleAppWidgetProvider.java</a> sample class.</p>
332
333
334<h3 id="ProviderBroadcasts">Receiving App Widget broadcast Intents</h3>
335
336<p>{@link android.appwidget.AppWidgetProvider} is just a convenience class.  If you would like
337to receive the App Widget broadcasts directly, you can implement your own 
338{@link android.content.BroadcastReceiver} or override the 
339{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)} callback. 
340The four Intents you need to care about are:</p>
341<ul>
342  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE}</li>
343  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DELETED}</li>
344  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_ENABLED}</li>
345  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DISABLED}</li>
346</ul>
347
348
349
350<h2 id="Configuring">Creating an App Widget Configuration Activity</h2>
351
352<p>If you would like the user to configure settings when he or she adds a new App Widget,
353you can create an App Widget configuration Activity. This {@link android.app.Activity} 
354will be automatically launched by the App Widget host and allows the user to configure
355available settings for the App Widget at create-time, such as the App Widget color, size, 
356update period or other functionality settings.</p>
357
358<p>The configuration Activity should be declared as a normal Activity in the Android manifest file.
359However, it will be launched by the App Widget host with the {@link
360android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE ACTION_APPWIDGET_CONFIGURE} action,
361so the Activity needs to accept this Intent. For example:</p>
362
363<pre>
364&lt;activity android:name=".ExampleAppWidgetConfigure">
365    &lt;intent-filter>
366        &lt;action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
367    &lt;/intent-filter>
368&lt;/activity>
369</pre>
370
371<p>Also, the Activity must be declared in the AppWidgetProviderInfo XML file, with the 
372<code>android:configure</code> attribute (see <a href="#MetaData">Adding 
373the AppWidgetProvierInfo Metadata</a> above). For example, the configuration Activity
374can be declared like this:</p>
375
376<pre>
377&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
378    ...
379    android:configure="com.example.android.ExampleAppWidgetConfigure" 
380    ... >
381&lt;/appwidget-provider>
382</pre>
383
384<p>Notice that the Activity is declared with a fully-qualified namespace, because 
385it will be referenced from outside your package scope.</p>
386
387<p>That's all you need to get started with a configuration Activity. Now all you need is the actual
388Activity. There are, however, two important things to remember when you implement the Activity:</p>
389<ul>
390  <li>The App Widget host calls the configuration Activity and the configuration Activity should always 
391    return a result. The result should include the App Widget ID
392    passed by the Intent that launched the Activity (saved in the Intent extras as
393    {@link android.appwidget.AppWidgetManager#EXTRA_APPWIDGET_ID}).</li>
394  <li>The {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
395    onUpdate()} method <strong>will not be called</strong> when the App Widget is created
396    (the system will not send the ACTION_APPWIDGET_UPDATE broadcast when a configuration Activity
397    is launched). It is the responsibility of the configuration Activity to request an update from the 
398    AppWidgetManager when the App Widget is first created. However, 
399    {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
400    onUpdate()} will be called for subsequent updates&mdash;it is only skipped the first time.</li>
401</ul>
402
403<p>See the code snippets in the following section for an example of how to return a result
404from the configuration and update the App Widget.</p>
405
406
407<h3 id="UpdatingFromTheConfiguration">Updating the App Widget from the configuration Activity</h3>
408
409<p>When an App Widget uses a configuration Activity, it is the responsibility of the Activity
410to update the App Widget when configuration is complete. 
411You can do so by requesting an update directly from the 
412{@link android.appwidget.AppWidgetManager}.</p>
413
414<p>Here's a summary of the procedure to properly update the App Widget and close
415the configuration Activity:</p>
416
417<ol>
418  <li>First, get the App Widget ID from the Intent that launched the Activity:
419<pre>
420Intent intent = getIntent();
421Bundle extras = intent.getExtras();
422if (extras != null) {
423    mAppWidgetId = extras.getInt(
424            AppWidgetManager.EXTRA_APPWIDGET_ID, 
425            AppWidgetManager.INVALID_APPWIDGET_ID);
426}
427</pre>
428  </li>
429  <li>Perform your App Widget configuration.</li>
430  <li>When the configuration is complete, get an instance of the AppWidgetManager by calling
431    {@link android.appwidget.AppWidgetManager#getInstance(Context)}:
432<pre>
433AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
434</pre>
435  </li>
436  <li>Update the App Widget with a {@link android.widget.RemoteViews} layout by calling
437    {@link android.appwidget.AppWidgetManager#updateAppWidget(int,RemoteViews)}:
438<pre>
439RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
440appWidgetManager.updateAppWidget(mAppWidgetId, views);
441</pre>
442  </li>
443  <li>Finally, create the return Intent, set it with the Activity result, and finish the Activity:</li>
444<pre>
445Intent resultValue = new Intent();
446resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
447setResult(RESULT_OK, resultValue);
448finish();
449</pre>
450  </li>
451</ol>
452
453<p class="note"><strong>Tip:</strong> When your configuration Activity first opens, set
454the Activity result to RESULT_CANCELED. This way, if the user backs-out of the Activity before
455reaching the end, the App Widget host is notified that the configuration was cancelled and the
456App Widget will not be added.</p>
457
458<p>See the <a 
459href="{@docRoot}guide/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetConfigure.html">
460ExampleAppWidgetConfigure.java</a> sample class in ApiDemos for an example.</p>
461
462
463
464