OSDN Git Service

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