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