index.jd revision 1019a9c44e573d1eb44bf1733005afb46fb73f72
1page.title=App Widgets
2@jd:body
3
4<div id="qv-wrapper">
5  <div id="qv">
6    <h2>Quickview</h2>
7    <ul>
8      <li>App Widgets provide users access to some of your application features
9directly from the Home screen (without the need to launch an activity)</li>
10      <li>App Widgets are backed by a special kind of broadcast receiver that
11handles the App
12Widget lifecycle</li>
13    </ul>
14    
15    <h2>In this document</h2>
16    <ol>
17      <li><a href="#Basics">The Basics</a></li>
18      <li><a href="#Manifest">Declaring an App Widget in the Manifest</a></li>
19      <li><a href="#MetaData">Adding the AppWidgetProviderInfo Metadata</a></li>
20      <li><a href="#CreatingLayout">Creating the App Widget Layout</a></li>
21      <li><a href="#AppWidgetProvider">Using the AppWidgetProvider Class</a>
22        <ol>
23          <li><a href="#ProviderBroadcasts">Receiving App Widget broadcast
24Intents</a></li>
25        </ol>
26      </li>
27      <li><a href="#Configuring">Creating an App Widget Configuration
28Activity</a>
29        <ol>
30          <li><a href="#UpdatingFromTheConfiguration">Updating the App Widget
31from 
32            the configuration Activity</a></li>
33        </ol>
34      </li>
35      <li><a href="#preview">Setting a Preview Image</a></li>
36      <li><a href="#collections">Using App Widgets with Collections</a>
37        <ol>
38          <li><a href="#collection_sample">Sample application</a></li>
39          <li><a href="#implementing_collections">Implementing app widgets with
40collections
41</a></li>
42          <li><a href="#fresh">Keeping Collection Data Fresh</a></li>
43        </ol>   
44      </li>
45    </ol>
46
47    <h2>Key classes</h2>
48    <ol>
49      <li>{@link android.appwidget.AppWidgetProvider}</li>
50      <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
51      <li>{@link android.appwidget.AppWidgetManager}</li>
52    </ol>
53    
54    <h2>See also</h2>
55    <ol>
56      <li><a
57href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget
58Design 
59        Guidelines</a></li>
60      <li><a
61href="http://android-developers.blogspot.com/2009/04/introducing-home-screen-
62widgets-and.html">Introducing
63        home screen widgets and the AppWidget framework &raquo;</a></li>
64    </ol>
65  </div>
66</div>
67
68
69<p>App Widgets are miniature application views that can be embedded in other
70applications
71(such as the Home screen) and receive periodic updates. These views are
72referred 
73to as Widgets in the user interface,
74and you can publish one with an App Widget provider. An application component
75that is 
76able to hold other App Widgets is called an App Widget host. The screenshot
77below shows
78the Music App Widget.</p>
79
80<img src="{@docRoot}images/appwidgets/appwidget.png" alt="" />
81
82<p>This document describes how to publish an App Widget using an App Widget
83provider.</p>
84
85
86<h2 id="Basics">The Basics</h2>
87
88<p>To create an App Widget, you need the following:</p>
89
90<dl>
91  <dt>{@link android.appwidget.AppWidgetProviderInfo} object</dt>
92  <dd>Describes the metadata for an App Widget, such as the App Widget's layout,
93update frequency,
94    and the AppWidgetProvider class. This should be defined in XML.</dd>
95  <dt>{@link android.appwidget.AppWidgetProvider} class implementation</dt>
96  <dd>Defines the basic methods that allow you to programmatically interface
97with the App Widget,
98    based on broadcast events. Through it, you will receive broadcasts when the
99App Widget is updated, 
100    enabled, disabled and deleted.</dd>
101  <dt>View layout</dt>
102  <dd>Defines the initial layout for the App Widget, defined in XML.</dd>
103</dl>
104
105<p>Additionally, you can implement an App Widget configuration Activity. This is
106an optional 
107{@link android.app.Activity} that launches when the user adds your App Widget
108and allows him or her
109to modify App Widget settings at create-time.</p>
110
111<p>The following sections describe how to setup each of these components.</p>
112
113
114<h2 id="Manifest">Declaring an App Widget in the Manifest</h2>
115
116<p>First, declare the {@link android.appwidget.AppWidgetProvider} class in your
117application's
118<code>AndroidManifest.xml</code> file. For example:</p>
119
120<pre style="clear:right">
121&lt;receiver android:name="ExampleAppWidgetProvider" >
122    &lt;intent-filter>
123        &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
124    &lt;/intent-filter>
125    &lt;meta-data android:name="android.appwidget.provider"
126               android:resource="@xml/example_appwidget_info" />
127&lt;/receiver>
128</pre>
129
130<p>The <code>&lt;receiver&gt;</code> element requires the
131<code>android:name</code> 
132attribute, which specifies the {@link android.appwidget.AppWidgetProvider} used
133by the App Widget.</p>
134
135<p>The <code>&lt;intent-filter&gt;</code> element must include an
136<code>&lt;action></code>
137element with the <code>android:name</code> attribute. This attribute specifies
138that the {@link android.appwidget.AppWidgetProvider} accepts the {@link
139android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE
140ACTION_APPWIDGET_UPDATE} broadcast.
141This is the only broadcast that you must explicitly declare. The {@link
142android.appwidget.AppWidgetManager}
143automatically sends all other App Widget broadcasts to the AppWidgetProvider as
144necessary.</p>
145
146<p>The <code>&lt;meta-data&gt;</code> element specifies the
147{@link android.appwidget.AppWidgetProviderInfo} resource and requires the 
148following attributes:</p>
149<ul>
150  <li><code>android:name</code> - Specifies the metadata name. Use
151<code>android.appwidget.provider</code>
152    to identify the data as the {@link android.appwidget.AppWidgetProviderInfo}
153descriptor.</li>
154  <li><code>android:resource</code> - Specifies the {@link
155android.appwidget.AppWidgetProviderInfo} 
156    resource location.</li>
157</ul>
158
159
160<h2 id="MetaData">Adding the AppWidgetProviderInfo Metadata</h2>
161
162<p>The {@link android.appwidget.AppWidgetProviderInfo} defines the essential 
163qualities of an App Widget, such as its minimum layout dimensions, its initial
164layout resource,
165how often to update the App Widget, and (optionally) a configuration Activity to
166launch at create-time.
167Define the AppWidgetProviderInfo object in an XML resource using a single
168<code>&lt;appwidget-provider></code> element and save it in the project's
169<code>res/xml/</code> 
170folder.</p>
171
172<p>For example:</p>
173
174<pre>
175&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
176    android:minWidth="294dp"
177    android:minHeight="72dp"
178    android:updatePeriodMillis="86400000"
179    android:previewImage="@drawable/preview"
180    android:initialLayout="@layout/example_appwidget"
181    android:configure="com.example.android.ExampleAppWidgetConfigure" 
182    android:resizeMode="horizontal|vertical">
183&lt;/appwidget-provider>
184</pre>
185
186<p>Here's a summary of the <code>&lt;appwidget-provider></code> attributes:</p>
187<ul>
188  <li>The values for the <code>minWidth</code> and <code>minHeight</code>
189    attributes specify the minimum amount of space the App Widget consumes
190    <em>by default</em>. The default Home screen positions App Widgets in its
191    window based on a grid of cells that have a defined height and width. If
192    the values for an App Widget's minimum width or height don't match the
193    dimensions of the cells, then the App Widget dimensions round
194    <em>up</em> to the nearest cell size.
195    <p>See the <a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html#anatomy_determining_size">
196    App Widget Design Guidelines</a> for more information on sizing your App
197    Widgets.</p>
198
199    <p class="note"><strong>Note:</strong> To make your app widget portable
200    across devices, your app widget's minimum size should never be larger
201    than 4 x 4 cells.</p>
202  </li>
203
204  <li>The <code>minResizeWidth</code> and <code>minResizeHeight</code> attributes
205    specify the App Widget's absolute minimum size. These values should specify
206    the size below which the App Widget would be illegible or otherwise unusable.
207    Using these attributes allows the user to resize the widget to a size that
208    may be smaller than the default widget size defined by the
209    <code>minWidth</code> and <code>minHeight</code> attributes.
210    Introduced in Android 3.1.
211
212    <p>See the <a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html#anatomy_determining_size">
213    App Widget Design Guidelines</a> for more information on sizing your App
214    Widgets.</p>
215  </li>
216
217  <li>The <code>updatePeriodMillis</code> attribute defines how often the App
218Widget framework should request an update from the {@link
219android.appwidget.AppWidgetProvider} by calling the 
220{@link android.appwidget.AppWidgetProvider#onUpdate(android.content.Context,android.appwidget.AppWidgetManager,int[]) onUpdate()} 
221callback method. The actual update
222is not guaranteed to occur exactly on time with this value and we suggest
223updating as infrequently as possible&mdash;perhaps no more than once an hour to
224conserve the battery. You might also allow the user to adjust the frequency in a
225configuration&mdash;some people might want a stock ticker to update every 15
226minutes, or maybe only four times a day. 
227    	<p class="note"><strong>Note:</strong> If the device is asleep when it
228is time for an update 
229    	(as defined by <code>updatePeriodMillis</code>), then the device will
230wake up in order 
231    	to perform the update. If you don't update more than once per hour, this
232probably won't 
233    	cause significant problems for the battery life. If, however, you need
234to update more 
235    	frequently and/or you do not need to update while the device is asleep,
236then you can instead 
237    	perform updates based on an alarm that will not wake the device. To do
238so, set an alarm with 
239    	an Intent that your AppWidgetProvider receives, using the	{@link
240android.app.AlarmManager}. 
241    	Set the alarm type to either {@link
242android.app.AlarmManager#ELAPSED_REALTIME} or 
243    	{@link android.app.AlarmManager#RTC}, which will only
244    	deliver the alarm when the device is awake. Then set
245<code>updatePeriodMillis</code> to 
246    	zero (<code>"0"</code>).</p>
247  </li>
248  <li>The <code>initialLayout</code> attribute points to the layout resource
249that defines the
250    App Widget layout.</li>
251  <li>The <code>configure</code> attribute defines the {@link
252android.app.Activity} to launch when
253    the user adds the App Widget, in order for him or her to configure App
254Widget properties. This is optional
255    (read <a href="#Configuring">Creating an App Widget Configuration
256Activity</a> below).</li>
257    
258   <li>The <code>previewImage</code> attribute specifies a preview of what the
259app widget will look like after it's configured, which the user sees when
260selecting the app widget. If not supplied, the user instead sees your
261application's launcher icon. This field corresponds to the
262<code>android:previewImage</code> attribute in the <code>&lt;receiver&gt;</code>
263element in the <code>AndroidManifest.xml</code> file. For more discussion of
264using <code>previewImage</code>, see <a href="#preview">Setting a Preview
265Image</a>. Introduced in Android 3.0.</li>
266
267   <li>The <code>autoAdvanceViewId</code> attribute specifies the view ID of the
268app widget subview that should be auto-advanced by the widget's host. Introduced in Android 3.0.</li> 
269
270<li>The <code>resizeMode</code> attribute specifies the rules by which a widget
271can be resized. You use this attribute to make homescreen widgets
272resizeable&mdash;horizontally, vertically, or on both axes. Users touch-hold a
273widget to show its resize handles, then drag the horizontal and/or vertical
274handles to change the size on the layout grid. Values for the
275<code>resizeMode</code> attribute include "horizontal", "vertical", and "none".
276To declare a widget as resizeable horizontally and vertically, supply the value
277"horizontal|vertical". Introduced in Android 3.1.</li> </ul>
278
279<p>See the {@link android.appwidget.AppWidgetProviderInfo} class for more
280information on the
281attributes accepted by the <code>&lt;appwidget-provider></code> element.</p>
282
283
284<h2 id="CreatingLayout">Creating the App Widget Layout</h2>
285
286<p>You must define an initial layout for your App Widget in XML and save it in
287the project's
288<code>res/layout/</code> directory. You can design your App Widget using the
289View objects listed
290below, but before you begin designing your App Widget, please read and
291understand the
292<a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget
293Design 
294Guidelines</a>.</p>
295
296<p>Creating the App Widget layout is simple if you're
297familiar with <a
298href="{@docRoot}guide/topics/ui/declaring-layout.html">Layouts</a>.
299However, you must be aware that App Widget layouts are based on {@link
300android.widget.RemoteViews},
301which do not support every kind of layout or view widget.</p>
302
303<p>A RemoteViews object (and, consequently, an App Widget) can support the 
304following layout classes:</p>
305
306<ul class="nolist">
307  <li>{@link android.widget.FrameLayout}</li>
308  <li>{@link android.widget.LinearLayout}</li>
309  <li>{@link android.widget.RelativeLayout}</li>
310  <li>{@link android.widget.GridLayout}</li>
311</ul>
312
313<p>And the following widget classes:</p>
314<ul class="nolist">
315  <li>{@link android.widget.AnalogClock}</li>
316  <li>{@link android.widget.Button}</li>
317  <li>{@link android.widget.Chronometer}</li>
318  <li>{@link android.widget.ImageButton}</li>
319  <li>{@link android.widget.ImageView}</li>
320  <li>{@link android.widget.ProgressBar}</li>
321  <li>{@link android.widget.TextView}</li>
322  <li>{@link android.widget.ViewFlipper}</li>
323  <li>{@link android.widget.ListView}</li>
324  <li>{@link android.widget.GridView}</li>
325  <li>{@link android.widget.StackView}</li>
326  <li>{@link android.widget.AdapterViewFlipper}</li>
327</ul>
328
329<p>Descendants of these classes are not supported.</p>
330
331<p>RemoteViews also supports {@link android.view.ViewStub}, which is an invisible, zero-sized View you can use 
332to lazily inflate layout resources at runtime.</p>
333
334
335<h3 id="AddingMargins">Adding margins to App Widgets</h3>
336
337<p>Widgets should not generally extend to screen edges and should not visually be flush with other widgets, so you should add margins on all sides around your widget frame.</p>
338
339<p>As of Android 4.0, app widgets are automatically given padding between the widget frame and the app widget's bounding box to provide better alignment with other widgets and icons on the user's home screen. To take advantage of this strongly recommended behavior, set your application's <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">targetSdkVersion</a> to 14 or greater.</p>
340
341<p>It's easy to write a single layout that has custom margins applied for earlier versions of the platform, and has no extra margins for Android 4.0 and greater:</p>
342
343<ol>
344  <li>Set your application's <code>targetSdkVersion</code> to 14 or greater.</li>
345  <li>Create a layout such as the one below, that references a <a href="{@docRoot}guide/topics/resources/more-resources.html#Dimension">dimension resource</a> for its margins:
346
347<pre>
348&lt;FrameLayout
349  android:layout_width="match_parent"
350  android:layout_height="match_parent"
351  <strong>android:padding="@dimen/widget_margin"&gt;</strong>
352
353  &lt;LinearLayout
354    android:layout_width="match_parent"
355    android:layout_height="match_parent"
356    android:orientation="horizontal"
357    android:background="@drawable/my_widget_background"&gt;
358    &hellip;
359  &lt;/LinearLayout&gt;
360
361&lt;/FrameLayout&gt;
362</pre>
363
364  </li>
365  <li>Create two dimensions resources, one in <code>res/values/</code> to provide the pre-Android 4.0 custom margins, and one in <code>res/values-v14/</code> to provide no extra padding for Android 4.0 widgets:
366
367    <p><strong>res/values/dimens.xml</strong>:<br>
368    <pre>&lt;dimen name="widget_margin"&gt;8dp&lt;/dimen&gt;</pre></p>
369
370    <p><strong>res/values-v14/dimens.xml</strong>:<br>
371    <pre>&lt;dimen name="widget_margin"&gt;0dp&lt;/dimen&gt;</pre></p>
372  </li>
373</ol>
374
375<p>Another option is to simply build extra margins into your <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">nine-patch</a> background assets by default, and provide different nine-patches with no margins for API level 14 or later.</p>
376
377
378<h2 id="AppWidgetProvider">Using the AppWidgetProvider Class</h2>
379
380<div class="sidebox-wrapper">
381<div class="sidebox">
382    <p>You must declare your AppWidgetProvider class implementation as a
383broadcast receiver 
384    using the <code>&lt;receiver></code> element in the AndroidManifest (see
385    <a href="#Manifest">Declaring an App Widget in the Manifest</a> above).</p>
386  </div>
387</div>
388
389<p>The {@link android.appwidget.AppWidgetProvider} class extends
390BroadcastReceiver as a convenience
391class to handle the App Widget broadcasts. The AppWidgetProvider receives only
392the event broadcasts that
393are relevant to the App Widget, such as when the App Widget is updated, deleted,
394enabled, and disabled.
395When these broadcast events occur, the AppWidgetProvider receives the following
396method calls:</p>
397
398<dl>
399  <dt>
400  {@link android.appwidget.AppWidgetProvider#onUpdate(android.content.Context,android.appwidget.AppWidgetManager,int[]) onUpdate()} 
401</dt>
402    <dd>This is called to update the App Widget at intervals defined by the
403<code>updatePeriodMillis</code>
404    attribute in the AppWidgetProviderInfo (see <a href="#MetaData">Adding the 
405    AppWidgetProviderInfo Metadata</a> above). This method is also called
406    when the user adds the App Widget, so it should perform the essential setup,
407    such as define event handlers for Views and start a temporary
408    {@link android.app.Service}, if necessary. However, if you have declared a
409configuration
410    Activity, <strong>this method is not called</strong> when the user adds the
411App Widget,
412    but is called for the subsequent updates. It is the responsibility of the 
413    configuration Activity to perform the first update when configuration is
414done.
415    (See <a href="#Configuring">Creating an App Widget Configuration
416Activity</a> below.)</dd> 
417
418<dt>
419  {@link android.appwidget.AppWidgetProvider#onAppWidgetOptionsChanged onAppWidgetOptionsChanged()} 
420</dt>
421<dd>
422This is called when the widget is first placed and any time the widget is resized. You can use this callback to show or hide content based on the widget's size ranges. You get the size ranges by calling {@link android.appwidget.AppWidgetManager#getAppWidgetOptions getAppWidgetOptions()}, which returns a  {@link android.os.Bundle} that includes the following:<br /><br />
423<ul>
424  <li>{@link android.appwidget.AppWidgetManager#OPTION_APPWIDGET_MIN_WIDTH}&mdash;Contains 
425the lower bound on the current width, in dp units, of a widget instance.</li>
426  <li>{@link android.appwidget.AppWidgetManager#OPTION_APPWIDGET_MIN_HEIGHT}&mdash;Contains 
427the lower bound on the current height, in dp units, of a widget instance.</li>
428  <li>{@link android.appwidget.AppWidgetManager#OPTION_APPWIDGET_MAX_WIDTH}&mdash;Contains
429 the upper bound on the current width, in dp units, of a widget instance.</li>
430  <li>{@link android.appwidget.AppWidgetManager#OPTION_APPWIDGET_MAX_HEIGHT}&mdash;Contains 
431the upper bound on the current width, in dp units, of a widget instance.</li>
432</ul>
433
434This callback was introduced in API Level 16 (Android 4.1). If you implement this callback, make sure that your app doesn't depend on it since it won't be called on older devices.
435</dd>
436  <dt>{@link android.appwidget.AppWidgetProvider#onDeleted(Context,int[])}</dt>
437    <dd>This is called every time an App Widget is deleted from the App Widget
438host.</dd>
439  <dt>{@link android.appwidget.AppWidgetProvider#onEnabled(Context)}</dt>
440    <dd>This is called when an instance the App Widget is created for the first
441time. For example, if the user 
442    adds two instances of your App Widget, this is only called the first time.
443    If you need to open a new database or perform other setup that only needs to
444occur once 
445    for all App Widget instances, then this is a good place to do it.</dd> 
446  <dt>{@link android.appwidget.AppWidgetProvider#onDisabled(Context)}</dt>
447    <dd>This is called when the last instance of your App Widget is deleted from
448the App Widget host. 
449    This is where you should clean up any work done in 
450    {@link android.appwidget.AppWidgetProvider#onEnabled(Context)}, 
451    such as delete a temporary database.</dd> 
452  <dt>{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)}</dt>
453    <dd>This is called for every broadcast and before each of the above callback
454methods.
455    You normally don't need to implement this method because the default
456AppWidgetProvider 
457    implementation filters all App Widget broadcasts and calls the above 
458    methods as appropriate.</dd> 
459</dl>
460
461<p class="warning"><strong>Note:</strong> In Android 1.5, there is a known issue
462in which the
463<code>onDeleted()</code> method will not be called when it should be. To work
464around this issue, 
465you can implement {@link
466android.appwidget.AppWidgetProvider#onReceive(Context,Intent)
467onReceive()} as described in this 
468<a
469href="http://groups.google.com/group/android-developers/msg/e405ca19df2170e2">
470Group post</a>
471to receive the <code>onDeleted()</code> callback.
472</p>
473
474<p>The most important AppWidgetProvider callback is 
475{@link android.appwidget.AppWidgetProvider#onUpdate(android.content.Context, android.appwidget.AppWidgetManager, int[]) onUpdate()} 
476because it is called when
477each App Widget is added to a host (unless you use a configuration Activity). If
478your App Widget accepts any user interaction events, then you need to register
479the event handlers in this callback. If your App Widget doesn't create temporary
480files or databases, or perform other work that requires clean-up, then 
481{@link android.appwidget.AppWidgetProvider#onUpdate(android.content.Context, android.appwidget.AppWidgetManager, int[]) onUpdate()} 
482may be the only callback
483method you need to define. For example, if you want an App Widget with a button
484that launches an Activity when clicked, you could use the following
485implementation of AppWidgetProvider:</p>
486
487<pre>
488public class ExampleAppWidgetProvider extends AppWidgetProvider {
489
490    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
491        final int N = appWidgetIds.length;
492
493        // Perform this loop procedure for each App Widget that belongs to this provider
494        for (int i=0; i&lt;N; i++) {
495            int appWidgetId = appWidgetIds[i];
496
497            // Create an Intent to launch ExampleActivity
498            Intent intent = new Intent(context, ExampleActivity.class);
499            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
500
501            // Get the layout for the App Widget and attach an on-click listener
502            // to the button
503            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
504            views.setOnClickPendingIntent(R.id.button, pendingIntent);
505
506            // Tell the AppWidgetManager to perform an update on the current app widget
507            appWidgetManager.updateAppWidget(appWidgetId, views);
508        }
509    }
510}
511</pre>
512
513<p>This AppWidgetProvider defines only the 
514{@link
515android.appwidget.AppWidgetProvider#onUpdate(android.content.Context, android.appwidget.AppWidgetManager, int[]) onUpdate()} 
516method for the purpose of
517defining a {@link android.app.PendingIntent} that launches an {@link
518android.app.Activity} and attaching it to the App Widget's button with {@link
519android.widget.RemoteViews#setOnClickPendingIntent(int,PendingIntent)}. Notice
520that it includes a loop that iterates through each entry in
521<code>appWidgetIds</code>, which is an array of IDs that identify each App
522Widget created by this provider. In this way, if the user creates more than one
523instance of the App Widget, then they are all updated simultaneously. However,
524only one <code>updatePeriodMillis</code> schedule will be managed for all
525instances of the App Widget. For example, if the update schedule is defined to
526be every two hours, and a second instance of the App Widget is added one hour
527after the first one, then they will both be updated on the period defined by the
528first one and the second update period will be ignored (they'll both be updated
529every two hours, not every hour).</p>
530
531<p class="note"><strong>Note:</strong> Because {@link
532android.appwidget.AppWidgetProvider} is an extension of {@link
533android.content.BroadcastReceiver}, your process is not guaranteed to keep
534running after the callback methods return (see {@link
535android.content.BroadcastReceiver} for information about the broadcast
536lifecycle). If your App Widget setup process can take several seconds (perhaps
537while performing web requests) and you require that your process continues,
538consider starting a {@link android.app.Service} in the 
539{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[]) onUpdate()} 
540method. From within the Service, you can perform your own updates
541to the App Widget without worrying about the AppWidgetProvider closing down due
542to an <a href="{@docRoot}guide/practices/responsiveness.html">Application
543Not Responding</a> (ANR) error. See the <a
544href="http://code.google.com/p/wiktionary-android/source/browse/trunk/Wiktionary/src/com/example/android/wiktionary/WordWidget.java">Wiktionary sample's AppWidgetProvider</a> for an example of an App Widget running a {@link
545android.app.Service}.</p>
546
547<p>Also see the <a 
548href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.html">ExampleAppWidgetProvider.java</a>
549sample class.</p>
550
551
552<h3 id="ProviderBroadcasts">Receiving App Widget broadcast Intents</h3>
553
554<p>{@link android.appwidget.AppWidgetProvider} is just a convenience class.  If
555you would like
556to receive the App Widget broadcasts directly, you can implement your own 
557{@link android.content.BroadcastReceiver} or override the 
558{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)} callback. 
559The Intents you need to care about are as follows:</p>
560<ul>
561  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE}</li>
562  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DELETED}</li>
563  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_ENABLED}</li>
564  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DISABLED}</li>
565  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_OPTIONS_CHANGED}</li>
566</ul>
567
568
569
570<h2 id="Configuring">Creating an App Widget Configuration Activity</h2>
571
572<p>If you would like the user to configure settings when he or she adds a new
573App Widget,
574you can create an App Widget configuration Activity. This {@link
575android.app.Activity} 
576will be automatically launched by the App Widget host and allows the user to
577configure
578available settings for the App Widget at create-time, such as the App Widget
579color, size, 
580update period or other functionality settings.</p>
581
582<p>The configuration Activity should be declared as a normal Activity in the
583Android manifest file.
584However, it will be launched by the App Widget host with the {@link
585android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE
586ACTION_APPWIDGET_CONFIGURE} action,
587so the Activity needs to accept this Intent. For example:</p>
588
589<pre>
590&lt;activity android:name=".ExampleAppWidgetConfigure">
591    &lt;intent-filter>
592        &lt;action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
593    &lt;/intent-filter>
594&lt;/activity>
595</pre>
596
597<p>Also, the Activity must be declared in the AppWidgetProviderInfo XML file,
598with the 
599<code>android:configure</code> attribute (see <a href="#MetaData">Adding 
600the AppWidgetProviderInfo Metadata</a> above). For example, the configuration
601Activity
602can be declared like this:</p>
603
604<pre>
605&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
606    ...
607    android:configure="com.example.android.ExampleAppWidgetConfigure" 
608    ... >
609&lt;/appwidget-provider>
610</pre>
611
612<p>Notice that the Activity is declared with a fully-qualified namespace,
613because 
614it will be referenced from outside your package scope.</p>
615
616<p>That's all you need to get started with a configuration Activity. Now all you
617need is the actual
618Activity. There are, however, two important things to remember when you
619implement the Activity:</p>
620<ul>
621  <li>The App Widget host calls the configuration Activity and the configuration
622Activity should always 
623    return a result. The result should include the App Widget ID
624    passed by the Intent that launched the Activity (saved in the Intent extras
625as
626    {@link android.appwidget.AppWidgetManager#EXTRA_APPWIDGET_ID}).</li>
627  <li>The 
628  {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[]) onUpdate()} 
629    method <strong>will not be called</strong> when the App Widget
630is created
631    (the system will not send the ACTION_APPWIDGET_UPDATE broadcast when a
632configuration Activity
633    is launched). It is the responsibility of the configuration Activity to
634request an update from the 
635    AppWidgetManager when the App Widget is first created. However, 
636{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[]) onUpdate()} 
637    will be called for subsequent updates&mdash;it is only skipped
638the first time.</li>
639</ul>
640
641<p>See the code snippets in the following section for an example of how to
642return a result
643from the configuration and update the App Widget.</p>
644
645
646<h3 id="UpdatingFromTheConfiguration">Updating the App Widget from the
647configuration Activity</h3>
648
649<p>When an App Widget uses a configuration Activity, it is the responsibility of
650the Activity
651to update the App Widget when configuration is complete. 
652You can do so by requesting an update directly from the 
653{@link android.appwidget.AppWidgetManager}.</p>
654
655<p>Here's a summary of the procedure to properly update the App Widget and close
656the configuration Activity:</p>
657
658<ol>
659  <li>First, get the App Widget ID from the Intent that launched the Activity:
660<pre>
661Intent intent = getIntent();
662Bundle extras = intent.getExtras();
663if (extras != null) {
664    mAppWidgetId = extras.getInt(
665            AppWidgetManager.EXTRA_APPWIDGET_ID, 
666            AppWidgetManager.INVALID_APPWIDGET_ID);
667}
668</pre>
669  </li>
670  <li>Perform your App Widget configuration.</li>
671  <li>When the configuration is complete, get an instance of the
672AppWidgetManager by calling
673    {@link android.appwidget.AppWidgetManager#getInstance(Context)}:
674<pre>
675AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
676</pre>
677  </li>
678  <li>Update the App Widget with a {@link android.widget.RemoteViews} layout by
679calling
680    {@link android.appwidget.AppWidgetManager#updateAppWidget(int,RemoteViews)}:
681<pre>
682RemoteViews views = new RemoteViews(context.getPackageName(),
683R.layout.example_appwidget);
684appWidgetManager.updateAppWidget(mAppWidgetId, views);
685</pre>
686  </li>
687  <li>Finally, create the return Intent, set it with the Activity result, and
688finish the Activity:</li>
689<pre>
690Intent resultValue = new Intent();
691resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
692setResult(RESULT_OK, resultValue);
693finish();
694</pre>
695  </li>
696</ol>
697
698<p class="note"><strong>Tip:</strong> When your configuration Activity first
699opens, set
700the Activity result to RESULT_CANCELED. This way, if the user backs-out of the
701Activity before
702reaching the end, the App Widget host is notified that the configuration was
703cancelled and the
704App Widget will not be added.</p>
705
706<p>See the <a 
707href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetConfigure.html">ExampleAppWidgetConfigure.java</a>
708sample class in ApiDemos for an example.</p>
709
710<h2 id="preview">Setting a Preview Image</h2>
711
712<p>Android 3.0 introduces the {@link
713
714
715android.appwidget.AppWidgetProviderInfo#previewImage} field, which specifies a
716preview of what the app widget looks like. This preview is shown to the user from the
717widget picker. If this field is not supplied, the app widget's icon is used for
718the preview.</p> 
719
720<p>This is how you specify this setting in XML:</p>
721
722<pre>&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
723  ...
724  android:previewImage="@drawable/preview">
725&lt;/appwidget-provider></pre>
726
727<p>To help create a preview image for your app widget (to specify in the {@link
728android.appwidget.AppWidgetProviderInfo#previewImage} field), the Android
729emulator includes an application called &quot;Widget Preview.&quot; To create a
730preview image, launch this application, select the app widget for your
731application and set it up how you'd like your preview image to appear, then save
732it and place it in your application's drawable resources.</p>
733
734<h2 id="collections">Using App Widgets with Collections</h2>
735
736<p>Android 3.0 introduces App Widgets with collections. These kinds of App
737Widgets use the {@link android.widget.RemoteViewsService} to display collections
738that are backed by remote data, such as from a <a
739href="{@docRoot}guide/topics/providers/content-providers.html">content
740provider</a>. The data provided by the {@link android.widget.RemoteViewsService}
741is presented in the App Widget using one of the following view types, which
742we’ll refer to as “collection views:”</p>
743
744<dl>
745  <dt>{@link android.widget.ListView}</dt>
746  <dd>A view that shows items in a
747vertically scrolling
748list. For an example, see the Gmail app widget. </dd>
749<dt>{@link android.widget.GridView}</dt>
750<dd>A view that shows items in
751two-dimensional scrolling grid. For an example, see the Bookmarks app
752widget.</dd> 
753<dt>{@link android.widget.StackView}</dt>
754<dd>A
755stacked card view (kind of like a rolodex), where the user can flick the  front
756card up/down to see the previous/next card, respectively.  Examples include
757the YouTube and Books app widgets. </dd> 
758<dt>{@link android.widget.AdapterViewFlipper}</dt>
759<dd>An adapter-backed simple
760{@link
761android.widget.ViewAnimator} that  animates between two or more views. Only one
762child is shown at a time.  </dd>
763</dl>
764
765<p>As stated above, these collection views display collections backed by remote
766data. This means that they use an {@link android.widget.Adapter} to bind their
767user interface to their data. An {@link android.widget.Adapter} binds individual
768items from a set of data into individual {@link android.view.View} objects.
769Because these collection views are backed by adapters, the Android framework
770must include extra architecture to support their use in app widgets. In the
771context of an app widget, the {@link android.widget.Adapter} is replaced by a
772{@link android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory},
773which is simply a thin wrapper around  the {@link android.widget.Adapter}
774interface. 
775 When
776requested for a specific item in the collection, the {@link
777android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory} creates
778and returns the item for the collection as a {@link android.widget.RemoteViews}
779object.
780In order to include a collection view in your app widget, you
781must implement {@link android.widget.RemoteViewsService} and {@link
782android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}.</p>
783
784<p> {@link android.widget.RemoteViewsService} is a service that allows a remote
785adapter to request {@link
786android.widget.RemoteViews} objects. {@link
787android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory} is an
788interface for an adapter between a collection view (such as {@link
789android.widget.ListView}, {@link android.widget.GridView}, and so on) and the
790underlying data for that view. From the  <a
791href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
792sample</a>, here is an example of the boilerplate code you use to implement 
793this service and interface:
794</p>
795
796<pre>
797public class StackWidgetService extends RemoteViewsService {
798    &#64;Override
799    public RemoteViewsFactory onGetViewFactory(Intent intent) {
800        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
801    }
802}
803
804class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
805
806//... include adapter-like methods here. See the StackView Widget sample.
807
808}
809</pre>
810
811<h3 id="collection_sample">Sample application</h3>
812
813<p>The code excerpts in this section are drawn from the <a
814href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
815sample</a>:</p>
816
817<p>
818<img src="{@docRoot}images/appwidgets/StackWidget.png" alt="" />
819</p>
820
821<p>This sample consists of a stack of 10 views, which  display the values
822<code>&quot;0!&quot;</code> through <code>&quot;9!&quot;</code> The sample
823app widget has these primary behaviors:</p> 
824
825<ul>
826
827  <li>The user can vertically fling the top view in the
828app widget to display the next or previous view. This is a built-in StackView
829behavior.</li> 
830
831  <li>Without any user interaction, the app widget automatically advances
832through
833its views in sequence, like a slide show. This is due to the setting
834<code>android:autoAdvanceViewId=&quot;@id/stack_view&quot;</code> in the
835<code>res/xml/stackwidgetinfo.xml</code> file. This setting applies to the view
836ID,
837which in this case is the view ID of the stack view.</li>
838  
839  <li>If the user touches the top view, the app widget displays the {@link
840android.widget.Toast} message &quot;Touched view <em>n</em>,&quot; where
841<em>n</em> is the index (position) of the touched view. For more discussion of
842how this is implemented, see  
843<a href="#behavior">Adding behavior to individual items</a>.</li>
844
845</ul>
846<h3 id="implementing_collections">Implementing app widgets with collections</h3>
847
848<p>To implement an App Widget with collections, you follow the same basic steps 
849you would use to implement any app widget. The following sections  describe the
850additional steps you need to perform to implement an App Widget with
851collections.</p>
852
853<h4>Manifest for app widgets with collections</h4>
854
855<p> In addition to the requirements listed in <a href="#Manifest">Declaring an
856App Widget in the Manifest</a>, to make it possible for App Widgets with
857collections to bind to your {@link android.widget.RemoteViewsService}, you must
858declare the service in your manifest file with the permission {@link
859android.Manifest.permission#BIND_REMOTEVIEWS}. This prevents other applications
860from freely accessing your app widget's data. For example, when creating an App
861Widget that uses {@link android.widget.RemoteViewsService} to populate a
862collection view, the manifest entry may look like this:</p>
863
864<pre>&lt;service android:name=&quot;MyWidgetService&quot;
865...
866android:permission=&quot;android.permission.BIND_REMOTEVIEWS&quot; /&gt;</pre>
867
868<p>The line <code>android:name=&quot;MyWidgetService&quot;</code>
869refers to your subclass of {@link android.widget.RemoteViewsService}. </p>
870
871<h4>Layout for app widgets with collections</h4>
872
873<p>The main requirement for your app widget layout XML file is that it
874include one of the collection views: {@link android.widget.ListView},
875{@link android.widget.GridView}, {@link android.widget.StackView}, or
876{@link android.widget.AdapterViewFlipper}. Here is the
877<code>widget_layout.xml</code> for
878the <a href="{@docRoot}resources/samples/StackWidget/index.html">StackView
879Widget sample</a>:</p>
880
881<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
882
883&lt;FrameLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android";
884    android:layout_width=&quot;match_parent&quot;
885    android:layout_height=&quot;match_parent&quot;&gt;
886    &lt;StackView xmlns:android=&quot;http://schemas.android.com/apk/res/android";
887        android:id=&quot;&#64;+id/stack_view&quot;
888        android:layout_width=&quot;match_parent&quot;
889        android:layout_height=&quot;match_parent&quot;
890        android:gravity=&quot;center&quot;
891        android:loopViews=&quot;true&quot; /&gt;
892    &lt;TextView xmlns:android=&quot;http://schemas.android.com/apk/res/android";
893        android:id=&quot;&#64;+id/empty_view&quot;
894        android:layout_width=&quot;match_parent&quot;
895        android:layout_height=&quot;match_parent&quot;
896        android:gravity=&quot;center&quot;
897        android:background=&quot;&#64;drawable/widget_item_background&quot;
898        android:textColor=&quot;#ffffff&quot;
899        android:textStyle=&quot;bold&quot;
900        android:text=&quot;&#64;string/empty_view_text&quot;
901        android:textSize=&quot;20sp&quot; /&gt;
902&lt;/FrameLayout&gt;</pre>
903
904<p> Note that empty views must be siblings of the collection view for which the
905empty view represents empty state. </p>
906
907<p>In addition to the layout file for your entire app widget, you must create
908another layout file that defines the layout for each item in the collection (for
909example, a layout for each book in a collection of books). For example, the <a
910href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
911sample</a> only has one layout file, <code>widget_item.xml</code>, since all
912items use the same layout. But the <a
913href="{@docRoot}resources/samples/WeatherListWidget/index.html">
914WeatherListWidget sample</a> has two layout files:
915<code>dark_widget_item.xml</code> and <code>light_widget_item.xml</code>.</p>
916
917
918
919<h4 id="AppWidgetProvider-collections">AppWidgetProvider class for app widgets with collections</h4>
920
921<p>As with a regular app widget, the bulk of your code in your {@link
922android.appwidget.AppWidgetProvider} subclass typically goes in {@link
923android.appwidget.AppWidgetProvider#onUpdate(android.content.Context,
924android.appwidget.AppWidgetManager, int[]) onUpdate()}. The major difference in
925your implementation for {@link
926android.appwidget.AppWidgetProvider#onUpdate(android.content.Context,
927android.appwidget.AppWidgetManager, int[]) onUpdate()} when creating an app
928widget with collections is that you must call {@link
929android.widget.RemoteViews#setRemoteAdapter setRemoteAdapter()}. This tells the
930collection view where to get its data. The {@link
931android.widget.RemoteViewsService} can then return your implementation of {@link
932android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}, and
933the widget can serve up the appropriate data. When you call this method, you
934must pass an intent that  points to your implementation of {@link
935android.widget.RemoteViewsService} and the App Widget ID that specifies the app
936widget to update.</p>
937
938
939<p>For example, here's how the StackView Widget sample implements the {@link
940android.appwidget.AppWidgetProvider#onUpdate(android.content.Context,
941android.appwidget.AppWidgetManager, int[]) onUpdate()} callback method to set
942the {@link
943android.widget.RemoteViewsService} as the remote adapter for the app widget
944collection:</p>
945
946<pre>public void onUpdate(Context context, AppWidgetManager appWidgetManager,
947int[] appWidgetIds) {
948    // update each of the app widgets with the remote adapter
949    for (int i = 0; i &lt; appWidgetIds.length; ++i) {
950        
951        // Set up the intent that starts the StackViewService, which will
952        // provide the views for this collection.
953        Intent intent = new Intent(context, StackWidgetService.class);
954        // Add the app widget ID to the intent extras.
955        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
956        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
957        // Instantiate the RemoteViews object for the App Widget layout.
958        RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
959        // Set up the RemoteViews object to use a RemoteViews adapter. 
960        // This adapter connects
961        // to a RemoteViewsService  through the specified intent.
962        // This is how you populate the data.
963        rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent);
964        
965        // The empty view is displayed when the collection has no items. 
966        // It should be in the same layout used to instantiate the RemoteViews
967        // object above.
968        rv.setEmptyView(R.id.stack_view, R.id.empty_view);
969
970        //
971        // Do additional processing specific to this app widget...
972        //
973        
974        appWidgetManager.updateAppWidget(appWidgetIds[i], rv);   
975    }
976    super.onUpdate(context, appWidgetManager, appWidgetIds);
977}</pre>
978            
979<h4>RemoteViewsService class</h4>
980
981<div class="sidebox-wrapper">
982<div class="sidebox">
983<h3>Persisting data</h3>
984   <p>You can’t rely on a single instance of your service, or any data it
985contains, to persist. You should therefore not store any data in your {@link
986android.widget.RemoteViewsService} (unless it is static). If you want your
987app widget’s data to persist, the best approach is to use a {@link
988android.content.ContentProvider} whose data persists beyond the process
989lifecycle.</p> </div>
990</div>
991
992<p>As described above, your {@link android.widget.RemoteViewsService} subclass
993provides the {@link android.widget.RemoteViewsService.RemoteViewsFactory
994RemoteViewsFactory} used to  populate the remote collection view.</p> 
995
996<p>Specifically, you need to
997perform these steps:</p>
998
999<ol>
1000  <li>Subclass {@link android.widget.RemoteViewsService}. {@link
1001android.widget.RemoteViewsService} is the service through which
1002a remote adapter can request {@link android.widget.RemoteViews}.  </li>
1003  
1004  <li>In your {@link android.widget.RemoteViewsService} subclass, include a
1005class that implements the {@link
1006android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}
1007interface. {@link android.widget.RemoteViewsService.RemoteViewsFactory
1008RemoteViewsFactory} is an interface for an adapter between a remote collection
1009view (such as {@link android.widget.ListView}, {@link android.widget.GridView},
1010and so on) and  the underlying data for that view.  Your implementation is
1011responsible for making a {@link android.widget.RemoteViews} object  for each
1012item in the data set. This interface is a thin wrapper around {@link
1013android.widget.Adapter}.</li>
1014</ol>
1015
1016<p>The primary contents of the {@link android.widget.RemoteViewsService}
1017implementation is its {@link
1018android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory},
1019described below.</p>
1020
1021<h4>RemoteViewsFactory interface</h4>
1022
1023<p>Your custom class that implements the {@link
1024android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}
1025interface provides the app widget with the data for the items in its collection.
1026To
1027do this, it combines your app widget item XML layout file with a source of data.
1028This source of data could be anything from a database to a simple array. In the
1029<a href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
1030sample</a>, the data source is an array of <code>WidgetItems</code>. The {@link
1031android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}
1032functions as an adapter to glue the data to the remote collection view.</p>
1033
1034<p>The two most important methods you need to implement for your
1035
1036{@link android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}
1037subclass are 
1038{@link android.widget.RemoteViewsService.RemoteViewsFactory#onCreate()
1039onCreate()} and
1040{@link android.widget.RemoteViewsService.RemoteViewsFactory#getViewAt(int)
1041getViewAt()}
1042.</p> 
1043
1044<p>The system calls {@link
1045android.widget.RemoteViewsService.RemoteViewsFactory#onCreate() onCreate()} when
1046creating your factory for the first time. This is where you set up any
1047connections and/or cursors to your data source. For example, the <a
1048href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
1049sample</a> uses {@link
1050android.widget.RemoteViewsService.RemoteViewsFactory#onCreate() onCreate()} to
1051initialize an array of <code>WidgetItem</code> objects. When your app widget is
1052active, the system accesses these objects using their index position in the
1053array and the text they contain is displayed  </p>
1054
1055<p>Here is an excerpt from the the <a
1056href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget</a>
1057sample's 
1058{@link android.widget.RemoteViewsService.RemoteViewsFactory
1059RemoteViewsFactory} implementation that shows portions of the {@link
1060android.widget.RemoteViewsService.RemoteViewsFactory#onCreate() onCreate()}
1061method:</p>
1062
1063<pre>class StackRemoteViewsFactory implements
1064RemoteViewsService.RemoteViewsFactory {
1065    private static final int mCount = 10;
1066    private List&lt;WidgetItem&gt; mWidgetItems = new ArrayList&lt;WidgetItem&gt;();
1067    private Context mContext;
1068    private int mAppWidgetId;
1069
1070    public StackRemoteViewsFactory(Context context, Intent intent) {
1071        mContext = context;
1072        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
1073                AppWidgetManager.INVALID_APPWIDGET_ID);
1074    }
1075
1076    public void onCreate() {
1077        // In onCreate() you setup any connections / cursors to your data source. Heavy lifting,
1078        // for example downloading or creating content etc, should be deferred to onDataSetChanged()
1079        // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR.
1080        for (int i = 0; i &lt; mCount; i++) {
1081            mWidgetItems.add(new WidgetItem(i + &quot;!&quot;));
1082        }
1083        ...
1084    }
1085...</pre>
1086
1087<p>The {@link android.widget.RemoteViewsService.RemoteViewsFactory
1088RemoteViewsFactory} method {@link
1089android.widget.RemoteViewsService.RemoteViewsFactory#getViewAt(int) getViewAt()}
1090returns a {@link android.widget.RemoteViews} object corresponding to the data at
1091the specified <code>position</code> in the data set. Here is an excerpt from 
1092the <a
1093href="http://developer.android.com/resources/samples/StackWidget/index.html">
1094StackView Widget</a> sample's {@link
1095android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}
1096implementation:</p>
1097
1098<pre>public RemoteViews getViewAt(int position) {
1099   
1100    // Construct a remote views item based on the app widget item XML file, 
1101    // and set the text based on the position.
1102    RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
1103    rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);
1104
1105    ...
1106    // Return the remote views object.
1107    return rv;
1108}</pre>
1109
1110<h4 id="behavior">Adding behavior to individual items</h4>
1111
1112<p>The above sections show you how to bind your data to your app widget
1113collection. But what if you want to add dynamic behavior to the individual items
1114in your collection view?</p> 
1115
1116<p> As described in <a href="#AppWidgetProvider">Using the AppWidgetProvider
1117Class</a>, you  normally use {@link
1118android.widget.RemoteViews#setOnClickPendingIntent(int,
1119android.app.PendingIntent) setOnClickPendingIntent()} to set an object's click
1120behavior&mdash;such as to cause a button to launch an {@link
1121android.app.Activity}. But this approach is not allowed for child views in an
1122individual collection item (to clarify, you could use {@link
1123android.widget.RemoteViews#setOnClickPendingIntent(int,
1124android.app.PendingIntent) setOnClickPendingIntent()} to set up a global button
1125in the Gmail app widget that launches the app, for example, but not on the
1126individual list items). Instead, to add click behavior to individual items in a
1127collection, you  use {@link
1128android.widget.RemoteViews#setOnClickFillInIntent(int, android.content.Intent)
1129setOnClickFillInIntent()}. This entails setting up up a pending intent template
1130for your collection view, and then setting a fill-in intent on each item in the
1131collection via your {@link android.widget.RemoteViewsService.RemoteViewsFactory
1132RemoteViewsFactory}.</p> 
1133<p>This section uses the <a
1134href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
1135sample</a> to describe how to add behavior to individual items. In the <a
1136href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
1137sample</a>, if the user touches the top view, the app widget displays the {@link
1138android.widget.Toast} message &quot;Touched view <em>n</em>,&quot; where
1139<em>n</em> is the index (position) of the touched view. This is how it
1140works:</p>
1141
1142<ul>
1143  <li>The <code>StackWidgetProvider</code> (an {@link
1144android.appwidget.AppWidgetProvider} subclass) creates a pending intent that has
1145a custom action called <code>TOAST_ACTION</code>.</li>
1146  <li>When the user touches a view, the intent is fired and it broadcasts
1147<code>TOAST_ACTION</code>.</li>
1148  
1149  <li>This broadcast is intercepted by the <code>StackWidgetProvider</code>'s
1150{@link android.appwidget.AppWidgetProvider#onReceive(android.content.Context,
1151android.content.Intent) onReceive()} method, and the app widget displays the
1152{@link
1153android.widget.Toast} message for the touched view. The data for the collection
1154items is provided by the {@link
1155android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}, via
1156the {@link android.widget.RemoteViewsService}.</li>
1157</ul>
1158
1159<p class="note"><strong>Note:</strong> The <a
1160href="{@docRoot}resources/samples/StackWidget/index.html">StackView Widget
1161sample</a> uses a broadcast, but typically an app widget would simply launch an
1162activity in a scenario like this one.</p>
1163
1164<h5>Setting up the pending intent template</h5> 
1165
1166<p>The <code>StackWidgetProvider</code> ({@link
1167android.appwidget.AppWidgetProvider} subclass) sets up a pending intent.
1168Individuals items of a collection cannot set up their own pending intents.
1169Instead, the collection as a whole sets up a pending intent template, and the
1170individual items set a fill-in intent to create unique behavior on an
1171item-by-item
1172basis.</p> 
1173
1174<p>This class  also receives the broadcast that is sent when the user touches a
1175view. It processes this event in its {@link
1176android.appwidget.AppWidgetProvider#onReceive(android.content.Context,
1177android.content.Intent) onReceive()} method. If the intent's action is
1178<code>TOAST_ACTION</code>, the app widget displays a {@link
1179android.widget.Toast}
1180message for the current view.</p>
1181
1182<pre>public class StackWidgetProvider extends AppWidgetProvider {
1183    public static final String TOAST_ACTION = &quot;com.example.android.stackwidget.TOAST_ACTION&quot;;
1184    public static final String EXTRA_ITEM = &quot;com.example.android.stackwidget.EXTRA_ITEM&quot;;
1185
1186    ...
1187
1188    // Called when the BroadcastReceiver receives an Intent broadcast.
1189    // Checks to see whether the intent's action is TOAST_ACTION. If it is, the app widget 
1190    // displays a Toast message for the current item.
1191    &#64;Override
1192    public void onReceive(Context context, Intent intent) {
1193        AppWidgetManager mgr = AppWidgetManager.getInstance(context);
1194        if (intent.getAction().equals(TOAST_ACTION)) {
1195            int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
1196                AppWidgetManager.INVALID_APPWIDGET_ID);
1197            int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0);
1198            Toast.makeText(context, &quot;Touched view &quot; + viewIndex, Toast.LENGTH_SHORT).show();
1199        }
1200        super.onReceive(context, intent);
1201    }
1202    
1203    &#64;Override
1204    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
1205        // update each of the app widgets with the remote adapter
1206        for (int i = 0; i &lt; appWidgetIds.length; ++i) {
1207    
1208            // Sets up the intent that points to the StackViewService that will
1209            // provide the views for this collection.
1210            Intent intent = new Intent(context, StackWidgetService.class);
1211            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
1212            // When intents are compared, the extras are ignored, so we need to embed the extras
1213            // into the data so that the extras will not be ignored.
1214            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
1215            RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
1216            rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent);
1217    
1218            // The empty view is displayed when the collection has no items. It should be a sibling
1219            // of the collection view.
1220            rv.setEmptyView(R.id.stack_view, R.id.empty_view);
1221
1222            // This section makes it possible for items to have individualized behavior.
1223            // It does this by setting up a pending intent template. Individuals items of a collection
1224            // cannot set up their own pending intents. Instead, the collection as a whole sets
1225            // up a pending intent template, and the individual items set a fillInIntent
1226            // to create unique behavior on an item-by-item basis.
1227            Intent toastIntent = new Intent(context, StackWidgetProvider.class);
1228            // Set the action for the intent.
1229            // When the user touches a particular view, it will have the effect of
1230            // broadcasting TOAST_ACTION.
1231            toastIntent.setAction(StackWidgetProvider.TOAST_ACTION);
1232            toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
1233            intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
1234            PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
1235                PendingIntent.FLAG_UPDATE_CURRENT);
1236            rv.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent);
1237            
1238            appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
1239        }
1240    super.onUpdate(context, appWidgetManager, appWidgetIds);
1241    }
1242}</pre>
1243            
1244<h5><strong>Setting the fill-in Intent</strong></h5>
1245
1246<p>Your {@link android.widget.RemoteViewsService.RemoteViewsFactory
1247RemoteViewsFactory} must set a fill-in intent on each item in the collection.
1248This makes it possible to distinguish the individual on-click action of a given
1249item. The fill-in intent is then combined with the {@link
1250android.app.PendingIntent} template in order to determine the final intent that
1251will be executed when the item is clicked. </p>
1252
1253<pre>
1254public class StackWidgetService extends RemoteViewsService {
1255    &#64;Override
1256    public RemoteViewsFactory onGetViewFactory(Intent intent) {
1257        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
1258    }
1259}
1260
1261class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
1262    private static final int mCount = 10;
1263    private List&lt;WidgetItem&gt; mWidgetItems = new ArrayList&lt;WidgetItem&gt;();
1264    private Context mContext;
1265    private int mAppWidgetId;
1266
1267    public StackRemoteViewsFactory(Context context, Intent intent) {
1268        mContext = context;
1269        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
1270                AppWidgetManager.INVALID_APPWIDGET_ID);
1271    }
1272
1273    // Initialize the data set.
1274        public void onCreate() {
1275            // In onCreate() you set up any connections / cursors to your data source. Heavy lifting,
1276            // for example downloading or creating content etc, should be deferred to onDataSetChanged()
1277            // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR.
1278            for (int i = 0; i &lt; mCount; i++) {
1279                mWidgetItems.add(new WidgetItem(i + &quot;!&quot;));
1280            }
1281           ...
1282        }
1283        ...
1284    
1285        // Given the position (index) of a WidgetItem in the array, use the item's text value in 
1286        // combination with the app widget item XML file to construct a RemoteViews object.
1287        public RemoteViews getViewAt(int position) {
1288            // position will always range from 0 to getCount() - 1.
1289    
1290            // Construct a RemoteViews item based on the app widget item XML file, and set the
1291            // text based on the position.
1292            RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
1293            rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);
1294    
1295            // Next, set a fill-intent, which will be used to fill in the pending intent template
1296            // that is set on the collection view in StackWidgetProvider.
1297            Bundle extras = new Bundle();
1298            extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
1299            Intent fillInIntent = new Intent();
1300            fillInIntent.putExtras(extras);
1301            // Make it possible to distinguish the individual on-click
1302            // action of a given item
1303            rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
1304        
1305            ...
1306        
1307            // Return the RemoteViews object.
1308            return rv;
1309        }
1310    ...
1311    }</pre>
1312
1313<h3 id="fresh">Keeping Collection Data Fresh</h3>
1314
1315<p>The following figure illustrates the flow that occurs in an App Widget that
1316uses
1317collections when updates occur. It shows how the App Widget code interacts with
1318the  {@link android.widget.RemoteViewsService.RemoteViewsFactory
1319RemoteViewsFactory}, and how you can trigger updates:</p>
1320
1321<img src="{@docRoot}images/appwidgets/appwidget_collections.png" alt="" />
1322
1323<p>One feature of App Widgets that use collections is the ability to provide
1324users with up-to-date content. For example, consider the Android 3.0 Gmail
1325app widget, which provides users with a snapshot of their inbox. To make this
1326possible, you need to be able to trigger your {@link
1327android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory} and
1328collection view to fetch and display new data. You achieve this with the {@link
1329android.appwidget.AppWidgetManager} call {@link
1330android.appwidget.AppWidgetManager#notifyAppWidgetViewDataChanged(int, int)
1331notifyAppWidgetViewDataChanged()}. This call results in a callback to your
1332<code>RemoteViewsFactory</code>’s {@link
1333android.widget.RemoteViewsService.RemoteViewsFactory#onDataSetChanged()
1334onDataSetChanged()} method, which gives you the opportunity to fetch any new
1335data. Note that you can perform
1336processing-intensive operations synchronously within the  {@link
1337android.widget.RemoteViewsService.RemoteViewsFactory#onDataSetChanged()
1338onDataSetChanged()} callback. You are guaranteed that this call will be
1339completed before the metadata or view data is fetched from the {@link
1340android.widget.RemoteViewsService.RemoteViewsFactory RemoteViewsFactory}. In
1341addition, you can perform processing-intensive operations within the {@link
1342android.widget.RemoteViewsService.RemoteViewsFactory#getViewAt(int) getViewAt()}
1343method. If this call takes a long time, the loading view (specified by the
1344<code>RemoteViewsFactory</code>’s  {@link
1345android.widget.RemoteViewsService.RemoteViewsFactory#getLoadingView()} method)
1346will be displayed in the corresponding position of the collection view until it
1347returns.</p>
1348
1349
1350