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