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