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