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