OSDN Git Service

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