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