blob: 8a89cbc236c6afda694ff69f424846dbe730e68e [file] [log] [blame]
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -07001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.appwidget;
18
19import android.content.ComponentName;
20import android.content.Context;
Winson Chung81f39eb2011-01-11 18:05:01 -080021import android.content.Intent;
Adam Cohene8724c82012-04-19 17:11:40 -070022import android.os.Bundle;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070023import android.os.IBinder;
24import android.os.RemoteException;
25import android.os.ServiceManager;
Amith Yamasanic566b432012-11-30 15:26:21 -080026import android.os.UserHandle;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -070027import android.util.DisplayMetrics;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -070028import android.util.TypedValue;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070029import android.widget.RemoteViews;
30
31import com.android.internal.appwidget.IAppWidgetService;
32
33import java.lang.ref.WeakReference;
34import java.util.List;
35import java.util.WeakHashMap;
36
37/**
38 * Updates AppWidget state; gets information about installed AppWidget providers and other
39 * AppWidget related state.
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080040 *
41 * <div class="special reference">
42 * <h3>Developer Guides</h3>
43 * <p>For more information about creating app widgets, read the
44 * <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a> developer guide.</p>
45 * </div>
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070046 */
47public class AppWidgetManager {
48 static final String TAG = "AppWidgetManager";
49
50 /**
Dianne Hackborna40cfeb2013-03-25 17:49:36 -070051 * Activity action to launch from your {@link AppWidgetHost} activity when you want to
52 * pick an AppWidget to display. The AppWidget picker activity will be launched.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070053 * <p>
54 * You must supply the following extras:
55 * <table>
56 * <tr>
57 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
58 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
59 * once the user has selected one.</td>
60 * </tr>
61 * </table>
62 *
63 * <p>
64 * The system will respond with an onActivityResult call with the following extras in
65 * the intent:
66 * <table>
67 * <tr>
68 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
69 * <td>The appWidgetId that you supplied in the original intent.</td>
70 * </tr>
71 * </table>
72 * <p>
73 * When you receive the result from the AppWidget pick activity, if the resultCode is
74 * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected. You should then
75 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its configuration
76 * activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete
77 * the appWidgetId.
78 *
79 * @see #ACTION_APPWIDGET_CONFIGURE
80 */
81 public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
82
83 /**
Michael Jurkafc753c02012-10-30 18:30:52 -070084 * Similar to ACTION_APPWIDGET_PICK, but used from keyguard
85 * @hide
86 */
87 public static final String
88 ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK";
89
90 /**
Dianne Hackborna40cfeb2013-03-25 17:49:36 -070091 * Activity action to launch from your {@link AppWidgetHost} activity when you want to bind
92 * an AppWidget to display and bindAppWidgetIdIfAllowed returns false.
Michael Jurka61a5b012012-04-13 10:39:45 -070093 * <p>
94 * You must supply the following extras:
95 * <table>
96 * <tr>
97 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
98 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
99 * you provide.</td>
100 * </tr>
101 * <tr>
102 * <td>{@link #EXTRA_APPWIDGET_PROVIDER}</td>
103 * <td>The BroadcastReceiver that will be the AppWidget provider for this AppWidget.
104 * </td>
105 * </tr>
106 * </table>
107 *
108 * <p>
109 * The system will respond with an onActivityResult call with the following extras in
110 * the intent:
111 * <table>
112 * <tr>
113 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
114 * <td>The appWidgetId that you supplied in the original intent.</td>
115 * </tr>
116 * </table>
117 * <p>
118 * When you receive the result from the AppWidget bind activity, if the resultCode is
119 * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound. You should then
120 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
121 * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you
122 * should delete
123 * the appWidgetId.
124 *
125 * @see #ACTION_APPWIDGET_CONFIGURE
126 *
127 */
128 public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND";
129
130 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700131 * Sent when it is time to configure your AppWidget while it is being added to a host.
132 * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity
133 * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo meta-data}.
134 *
135 * <p>
136 * The intent will contain the following extras:
137 * <table>
138 * <tr>
139 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
140 * <td>The appWidgetId to configure.</td>
141 * </tr>
142 * </table>
143 *
144 * <p>If you return {@link android.app.Activity#RESULT_OK} using
145 * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added,
146 * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget.
147 * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
148 * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} broadcast.
149 */
150 public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
151
152 /**
153 * An intent extra that contains one appWidgetId.
154 * <p>
155 * The value will be an int that can be retrieved like this:
156 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID}
157 */
158 public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
159
160 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700161 * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700162 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700163 public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
Adam Cohene8724c82012-04-19 17:11:40 -0700164
165 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700166 * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700167 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700168 public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
Adam Cohene8724c82012-04-19 17:11:40 -0700169
170 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700171 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700172 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700173 public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
Adam Cohene8724c82012-04-19 17:11:40 -0700174
175 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700176 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700177 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700178 public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
Adam Cohene8724c82012-04-19 17:11:40 -0700179
180 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700181 * A bundle extra that hints to the AppWidgetProvider the category of host that owns this
182 * this widget. Can have the value {@link
183 * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link
184 * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}.
185 */
186 public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
187
188 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700189 * An intent extra which points to a bundle of extra information for a particular widget id.
190 * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT.
191 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700192 public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
Adam Cohene8724c82012-04-19 17:11:40 -0700193
194 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700195 * An intent extra that contains multiple appWidgetIds.
196 * <p>
197 * The value will be an int array that can be retrieved like this:
198 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
199 */
200 public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
201
202 /**
Michael Jurka61a5b012012-04-13 10:39:45 -0700203 * An intent extra that contains the component name of a AppWidget provider.
204 * <p>
205 * The value will be an ComponentName.
206 */
207 public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
208
209 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700210 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
211 * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are
212 * installed. (This is how the launcher shows the search widget).
213 */
214 public static final String EXTRA_CUSTOM_INFO = "customInfo";
215
216 /**
217 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
218 * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are
219 * installed. It will be added to the extras object on the {@link android.content.Intent}
220 * that is returned from the picker activity.
221 *
222 * {@more}
223 */
224 public static final String EXTRA_CUSTOM_EXTRAS = "customExtras";
225
226 /**
Adam Cohen8c09f632012-09-11 18:23:35 -0700227 * An intent extra to pass to the AppWidget picker which allows the picker to filter
228 * the list based on the {@link AppWidgetProviderInfo#widgetCategory}.
Jim Millerf229e4d2012-09-12 20:32:50 -0700229 *
230 * @hide
Adam Cohen8c09f632012-09-11 18:23:35 -0700231 */
Adam Cohen8c09f632012-09-11 18:23:35 -0700232 public static final String EXTRA_CATEGORY_FILTER = "categoryFilter";
233
234 /**
Jim Millerf229e4d2012-09-12 20:32:50 -0700235 * An intent extra to pass to the AppWidget picker to specify whether or not to sort
236 * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets
237 * @hide
238 */
239 public static final String EXTRA_CUSTOM_SORT = "customSort";
240
241 /**
Scott Main6aad9952013-01-07 18:51:49 -0800242 * A sentinel value that the AppWidget manager will never return as a appWidgetId.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700243 */
244 public static final int INVALID_APPWIDGET_ID = 0;
245
246 /**
247 * Sent when it is time to update your AppWidget.
248 *
249 * <p>This may be sent in response to a new instance for this AppWidget provider having
250 * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval}
251 * having lapsed, or the system booting.
252 *
253 * <p>
254 * The intent will contain the following extras:
255 * <table>
256 * <tr>
257 * <td>{@link #EXTRA_APPWIDGET_IDS}</td>
258 * <td>The appWidgetIds to update. This may be all of the AppWidgets created for this
259 * provider, or just a subset. The system tries to send updates for as few AppWidget
260 * instances as possible.</td>
261 * </tr>
262 * </table>
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200263 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700264 * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
265 */
266 public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
267
268 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700269 * Sent when the custom extras for an AppWidget change.
270 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700271 * <p class="note">This is a protected intent that can only be sent
272 * by the system.
273 *
Jim Millera75a8832013-02-07 16:53:32 -0800274 * @see AppWidgetProvider#onAppWidgetOptionsChanged
275 * AppWidgetProvider.onAppWidgetOptionsChanged(Context context,
Katie McCormick0e9f34b2012-09-10 15:32:46 -0700276 * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
Adam Cohene8724c82012-04-19 17:11:40 -0700277 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700278 public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
Adam Cohene8724c82012-04-19 17:11:40 -0700279
280 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700281 * Sent when an instance of an AppWidget is deleted from its host.
282 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700283 * <p class="note">This is a protected intent that can only be sent
284 * by the system.
285 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700286 * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
287 */
288 public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
289
290 /**
291 * Sent when an instance of an AppWidget is removed from the last host.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200292 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700293 * <p class="note">This is a protected intent that can only be sent
294 * by the system.
295 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700296 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
297 */
298 public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
299
300 /**
301 * Sent when an instance of an AppWidget is added to a host for the first time.
302 * This broadcast is sent at boot time if there is a AppWidgetHost installed with
303 * an instance for this provider.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200304 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700305 * <p class="note">This is a protected intent that can only be sent
306 * by the system.
307 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700308 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
309 */
310 public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
311
312 /**
313 * Field for the manifest meta-data tag.
314 *
315 * @see AppWidgetProviderInfo
316 */
317 public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200318
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200319 static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache =
320 new WeakHashMap<Context, WeakReference<AppWidgetManager>>();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700321 static IAppWidgetService sService;
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200322
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700323 Context mContext;
324
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700325 private DisplayMetrics mDisplayMetrics;
326
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700327 /**
328 * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
329 * Context} object.
330 */
331 public static AppWidgetManager getInstance(Context context) {
332 synchronized (sManagerCache) {
333 if (sService == null) {
334 IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
335 sService = IAppWidgetService.Stub.asInterface(b);
336 }
337
338 WeakReference<AppWidgetManager> ref = sManagerCache.get(context);
339 AppWidgetManager result = null;
340 if (ref != null) {
341 result = ref.get();
342 }
343 if (result == null) {
344 result = new AppWidgetManager(context);
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200345 sManagerCache.put(context, new WeakReference<AppWidgetManager>(result));
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700346 }
347 return result;
348 }
349 }
350
351 private AppWidgetManager(Context context) {
352 mContext = context;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700353 mDisplayMetrics = context.getResources().getDisplayMetrics();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700354 }
355
356 /**
357 * Set the RemoteViews to use for the specified appWidgetIds.
358 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700359 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
360 * contain a complete representation of the widget. For performing partial widget updates, see
361 * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}.
362 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700363 * <p>
364 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
365 * and outside of the handler.
366 * This method will only work when called from the uid that owns the AppWidget provider.
Jim Millera75a8832013-02-07 16:53:32 -0800367 *
Adam Cohen311c79c2012-05-10 14:44:38 -0700368 * <p>
369 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
Michael Jurkaf25ab442012-06-25 15:11:21 -0700370 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700371 *
372 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
373 * @param views The RemoteViews object to show.
374 */
375 public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
376 try {
Jim Millera75a8832013-02-07 16:53:32 -0800377 sService.updateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700378 }
379 catch (RemoteException e) {
380 throw new RuntimeException("system server dead?", e);
381 }
382 }
383
384 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700385 * Update the extras for a given widget instance.
386 *
387 * The extras can be used to embed additional information about this widget to be accessed
388 * by the associated widget's AppWidgetProvider.
389 *
Adam Cohend2097eb2012-05-01 18:10:28 -0700390 * @see #getAppWidgetOptions(int)
Adam Cohene8724c82012-04-19 17:11:40 -0700391 *
392 * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
Adam Cohend2097eb2012-05-01 18:10:28 -0700393 * @param options The options to associate with this widget
Adam Cohene8724c82012-04-19 17:11:40 -0700394 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700395 public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
Adam Cohene8724c82012-04-19 17:11:40 -0700396 try {
Jim Millera75a8832013-02-07 16:53:32 -0800397 sService.updateAppWidgetOptions(appWidgetId, options, mContext.getUserId());
Adam Cohene8724c82012-04-19 17:11:40 -0700398 }
399 catch (RemoteException e) {
400 throw new RuntimeException("system server dead?", e);
401 }
402 }
403
404 /**
405 * Get the extras associated with a given widget instance.
406 *
407 * The extras can be used to embed additional information about this widget to be accessed
408 * by the associated widget's AppWidgetProvider.
409 *
Adam Cohend2097eb2012-05-01 18:10:28 -0700410 * @see #updateAppWidgetOptions(int, Bundle)
Adam Cohene8724c82012-04-19 17:11:40 -0700411 *
412 * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
Adam Cohend2097eb2012-05-01 18:10:28 -0700413 * @return The options associated with the given widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700414 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700415 public Bundle getAppWidgetOptions(int appWidgetId) {
Adam Cohene8724c82012-04-19 17:11:40 -0700416 try {
Jim Millera75a8832013-02-07 16:53:32 -0800417 return sService.getAppWidgetOptions(appWidgetId, mContext.getUserId());
Adam Cohene8724c82012-04-19 17:11:40 -0700418 }
419 catch (RemoteException e) {
420 throw new RuntimeException("system server dead?", e);
421 }
422 }
423
424 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700425 * Set the RemoteViews to use for the specified appWidgetId.
426 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700427 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
428 * contain a complete representation of the widget. For performing partial widget updates, see
429 * {@link #partiallyUpdateAppWidget(int, RemoteViews)}.
430 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700431 * <p>
432 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
433 * and outside of the handler.
434 * This method will only work when called from the uid that owns the AppWidget provider.
435 *
Adam Cohen311c79c2012-05-10 14:44:38 -0700436 * <p>
437 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
Michael Jurkaf25ab442012-06-25 15:11:21 -0700438 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes.
Adam Cohen311c79c2012-05-10 14:44:38 -0700439 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700440 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
441 * @param views The RemoteViews object to show.
442 */
443 public void updateAppWidget(int appWidgetId, RemoteViews views) {
444 updateAppWidget(new int[] { appWidgetId }, views);
445 }
446
447 /**
Adam Cohen2dd21972010-08-15 18:20:04 -0700448 * Perform an incremental update or command on the widget(s) specified by appWidgetIds.
449 *
450 * This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
Jim Millera75a8832013-02-07 16:53:32 -0800451 * RemoteViews object which is passed is understood to be an incomplete representation of the
Adam Cohenfbe44b72012-09-19 20:36:23 -0700452 * widget, and hence does not replace the cached representation of the widget. As of API
453 * level 17, the new properties set within the views objects will be appended to the cached
454 * representation of the widget, and hence will persist.
Adam Cohen2dd21972010-08-15 18:20:04 -0700455 *
456 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
457 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
458 *
459 * <p>
460 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
461 * and outside of the handler.
462 * This method will only work when called from the uid that owns the AppWidget provider.
463 *
Winson Chung66119882012-10-11 14:26:25 -0700464 * <p>
465 * This method will be ignored if a widget has not received a full update via
466 * {@link #updateAppWidget(int[], RemoteViews)}.
467 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700468 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
469 * @param views The RemoteViews object containing the incremental update / command.
470 */
471 public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) {
472 try {
Jim Millera75a8832013-02-07 16:53:32 -0800473 sService.partiallyUpdateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
Adam Cohen2dd21972010-08-15 18:20:04 -0700474 } catch (RemoteException e) {
475 throw new RuntimeException("system server dead?", e);
476 }
477 }
478
479 /**
480 * Perform an incremental update or command on the widget specified by appWidgetId.
481 *
482 * This update differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews
483 * object which is passed is understood to be an incomplete representation of the widget, and
484 * hence is not cached by the AppWidgetService. Note that because these updates are not cached,
485 * any state that they modify that is not restored by restoreInstanceState will not persist in
486 * the case that the widgets are restored using the cached version in AppWidgetService.
487 *
488 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
489 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
490 *
491 * <p>
492 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
493 * and outside of the handler.
494 * This method will only work when called from the uid that owns the AppWidget provider.
495 *
Winson Chung66119882012-10-11 14:26:25 -0700496 * <p>
497 * This method will be ignored if a widget has not received a full update via
498 * {@link #updateAppWidget(int[], RemoteViews)}.
499 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700500 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
501 * @param views The RemoteViews object containing the incremental update / command.
502 */
503 public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) {
504 partiallyUpdateAppWidget(new int[] { appWidgetId }, views);
505 }
506
507 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700508 * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider.
509 *
510 * <p>
511 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
512 * and outside of the handler.
513 * This method will only work when called from the uid that owns the AppWidget provider.
514 *
515 * @param provider The {@link ComponentName} for the {@link
516 * android.content.BroadcastReceiver BroadcastReceiver} provider
517 * for your AppWidget.
518 * @param views The RemoteViews object to show.
519 */
520 public void updateAppWidget(ComponentName provider, RemoteViews views) {
521 try {
Jim Millera75a8832013-02-07 16:53:32 -0800522 sService.updateAppWidgetProvider(provider, views, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700523 }
524 catch (RemoteException e) {
525 throw new RuntimeException("system server dead?", e);
526 }
527 }
528
529 /**
Winson Chung499cb9f2010-07-16 11:18:17 -0700530 * Notifies the specified collection view in all the specified AppWidget instances
John Spurlock77624cd2013-06-03 09:47:01 -0400531 * to invalidate their data.
Winson Chung499cb9f2010-07-16 11:18:17 -0700532 *
John Spurlock77624cd2013-06-03 09:47:01 -0400533 * @param appWidgetIds The AppWidget instances to notify of view data changes.
Winson Chung499cb9f2010-07-16 11:18:17 -0700534 * @param viewId The collection view id.
535 */
Winson Chung6394c0e2010-08-16 10:14:56 -0700536 public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
Winson Chung499cb9f2010-07-16 11:18:17 -0700537 try {
Jim Millera75a8832013-02-07 16:53:32 -0800538 sService.notifyAppWidgetViewDataChanged(appWidgetIds, viewId, mContext.getUserId());
Winson Chung499cb9f2010-07-16 11:18:17 -0700539 }
540 catch (RemoteException e) {
541 throw new RuntimeException("system server dead?", e);
542 }
543 }
544
545 /**
John Spurlock77624cd2013-06-03 09:47:01 -0400546 * Notifies the specified collection view in the specified AppWidget instance
547 * to invalidate its data.
Winson Chung499cb9f2010-07-16 11:18:17 -0700548 *
John Spurlock77624cd2013-06-03 09:47:01 -0400549 * @param appWidgetId The AppWidget instance to notify of view data changes.
550 * @param viewId The collection view id.
Winson Chung499cb9f2010-07-16 11:18:17 -0700551 */
Winson Chung6394c0e2010-08-16 10:14:56 -0700552 public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
553 notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
Winson Chung499cb9f2010-07-16 11:18:17 -0700554 }
555
556 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700557 * Return a list of the AppWidget providers that are currently installed.
558 */
559 public List<AppWidgetProviderInfo> getInstalledProviders() {
Adam Cohend9e5af32012-11-28 16:34:57 -0800560 return getInstalledProviders(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
561 }
562
563 /**
564 * Return a list of the AppWidget providers that are currently installed.
565 *
566 * @param categoryFilter Will only return providers which register as any of the specified
567 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
568 * @hide
569 */
570 public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700571 try {
Jim Millera75a8832013-02-07 16:53:32 -0800572 List<AppWidgetProviderInfo> providers = sService.getInstalledProviders(categoryFilter,
573 mContext.getUserId());
Patrick Dubroy5d140912010-07-12 10:25:27 -0700574 for (AppWidgetProviderInfo info : providers) {
575 // Converting complex to dp.
576 info.minWidth =
577 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
578 info.minHeight =
579 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
Adam Cohen324afba2011-07-22 11:51:45 -0700580 info.minResizeWidth =
581 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
582 info.minResizeHeight =
583 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
Patrick Dubroy5d140912010-07-12 10:25:27 -0700584 }
585 return providers;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700586 }
587 catch (RemoteException e) {
588 throw new RuntimeException("system server dead?", e);
589 }
590 }
591
592 /**
593 * Get the available info about the AppWidget.
594 *
595 * @return A appWidgetId. If the appWidgetId has not been bound to a provider yet, or
596 * you don't have access to that appWidgetId, null is returned.
597 */
598 public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
599 try {
Jim Millera75a8832013-02-07 16:53:32 -0800600 AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId,
601 mContext.getUserId());
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700602 if (info != null) {
603 // Converting complex to dp.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200604 info.minWidth =
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700605 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
606 info.minHeight =
607 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
Adam Cohen324afba2011-07-22 11:51:45 -0700608 info.minResizeWidth =
609 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
610 info.minResizeHeight =
611 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700612 }
613 return info;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700614 }
615 catch (RemoteException e) {
616 throw new RuntimeException("system server dead?", e);
617 }
618 }
619
620 /**
621 * Set the component for a given appWidgetId.
622 *
Michael Jurka61a5b012012-04-13 10:39:45 -0700623 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
624 * widgets always for your component. This method is used by the AppWidget picker and
625 * should not be used by other apps.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700626 *
627 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
628 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
629 * provider for this AppWidget.
Michael Jurka61a5b012012-04-13 10:39:45 -0700630 * @hide
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700631 */
632 public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
633 try {
Jim Millera75a8832013-02-07 16:53:32 -0800634 sService.bindAppWidgetId(appWidgetId, provider, null, mContext.getUserId());
Adam Cohen0aa2d422012-09-07 17:37:26 -0700635 }
636 catch (RemoteException e) {
637 throw new RuntimeException("system server dead?", e);
638 }
639 }
640
641 /**
642 * Set the component for a given appWidgetId.
643 *
644 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
645 * widgets always for your component. This method is used by the AppWidget picker and
646 * should not be used by other apps.
647 *
648 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
649 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
650 * provider for this AppWidget.
651 * @param options Bundle containing options for the AppWidget. See also
652 * {@link #updateAppWidgetOptions(int, Bundle)}
653 *
654 * @hide
655 */
656 public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
657 try {
Jim Millera75a8832013-02-07 16:53:32 -0800658 sService.bindAppWidgetId(appWidgetId, provider, options, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700659 }
660 catch (RemoteException e) {
661 throw new RuntimeException("system server dead?", e);
662 }
663 }
664
665 /**
Michael Jurka61a5b012012-04-13 10:39:45 -0700666 * Set the component for a given appWidgetId.
667 *
668 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
669 * widgets always for your component. Should be used by apps that host widgets; if this
670 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
671 * bind
672 *
673 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
674 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
675 * provider for this AppWidget.
676 * @return true if this component has permission to bind the AppWidget
677 */
678 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
679 if (mContext == null) {
680 return false;
681 }
682 try {
683 return sService.bindAppWidgetIdIfAllowed(
Jim Millera75a8832013-02-07 16:53:32 -0800684 mContext.getPackageName(), appWidgetId, provider, null, mContext.getUserId());
Adam Cohen0aa2d422012-09-07 17:37:26 -0700685 }
686 catch (RemoteException e) {
687 throw new RuntimeException("system server dead?", e);
688 }
689 }
690
691 /**
692 * Set the component for a given appWidgetId.
693 *
694 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
695 * widgets always for your component. Should be used by apps that host widgets; if this
696 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
697 * bind
698 *
699 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
700 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
701 * provider for this AppWidget.
702 * @param options Bundle containing options for the AppWidget. See also
703 * {@link #updateAppWidgetOptions(int, Bundle)}
704 *
705 * @return true if this component has permission to bind the AppWidget
706 */
707 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
708 Bundle options) {
709 if (mContext == null) {
710 return false;
711 }
712 try {
Jim Millera75a8832013-02-07 16:53:32 -0800713 return sService.bindAppWidgetIdIfAllowed(mContext.getPackageName(), appWidgetId,
714 provider, options, mContext.getUserId());
Michael Jurka61a5b012012-04-13 10:39:45 -0700715 }
716 catch (RemoteException e) {
717 throw new RuntimeException("system server dead?", e);
718 }
719 }
720
721 /**
722 * Query if a given package was granted permission by the user to bind app widgets
723 *
724 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
725 *
726 * @param packageName The package for which the permission is being queried
727 * @return true if the package was granted permission by the user to bind app widgets
728 * @hide
729 */
730 public boolean hasBindAppWidgetPermission(String packageName) {
731 try {
Jim Millera75a8832013-02-07 16:53:32 -0800732 return sService.hasBindAppWidgetPermission(packageName, mContext.getUserId());
Michael Jurka61a5b012012-04-13 10:39:45 -0700733 }
734 catch (RemoteException e) {
735 throw new RuntimeException("system server dead?", e);
736 }
737 }
738
739 /**
740 * Changes any user-granted permission for the given package to bind app widgets
741 *
742 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
743 *
744 * @param provider The package whose permission is being changed
745 * @param permission Whether to give the package permission to bind widgets
746 * @hide
747 */
748 public void setBindAppWidgetPermission(String packageName, boolean permission) {
749 try {
Jim Millera75a8832013-02-07 16:53:32 -0800750 sService.setBindAppWidgetPermission(packageName, permission, mContext.getUserId());
Michael Jurka61a5b012012-04-13 10:39:45 -0700751 }
752 catch (RemoteException e) {
753 throw new RuntimeException("system server dead?", e);
754 }
755 }
756
757 /**
Winson Chung81f39eb2011-01-11 18:05:01 -0800758 * Binds the RemoteViewsService for a given appWidgetId and intent.
759 *
760 * The appWidgetId specified must already be bound to the calling AppWidgetHost via
761 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
762 *
763 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
764 * @param intent The intent of the service which will be providing the data to the
765 * RemoteViewsAdapter.
766 * @param connection The callback interface to be notified when a connection is made or lost.
Amith Yamasanic566b432012-11-30 15:26:21 -0800767 * @param userHandle The user to bind to.
Winson Chung81f39eb2011-01-11 18:05:01 -0800768 * @hide
769 */
Amith Yamasanic566b432012-11-30 15:26:21 -0800770 public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection,
771 UserHandle userHandle) {
Winson Chung81f39eb2011-01-11 18:05:01 -0800772 try {
Amith Yamasanic566b432012-11-30 15:26:21 -0800773 sService.bindRemoteViewsService(appWidgetId, intent, connection,
774 userHandle.getIdentifier());
Winson Chung81f39eb2011-01-11 18:05:01 -0800775 }
776 catch (RemoteException e) {
777 throw new RuntimeException("system server dead?", e);
778 }
779 }
780
781 /**
782 * Unbinds the RemoteViewsService for a given appWidgetId and intent.
783 *
784 * The appWidgetId specified muse already be bound to the calling AppWidgetHost via
785 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
786 *
787 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
788 * @param intent The intent of the service which will be providing the data to the
789 * RemoteViewsAdapter.
Amith Yamasanic566b432012-11-30 15:26:21 -0800790 * @param userHandle The user to unbind from.
Winson Chung81f39eb2011-01-11 18:05:01 -0800791 * @hide
792 */
Amith Yamasanic566b432012-11-30 15:26:21 -0800793 public void unbindRemoteViewsService(int appWidgetId, Intent intent, UserHandle userHandle) {
Winson Chung81f39eb2011-01-11 18:05:01 -0800794 try {
Amith Yamasanic566b432012-11-30 15:26:21 -0800795 sService.unbindRemoteViewsService(appWidgetId, intent, userHandle.getIdentifier());
Winson Chung81f39eb2011-01-11 18:05:01 -0800796 }
797 catch (RemoteException e) {
798 throw new RuntimeException("system server dead?", e);
799 }
800 }
801
802 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700803 * Get the list of appWidgetIds that have been bound to the given AppWidget
804 * provider.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200805 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700806 * @param provider The {@link android.content.BroadcastReceiver} that is the
807 * AppWidget provider to find appWidgetIds for.
808 */
809 public int[] getAppWidgetIds(ComponentName provider) {
810 try {
Jim Millera75a8832013-02-07 16:53:32 -0800811 return sService.getAppWidgetIds(provider, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700812 }
813 catch (RemoteException e) {
814 throw new RuntimeException("system server dead?", e);
815 }
816 }
817}
818