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