blob: 7a8dd599bed93ab7408a1082a65e3a272c8941ff [file] [log] [blame]
Scott Main04c72b42009-05-13 16:48:13 -07001page.title=App Widgets
Scott Main620986a2009-04-22 18:58:13 -07002@jd:body
3
4<div id="qv-wrapper">
5 <div id="qv">
6 <h2>Key classes</h2>
7 <ol>
8 <li>{@link android.appwidget.AppWidgetProvider}</li>
Scott Main04c72b42009-05-13 16:48:13 -07009 <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
10 <li>{@link android.appwidget.AppWidgetManager}</li>
Scott Main620986a2009-04-22 18:58:13 -070011 </ol>
12 <h2>In this document</h2>
13 <ol>
Scott Main04c72b42009-05-13 16:48:13 -070014 <li><a href="#Basics">The Basics</a></li>
15 <li><a href="#Manifest">Declaring an App Widget in the Manifest</a></li>
16 <li><a href="#MetaData">Adding the AppWidgetProviderInfo Metadata</a></li>
17 <li><a href="#CreatingLayout">Creating the App Widget Layout</a></li>
18 <li><a href="#AppWidgetProvider">Using the AppWidgetProvider Class</a>
Scott Main620986a2009-04-22 18:58:13 -070019 <ol>
Scott Main04c72b42009-05-13 16:48:13 -070020 <li><a href="#ProviderBroadcasts">Receiving App Widget broadcast Intents</a></li>
Scott Main620986a2009-04-22 18:58:13 -070021 </ol>
22 </li>
Scott Main04c72b42009-05-13 16:48:13 -070023 <li><a href="#Configuring">Creating an App Widget Configuration Activity</a>
24 <ol>
25 <li><a href="#UpdatingFromTheConfiguration">Updating the App Widget from
26 the configuration Activity</a></li>
27 </ol>
28 </li>
Scott Main620986a2009-04-22 18:58:13 -070029 </ol>
30
31 <h2>See also</h2>
32 <ol>
Scott Main04c72b42009-05-13 16:48:13 -070033 <li><a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design
34 Guidelines</a></li>
Scott Main620986a2009-04-22 18:58:13 -070035 <li><a href="http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html">Introducing
Scott Main04c72b42009-05-13 16:48:13 -070036 home screen widgets and the AppWidget framework &raquo;</a></li>
Scott Main620986a2009-04-22 18:58:13 -070037 </ol>
38 </div>
39</div>
40
Scott Main04c72b42009-05-13 16:48:13 -070041
42<p>App Widgets are miniature application views that can be embedded in other applications
43(such as the Home screen) and receive periodic updates. These views are referred
44to as Widgets in the user interface,
45and you can publish one with an App Widget provider. An application component that is
46able to hold other App Widgets is called an App Widget host. The screenshot below shows
47the Music App Widget.</p>
48
49<img src="{@docRoot}images/appwidget.png" alt="" />
50
51<p>This document describes how to publish an App Widget using an App Widget provider.</p>
Scott Main620986a2009-04-22 18:58:13 -070052
53
Scott Main04c72b42009-05-13 16:48:13 -070054<h2 id="Basics">The Basics</h2>
55
56<p>To create an App Widget, you need the following:</p>
57
58<dl>
59 <dt>{@link android.appwidget.AppWidgetProviderInfo} object</dt>
60 <dd>Describes the metadata for an App Widget, such as the App Widget's layout, update frequency,
61 and the AppWidgetProvider class. This should be defined in XML.</dd>
62 <dt>{@link android.appwidget.AppWidgetProvider} class implementation</dt>
63 <dd>Defines the basic methods that allow you to programmatically interface with the App Widget,
64 based on broadcast events. Through it, you will receive broadcasts when the App Widget is updated,
65 enabled, disabled and deleted.</dd>
66 <dt>View layout</dt>
67 <dd>Defines the initial layout for the App Widget, defined in XML.</dd>
68</dl>
69
70<p>Additionally, you can implement an App Widget configuration Activity. This is an optional
71{@link android.app.Activity} that launches when the user adds your App Widget and allows him or her
72to modify App Widget settings at create-time.</p>
73
74<p>The following sections describe how to setup each of these components.</p>
Scott Main620986a2009-04-22 18:58:13 -070075
76
Scott Main04c72b42009-05-13 16:48:13 -070077<h2 id="Manifest">Declaring an App Widget in the Manifest</h2>
Scott Main620986a2009-04-22 18:58:13 -070078
Scott Main04c72b42009-05-13 16:48:13 -070079<p>First, declare the {@link android.appwidget.AppWidgetProvider} class in your application's
80<code>AndroidManifest.xml</code> file. For example:</p>
Scott Main620986a2009-04-22 18:58:13 -070081
Scott Main04c72b42009-05-13 16:48:13 -070082<pre>
83&lt;receiver android:name="ExampleAppWidgetProvider" >
84 &lt;intent-filter>
85 &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
86 &lt;/intent-filter>
87 &lt;meta-data android:name="android.appwidget.provider"
88 android:resource="@xml/example_appwidget_info" />
89&lt;/receiver>
90</pre>
Scott Main620986a2009-04-22 18:58:13 -070091
Scott Main04c72b42009-05-13 16:48:13 -070092<p>The <code>&lt;receiver&gt;</code> element requires the <code>android:name</code>
93attribute, which specifies the {@link android.appwidget.AppWidgetProvider} used
94by the App Widget.</p>
Scott Main620986a2009-04-22 18:58:13 -070095
Scott Main04c72b42009-05-13 16:48:13 -070096<p>The <code>&lt;intent-filter&gt;</code> element must include an <code>&lt;action></code>
97element with the <code>android:name</code> attribute. This attribute specifies
98that the {@link android.appwidget.AppWidgetProvider} accepts the {@link
99android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE ACTION_APPWIDGET_UPDATE} broadcast.
100This is the only broadcast that you must explicitly declare. The {@link android.appwidget.AppWidgetManager}
101automatically sends all other App Widget broadcasts to the AppWidgetProvider as necessary.</p>
Scott Main620986a2009-04-22 18:58:13 -0700102
Scott Main04c72b42009-05-13 16:48:13 -0700103<p>The <code>&lt;meta-data&gt;</code> element specifies the
104{@link android.appwidget.AppWidgetProviderInfo} resource and requires the
105following attributes:</p>
Scott Main620986a2009-04-22 18:58:13 -0700106<ul>
Scott Main04c72b42009-05-13 16:48:13 -0700107 <li><code>android:name</code> - Specifies the metadata name. Use <code>android.appwidget.provider</code>
108 to identify the data as the {@link android.appwidget.AppWidgetProviderInfo} descriptor.</li>
109 <li><code>android:resource</code> - Specifies the {@link android.appwidget.AppWidgetProviderInfo}
110 resource location.</li>
Scott Main620986a2009-04-22 18:58:13 -0700111</ul>
112
113
Scott Main04c72b42009-05-13 16:48:13 -0700114<h2 id="MetaData">Adding the AppWidgetProviderInfo Metadata</h2>
Scott Main620986a2009-04-22 18:58:13 -0700115
Scott Main04c72b42009-05-13 16:48:13 -0700116<p>The {@link android.appwidget.AppWidgetProviderInfo} defines the essential
117qualities of an App Widget, such as its minimum layout dimensions, its initial layout resource,
118how often to update the App Widget, and (optionally) a configuration Activity to launch at create-time.
119Define the AppWidgetProviderInfo object in an XML resource using a single
120<code>&lt;appwidget-provider></code> element and save it in the project's <code>res/xml/</code>
121folder.</p>
Scott Main620986a2009-04-22 18:58:13 -0700122
Scott Main04c72b42009-05-13 16:48:13 -0700123<p>For example:</p>
Scott Main620986a2009-04-22 18:58:13 -0700124
Scott Main04c72b42009-05-13 16:48:13 -0700125<pre>
126&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
Scott Main33e0f002009-12-03 11:33:25 -0800127 android:minWidth="294dp"
Scott Main04c72b42009-05-13 16:48:13 -0700128 android:minHeight="72dp"
Scott Main33e0f002009-12-03 11:33:25 -0800129 android:updatePeriodMillis="86400000"
Scott Main04c72b42009-05-13 16:48:13 -0700130 android:initialLayout="@layout/example_appwidget"
131 android:configure="com.example.android.ExampleAppWidgetConfigure" >
132&lt;/appwidget-provider>
133</pre>
134
135<p>Here's a summary of the <code>&lt;appwidget-provider></code> attributes:</p>
136<ul>
137 <li>The values for the <code>minWidth</code> and <code>minHeight</code> attributes specify the minimum
138 area required by the App Widget's layout.
139 <p>The default Home screen positions App Widgets in its window based on a grid of
140 cells that have a defined height and width. If the values for an App Widget's minimum width
141 or height don't match the dimensions of the cells,
142 then the App Widget dimensions round <em>up</em> to the nearest cell size.
143 (See the <a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design
144 Guidelines</a> for more information on the Home screen cell sizes.)</p>
145 <p>Because the Home screen's layout orientation (and thus, the cell sizes) can change,
146 as a rule of thumb, you should assume the worst-case cell size of 74 pixels for the height
147 <em>and</em> width of a cell. However, you must subtract 2 from the final dimension to account
148 for any integer rounding errors that occur in the pixel count. To find your minimum width
149 and height in density-independent pixels (dp), use this formula:<br/>
150 <code>(number of cells * 74) - 2</code><br/>
151 Following this formula, you should use 72 dp for a height of one cell, 294 dp and for a width of four cells.</p>
152 </li>
Scott Maine5186062009-07-15 16:52:31 -0700153 <li>The <code>updatePeriodMillis</code> attribute defines how often the App Widget framework should
Scott Main04c72b42009-05-13 16:48:13 -0700154 request an update from the {@link android.appwidget.AppWidgetProvider} by calling the
155 {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
156 onUpdate()} method. The actual update is not guaranteed to occur exactly on time with this value
157 and we suggest updating as infrequently as possible&mdash;perhaps no more than once an hour to
158 conserve the battery. You might also allow the user to adjust the frequency in a
159 configuration&mdash;some people might want a stock ticker to update every 15 minutes, or maybe
Scott Maine5186062009-07-15 16:52:31 -0700160 only four times a day.
161 <p class="note"><strong>Note:</strong> If the device is asleep when it is time for an update
162 (as defined by <code>updatePeriodMillis</code>), then the device will wake up in order
163 to perform the update. If you don't update more than once per hour, this probably won't
164 cause significant problems for the battery life. If, however, you need to update more
165 frequently and/or you do not need to update while the device is asleep, then you can instead
166 perform updates based on an alarm that will not wake the device. To do so, set an alarm with
167 an Intent that your AppWidgetProvider receives, using the {@link android.app.AlarmManager}.
168 Set the alarm type to either {@link android.app.AlarmManager#ELAPSED_REALTIME} or
169 {@link android.app.AlarmManager#RTC}, which will only
170 deliver the alarm when the device is awake. Then set <code>updatePeriodMillis</code> to
171 zero (<code>"0"</code>).</p>
172 </li>
Scott Main04c72b42009-05-13 16:48:13 -0700173 <li>The <code>initialLayout</code> attribute points to the layout resource that defines the
174 App Widget layout.</li>
175 <li>The <code>configure</code> attribute defines the {@link android.app.Activity} to launch when
176 the user adds the App Widget, in order for him or her to configure App Widget properties. This is optional
177 (read <a href="#Configuring">Creating an App Widget Configuration Activity</a> below).</li>
178</ul>
179
180<p>See the {@link android.appwidget.AppWidgetProviderInfo} class for more information on the
181attributes accepted by the <code>&lt;appwidget-provider></code> element.</p>
Scott Main620986a2009-04-22 18:58:13 -0700182
183
Scott Main04c72b42009-05-13 16:48:13 -0700184<h2 id="CreatingLayout">Creating the App Widget Layout</h2>
Scott Main620986a2009-04-22 18:58:13 -0700185
Scott Main04c72b42009-05-13 16:48:13 -0700186<p>You must define an initial layout for your App Widget in XML and save it in the project's
187<code>res/layout/</code> directory. You can design your App Widget using the View objects listed
188below, but before you begin designing your App Widget, please read and understand the
189<a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design
190Guidelines</a>.</p>
Scott Main620986a2009-04-22 18:58:13 -0700191
Scott Main04c72b42009-05-13 16:48:13 -0700192<p>Creating the App Widget layout is simple if you're
193familiar with <a href="{@docRoot}guide/topics/ui/declaring-layout.html">Declaring Layout in XML</a>.
194However, you must be aware that App Widget layouts are based on {@link android.widget.RemoteViews},
195which do not support every kind of layout or view widget.</p>
196
197<p>A RemoteViews object (and, consequently, an App Widget) can support the
198following layout classes:</p>
199
200<ul class="nolist">
201 <li>{@link android.widget.FrameLayout}</li>
202 <li>{@link android.widget.LinearLayout}</li>
203 <li>{@link android.widget.RelativeLayout}</li>
204</ul>
205
206<p>And the following widget classes:</p>
207<ul class="nolist">
208 <li>{@link android.widget.AnalogClock}</li>
209 <li>{@link android.widget.Button}</li>
210 <li>{@link android.widget.Chronometer}</li>
211 <li>{@link android.widget.ImageButton}</li>
212 <li>{@link android.widget.ImageView}</li>
213 <li>{@link android.widget.ProgressBar}</li>
214 <li>{@link android.widget.TextView}</li>
215</ul>
216
217<p>Descendants of these classes are not supported.</p>
Scott Main620986a2009-04-22 18:58:13 -0700218
219
Scott Main04c72b42009-05-13 16:48:13 -0700220<h2 id="AppWidgetProvider">Using the AppWidgetProvider Class</h2>
Scott Main620986a2009-04-22 18:58:13 -0700221
Scott Main04c72b42009-05-13 16:48:13 -0700222<div class="sidebox-wrapper">
Scott Mainf54574a2010-03-24 17:18:01 -0700223<div class="sidebox">
Scott Main04c72b42009-05-13 16:48:13 -0700224 <p>You must declare your AppWidgetProvider class implementation as a broadcast receiver
225 using the <code>&lt;receiver></code> element in the AndroidManifest (see
226 <a href="#Manifest">Declaring an App Widget in the Manifest</a> above).</p>
227 </div>
228</div>
Scott Main620986a2009-04-22 18:58:13 -0700229
Scott Main04c72b42009-05-13 16:48:13 -0700230<p>The {@link android.appwidget.AppWidgetProvider} class extends BroadcastReceiver as a convenience
231class to handle the App Widget broadcasts. The AppWidgetProvider receives only the event broadcasts that
232are relevant to the App Widget, such as when the App Widget is updated, deleted, enabled, and disabled.
233When these broadcast events occur, the AppWidgetProvider receives the following method calls:</p>
Scott Main620986a2009-04-22 18:58:13 -0700234
Scott Main04c72b42009-05-13 16:48:13 -0700235<dl>
236 <dt>{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])}</dt>
237 <dd>This is called to update the App Widget at intervals defined by the <code>updatePeriodMillis</code>
238 attribute in the AppWidgetProviderInfo (see <a href="#MetaData">Adding the
239 AppWidgetProviderInfo Metadata</a> above). This method is also called
240 when the user adds the App Widget, so it should perform the essential setup,
241 such as define event handlers for Views and start a temporary
242 {@link android.app.Service}, if necessary. However, if you have declared a configuration
243 Activity, <strong>this method is not called</strong> when the user adds the App Widget,
244 but is called for the subsequent updates. It is the responsibility of the
245 configuration Activity to perform the first update when configuration is done.
246 (See <a href="#Configuring">Creating an App Widget Configuration Activity</a> below.)</dd>
247 <dt>{@link android.appwidget.AppWidgetProvider#onDeleted(Context,int[])}</dt>
248 <dd>This is called every time an App Widget is deleted from the App Widget host.</dd>
249 <dt>{@link android.appwidget.AppWidgetProvider#onEnabled(Context)}</dt>
250 <dd>This is called when an instance the App Widget is created for the first time. For example, if the user
251 adds two instances of your App Widget, this is only called the first time.
252 If you need to open a new database or perform other setup that only needs to occur once
253 for all App Widget instances, then this is a good place to do it.</dd>
254 <dt>{@link android.appwidget.AppWidgetProvider#onDisabled(Context)}</dt>
255 <dd>This is called when the last instance of your App Widget is deleted from the App Widget host.
256 This is where you should clean up any work done in
257 {@link android.appwidget.AppWidgetProvider#onEnabled(Context)},
258 such as delete a temporary database.</dd>
259 <dt>{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)}</dt>
260 <dd>This is called for every broadcast and before each of the above callback methods.
261 You normally don't need to implement this method because the default AppWidgetProvider
262 implementation filters all App Widget broadcasts and calls the above
263 methods as appropriate.</dd>
264</dl>
Scott Main620986a2009-04-22 18:58:13 -0700265
Scott Main04c72b42009-05-13 16:48:13 -0700266<p class="warning"><strong>Note:</strong> In Android 1.5, there is a known issue in which the
267<code>onDeleted()</code> method will not be called when it should be. To work around this issue,
268you can implement {@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)
269onReceive()} as described in this
270<a href="http://groups.google.com/group/android-developers/msg/e405ca19df2170e2">Group post</a>
271to receive the <code>onDeleted()</code> callback.
272</p>
273
274<p>The most important AppWidgetProvider callback is
275{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
276onUpdated()} because it is called when each App Widget is added to a host (unless you use
277a configuration Activity). If your App Widget accepts any
278user interaction events, then you need to register the event handlers in this callback.
279If your App Widget doesn't create temporary
280files or databases, or perform other work that requires clean-up, then
281{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
282onUpdated()} may be the only callback method you need to define. For example, if you want an App Widget
283with a button that launches an Activity when clicked, you could use the following
284implementation of AppWidgetProvider:</p>
285
286<pre>
287public class ExampleAppWidgetProvider extends AppWidgetProvider {
288
289 public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
290 final int N = appWidgetIds.length;
291
292 // Perform this loop procedure for each App Widget that belongs to this provider
293 for (int i=0; i&lt;N; i++) {
294 int appWidgetId = appWidgetIds[i];
295
296 // Create an Intent to launch ExampleActivity
297 Intent intent = new Intent(context, ExampleActivity.class);
298 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
299
300 // Get the layout for the App Widget and attach an on-click listener to the button
301 RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
302 views.setOnClickPendingIntent(R.id.button, pendingIntent);
303
304 // Tell the AppWidgetManager to perform an update on the current App Widget
305 appWidgetManager.updateAppWidget(appWidgetId, views);
306 }
307 }
308}
309</pre>
310
311<p>This AppWidgetProvider defines only the
312{@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
313onUpdated()} method for the purpose
314of defining a {@link android.app.PendingIntent} that launches an {@link android.app.Activity}
315and attaching it to the App Widget's button
316with {@link android.widget.RemoteViews#setOnClickPendingIntent(int,PendingIntent)}.
317Notice that it includes a loop that iterates through each entry in <code>appWidgetIds</code>, which
318is an array of IDs that identify each App Widget created by this provider.
319In this way, if the user creates more than one instance of the App Widget, then they are
320all updated simultaneously. However, only one <code>updatePeriodMillis</code> schedule will be
321managed for all instances of the App Widget. For example, if the update schedule is defined
322to be every two hours, and a second instance
323of the App Widget is added one hour after the first one, then they will both be updated
324on the period defined by the first one and the second update period will be ignored
325(they'll both be updated every two hours, not every hour).</p>
326
327<p class="note"><strong>Note:</strong> Because the AppWidgetProvider is a BroadcastReceiver,
328your process is not guaranteed to keep running after the callback methods return (see
329<a href="{@docRoot}guide/topics/fundamentals.html#broadlife">Application Fundamentals &gt;
330Broadcast Receiver Lifecycle</a> for more information). If your App Widget setup process can take several
331seconds (perhaps while performing web requests) and you require that your process continues,
332consider starting a {@link android.app.Service}
333in the {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
334onUpdated()} method. From within the Service, you can perform your own updates to the App Widget
335without worrying about the AppWidgetProvider closing down due to an
336<a href="{@docRoot}guide/practices/design/responsiveness.html">Application Not Responding</a>
337(ANR) error. See the
338<a href="http://code.google.com/p/wiktionary-android/source/browse/trunk/Wiktionary/src/com/example/android/wiktionary/WordWidget.java">Wiktionary
339sample's AppWidgetProvider</a> for an example of an App Widget running a {@link android.app.Service}.</p>
340
341<p>Also see the <a
Dirk Dougherty22558d02009-12-10 16:25:06 -0800342href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.html">
Scott Main04c72b42009-05-13 16:48:13 -0700343ExampleAppWidgetProvider.java</a> sample class.</p>
Scott Main620986a2009-04-22 18:58:13 -0700344
345
Scott Main04c72b42009-05-13 16:48:13 -0700346<h3 id="ProviderBroadcasts">Receiving App Widget broadcast Intents</h3>
Scott Main620986a2009-04-22 18:58:13 -0700347
348<p>{@link android.appwidget.AppWidgetProvider} is just a convenience class. If you would like
Scott Main04c72b42009-05-13 16:48:13 -0700349to receive the App Widget broadcasts directly, you can implement your own
350{@link android.content.BroadcastReceiver} or override the
351{@link android.appwidget.AppWidgetProvider#onReceive(Context,Intent)} callback.
352The four Intents you need to care about are:</p>
Scott Main620986a2009-04-22 18:58:13 -0700353<ul>
354 <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE}</li>
355 <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DELETED}</li>
356 <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_ENABLED}</li>
357 <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DISABLED}</li>
358</ul>
359
Scott Main620986a2009-04-22 18:58:13 -0700360
361
Scott Main04c72b42009-05-13 16:48:13 -0700362<h2 id="Configuring">Creating an App Widget Configuration Activity</h2>
Scott Main620986a2009-04-22 18:58:13 -0700363
Scott Main04c72b42009-05-13 16:48:13 -0700364<p>If you would like the user to configure settings when he or she adds a new App Widget,
365you can create an App Widget configuration Activity. This {@link android.app.Activity}
366will be automatically launched by the App Widget host and allows the user to configure
367available settings for the App Widget at create-time, such as the App Widget color, size,
368update period or other functionality settings.</p>
369
370<p>The configuration Activity should be declared as a normal Activity in the Android manifest file.
371However, it will be launched by the App Widget host with the {@link
372android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE ACTION_APPWIDGET_CONFIGURE} action,
373so the Activity needs to accept this Intent. For example:</p>
374
375<pre>
376&lt;activity android:name=".ExampleAppWidgetConfigure">
377 &lt;intent-filter>
378 &lt;action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
379 &lt;/intent-filter>
380&lt;/activity>
381</pre>
382
383<p>Also, the Activity must be declared in the AppWidgetProviderInfo XML file, with the
384<code>android:configure</code> attribute (see <a href="#MetaData">Adding
Elliott Hughes7f877062009-07-30 17:00:34 -0700385the AppWidgetProviderInfo Metadata</a> above). For example, the configuration Activity
Scott Main04c72b42009-05-13 16:48:13 -0700386can be declared like this:</p>
387
388<pre>
389&lt;appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
390 ...
391 android:configure="com.example.android.ExampleAppWidgetConfigure"
392 ... >
393&lt;/appwidget-provider>
394</pre>
395
396<p>Notice that the Activity is declared with a fully-qualified namespace, because
397it will be referenced from outside your package scope.</p>
398
399<p>That's all you need to get started with a configuration Activity. Now all you need is the actual
400Activity. There are, however, two important things to remember when you implement the Activity:</p>
401<ul>
402 <li>The App Widget host calls the configuration Activity and the configuration Activity should always
403 return a result. The result should include the App Widget ID
404 passed by the Intent that launched the Activity (saved in the Intent extras as
405 {@link android.appwidget.AppWidgetManager#EXTRA_APPWIDGET_ID}).</li>
406 <li>The {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
407 onUpdate()} method <strong>will not be called</strong> when the App Widget is created
408 (the system will not send the ACTION_APPWIDGET_UPDATE broadcast when a configuration Activity
409 is launched). It is the responsibility of the configuration Activity to request an update from the
410 AppWidgetManager when the App Widget is first created. However,
411 {@link android.appwidget.AppWidgetProvider#onUpdate(Context,AppWidgetManager,int[])
412 onUpdate()} will be called for subsequent updates&mdash;it is only skipped the first time.</li>
413</ul>
414
415<p>See the code snippets in the following section for an example of how to return a result
416from the configuration and update the App Widget.</p>
417
418
419<h3 id="UpdatingFromTheConfiguration">Updating the App Widget from the configuration Activity</h3>
420
421<p>When an App Widget uses a configuration Activity, it is the responsibility of the Activity
422to update the App Widget when configuration is complete.
423You can do so by requesting an update directly from the
424{@link android.appwidget.AppWidgetManager}.</p>
425
426<p>Here's a summary of the procedure to properly update the App Widget and close
427the configuration Activity:</p>
428
429<ol>
430 <li>First, get the App Widget ID from the Intent that launched the Activity:
431<pre>
432Intent intent = getIntent();
433Bundle extras = intent.getExtras();
434if (extras != null) {
435 mAppWidgetId = extras.getInt(
436 AppWidgetManager.EXTRA_APPWIDGET_ID,
437 AppWidgetManager.INVALID_APPWIDGET_ID);
438}
439</pre>
440 </li>
441 <li>Perform your App Widget configuration.</li>
442 <li>When the configuration is complete, get an instance of the AppWidgetManager by calling
443 {@link android.appwidget.AppWidgetManager#getInstance(Context)}:
444<pre>
445AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
446</pre>
447 </li>
448 <li>Update the App Widget with a {@link android.widget.RemoteViews} layout by calling
449 {@link android.appwidget.AppWidgetManager#updateAppWidget(int,RemoteViews)}:
450<pre>
451RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget);
452appWidgetManager.updateAppWidget(mAppWidgetId, views);
453</pre>
454 </li>
455 <li>Finally, create the return Intent, set it with the Activity result, and finish the Activity:</li>
456<pre>
457Intent resultValue = new Intent();
458resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
459setResult(RESULT_OK, resultValue);
460finish();
461</pre>
462 </li>
463</ol>
464
465<p class="note"><strong>Tip:</strong> When your configuration Activity first opens, set
466the Activity result to RESULT_CANCELED. This way, if the user backs-out of the Activity before
467reaching the end, the App Widget host is notified that the configuration was cancelled and the
468App Widget will not be added.</p>
469
470<p>See the <a
Dirk Dougherty22558d02009-12-10 16:25:06 -0800471href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetConfigure.html">
Scott Main04c72b42009-05-13 16:48:13 -0700472ExampleAppWidgetConfigure.java</a> sample class in ApiDemos for an example.</p>
473
474
475