blob: d1c7becd8dfb594028c8f698064d629ffc25d141 [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
Jim Millera75a8832013-02-07 16:53:32 -080019import android.app.ActivityManagerNative;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070020import android.content.ComponentName;
21import android.content.Context;
Winson Chung81f39eb2011-01-11 18:05:01 -080022import android.content.Intent;
Adam Cohene8724c82012-04-19 17:11:40 -070023import android.os.Bundle;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070024import android.os.IBinder;
25import android.os.RemoteException;
26import android.os.ServiceManager;
Amith Yamasanic566b432012-11-30 15:26:21 -080027import android.os.UserHandle;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -070028import android.util.DisplayMetrics;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -070029import android.util.TypedValue;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070030import android.widget.RemoteViews;
31
32import com.android.internal.appwidget.IAppWidgetService;
33
34import java.lang.ref.WeakReference;
35import java.util.List;
36import java.util.WeakHashMap;
37
38/**
39 * Updates AppWidget state; gets information about installed AppWidget providers and other
40 * AppWidget related state.
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080041 *
42 * <div class="special reference">
43 * <h3>Developer Guides</h3>
44 * <p>For more information about creating app widgets, read the
45 * <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a> developer guide.</p>
46 * </div>
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070047 */
48public class AppWidgetManager {
49 static final String TAG = "AppWidgetManager";
50
51 /**
Dianne Hackborna40cfeb2013-03-25 17:49:36 -070052 * Activity action to launch from your {@link AppWidgetHost} activity when you want to
53 * pick an AppWidget to display. The AppWidget picker activity will be launched.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -070054 * <p>
55 * You must supply the following extras:
56 * <table>
57 * <tr>
58 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
59 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
60 * once the user has selected one.</td>
61 * </tr>
62 * </table>
63 *
64 * <p>
65 * The system will respond with an onActivityResult call with the following extras in
66 * the intent:
67 * <table>
68 * <tr>
69 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
70 * <td>The appWidgetId that you supplied in the original intent.</td>
71 * </tr>
72 * </table>
73 * <p>
74 * When you receive the result from the AppWidget pick activity, if the resultCode is
75 * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected. You should then
76 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its configuration
77 * activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete
78 * the appWidgetId.
79 *
80 * @see #ACTION_APPWIDGET_CONFIGURE
81 */
82 public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
83
84 /**
Michael Jurkafc753c02012-10-30 18:30:52 -070085 * Similar to ACTION_APPWIDGET_PICK, but used from keyguard
86 * @hide
87 */
88 public static final String
89 ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK";
90
91 /**
Dianne Hackborna40cfeb2013-03-25 17:49:36 -070092 * Activity action to launch from your {@link AppWidgetHost} activity when you want to bind
93 * an AppWidget to display and bindAppWidgetIdIfAllowed returns false.
Michael Jurka61a5b012012-04-13 10:39:45 -070094 * <p>
95 * You must supply the following extras:
96 * <table>
97 * <tr>
98 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
99 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
100 * you provide.</td>
101 * </tr>
102 * <tr>
103 * <td>{@link #EXTRA_APPWIDGET_PROVIDER}</td>
104 * <td>The BroadcastReceiver that will be the AppWidget provider for this AppWidget.
105 * </td>
106 * </tr>
107 * </table>
108 *
109 * <p>
110 * The system will respond with an onActivityResult call with the following extras in
111 * the intent:
112 * <table>
113 * <tr>
114 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
115 * <td>The appWidgetId that you supplied in the original intent.</td>
116 * </tr>
117 * </table>
118 * <p>
119 * When you receive the result from the AppWidget bind activity, if the resultCode is
120 * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound. You should then
121 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its
122 * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you
123 * should delete
124 * the appWidgetId.
125 *
126 * @see #ACTION_APPWIDGET_CONFIGURE
127 *
128 */
129 public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND";
130
131 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700132 * Sent when it is time to configure your AppWidget while it is being added to a host.
133 * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity
134 * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo meta-data}.
135 *
136 * <p>
137 * The intent will contain the following extras:
138 * <table>
139 * <tr>
140 * <td>{@link #EXTRA_APPWIDGET_ID}</td>
141 * <td>The appWidgetId to configure.</td>
142 * </tr>
143 * </table>
144 *
145 * <p>If you return {@link android.app.Activity#RESULT_OK} using
146 * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added,
147 * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget.
148 * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
149 * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} broadcast.
150 */
151 public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
152
153 /**
154 * An intent extra that contains one appWidgetId.
155 * <p>
156 * The value will be an int that can be retrieved like this:
157 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID}
158 */
159 public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
160
161 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700162 * 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 -0700163 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700164 public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth";
Adam Cohene8724c82012-04-19 17:11:40 -0700165
166 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700167 * 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 -0700168 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700169 public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight";
Adam Cohene8724c82012-04-19 17:11:40 -0700170
171 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700172 * 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 -0700173 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700174 public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth";
Adam Cohene8724c82012-04-19 17:11:40 -0700175
176 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700177 * 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 -0700178 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700179 public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight";
Adam Cohene8724c82012-04-19 17:11:40 -0700180
181 /**
Adam Cohen0aa2d422012-09-07 17:37:26 -0700182 * A bundle extra that hints to the AppWidgetProvider the category of host that owns this
183 * this widget. Can have the value {@link
184 * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link
185 * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}.
186 */
187 public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory";
188
189 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700190 * An intent extra which points to a bundle of extra information for a particular widget id.
191 * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT.
192 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700193 public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions";
Adam Cohene8724c82012-04-19 17:11:40 -0700194
195 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700196 * An intent extra that contains multiple appWidgetIds.
197 * <p>
198 * The value will be an int array that can be retrieved like this:
199 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
200 */
201 public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
202
203 /**
Michael Jurka61a5b012012-04-13 10:39:45 -0700204 * An intent extra that contains the component name of a AppWidget provider.
205 * <p>
206 * The value will be an ComponentName.
207 */
208 public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider";
209
210 /**
The Android Open Source Project10592532009-03-18 17:39:46 -0700211 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
212 * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are
213 * installed. (This is how the launcher shows the search widget).
214 */
215 public static final String EXTRA_CUSTOM_INFO = "customInfo";
216
217 /**
218 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of
219 * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are
220 * installed. It will be added to the extras object on the {@link android.content.Intent}
221 * that is returned from the picker activity.
222 *
223 * {@more}
224 */
225 public static final String EXTRA_CUSTOM_EXTRAS = "customExtras";
226
227 /**
Adam Cohen8c09f632012-09-11 18:23:35 -0700228 * An intent extra to pass to the AppWidget picker which allows the picker to filter
229 * the list based on the {@link AppWidgetProviderInfo#widgetCategory}.
Jim Millerf229e4d2012-09-12 20:32:50 -0700230 *
231 * @hide
Adam Cohen8c09f632012-09-11 18:23:35 -0700232 */
Adam Cohen8c09f632012-09-11 18:23:35 -0700233 public static final String EXTRA_CATEGORY_FILTER = "categoryFilter";
234
235 /**
Jim Millerf229e4d2012-09-12 20:32:50 -0700236 * An intent extra to pass to the AppWidget picker to specify whether or not to sort
237 * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets
238 * @hide
239 */
240 public static final String EXTRA_CUSTOM_SORT = "customSort";
241
242 /**
Scott Main6aad9952013-01-07 18:51:49 -0800243 * A sentinel value that the AppWidget manager will never return as a appWidgetId.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700244 */
245 public static final int INVALID_APPWIDGET_ID = 0;
246
247 /**
248 * Sent when it is time to update your AppWidget.
249 *
250 * <p>This may be sent in response to a new instance for this AppWidget provider having
251 * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval}
252 * having lapsed, or the system booting.
253 *
254 * <p>
255 * The intent will contain the following extras:
256 * <table>
257 * <tr>
258 * <td>{@link #EXTRA_APPWIDGET_IDS}</td>
259 * <td>The appWidgetIds to update. This may be all of the AppWidgets created for this
260 * provider, or just a subset. The system tries to send updates for as few AppWidget
261 * instances as possible.</td>
262 * </tr>
263 * </table>
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200264 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700265 * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
266 */
267 public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
268
269 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700270 * Sent when the custom extras for an AppWidget change.
271 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700272 * <p class="note">This is a protected intent that can only be sent
273 * by the system.
274 *
Jim Millera75a8832013-02-07 16:53:32 -0800275 * @see AppWidgetProvider#onAppWidgetOptionsChanged
276 * AppWidgetProvider.onAppWidgetOptionsChanged(Context context,
Katie McCormick0e9f34b2012-09-10 15:32:46 -0700277 * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras)
Adam Cohene8724c82012-04-19 17:11:40 -0700278 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700279 public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS";
Adam Cohene8724c82012-04-19 17:11:40 -0700280
281 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700282 * Sent when an instance of an AppWidget is deleted from its host.
283 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700284 * <p class="note">This is a protected intent that can only be sent
285 * by the system.
286 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700287 * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
288 */
289 public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
290
291 /**
292 * Sent when an instance of an AppWidget is removed from the last host.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200293 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700294 * <p class="note">This is a protected intent that can only be sent
295 * by the system.
296 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700297 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
298 */
299 public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
300
301 /**
302 * Sent when an instance of an AppWidget is added to a host for the first time.
303 * This broadcast is sent at boot time if there is a AppWidgetHost installed with
304 * an instance for this provider.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200305 *
Dianne Hackborna40cfeb2013-03-25 17:49:36 -0700306 * <p class="note">This is a protected intent that can only be sent
307 * by the system.
308 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700309 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
310 */
311 public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
312
313 /**
314 * Field for the manifest meta-data tag.
315 *
316 * @see AppWidgetProviderInfo
317 */
318 public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200319
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200320 static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache =
321 new WeakHashMap<Context, WeakReference<AppWidgetManager>>();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700322 static IAppWidgetService sService;
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200323
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700324 Context mContext;
325
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700326 private DisplayMetrics mDisplayMetrics;
327
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700328 /**
329 * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
330 * Context} object.
331 */
332 public static AppWidgetManager getInstance(Context context) {
333 synchronized (sManagerCache) {
334 if (sService == null) {
335 IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
336 sService = IAppWidgetService.Stub.asInterface(b);
337 }
338
339 WeakReference<AppWidgetManager> ref = sManagerCache.get(context);
340 AppWidgetManager result = null;
341 if (ref != null) {
342 result = ref.get();
343 }
344 if (result == null) {
345 result = new AppWidgetManager(context);
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200346 sManagerCache.put(context, new WeakReference<AppWidgetManager>(result));
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700347 }
348 return result;
349 }
350 }
351
352 private AppWidgetManager(Context context) {
353 mContext = context;
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700354 mDisplayMetrics = context.getResources().getDisplayMetrics();
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700355 }
356
357 /**
358 * Set the RemoteViews to use for the specified appWidgetIds.
359 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700360 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
361 * contain a complete representation of the widget. For performing partial widget updates, see
362 * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}.
363 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700364 * <p>
365 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
366 * and outside of the handler.
367 * This method will only work when called from the uid that owns the AppWidget provider.
Jim Millera75a8832013-02-07 16:53:32 -0800368 *
Adam Cohen311c79c2012-05-10 14:44:38 -0700369 * <p>
370 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
Michael Jurkaf25ab442012-06-25 15:11:21 -0700371 * 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 -0700372 *
373 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
374 * @param views The RemoteViews object to show.
375 */
376 public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
377 try {
Jim Millera75a8832013-02-07 16:53:32 -0800378 sService.updateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700379 }
380 catch (RemoteException e) {
381 throw new RuntimeException("system server dead?", e);
382 }
383 }
384
385 /**
Adam Cohene8724c82012-04-19 17:11:40 -0700386 * Update the extras for a given widget instance.
387 *
388 * The extras can be used to embed additional information about this widget to be accessed
389 * by the associated widget's AppWidgetProvider.
390 *
Adam Cohend2097eb2012-05-01 18:10:28 -0700391 * @see #getAppWidgetOptions(int)
Adam Cohene8724c82012-04-19 17:11:40 -0700392 *
393 * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
Adam Cohend2097eb2012-05-01 18:10:28 -0700394 * @param options The options to associate with this widget
Adam Cohene8724c82012-04-19 17:11:40 -0700395 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700396 public void updateAppWidgetOptions(int appWidgetId, Bundle options) {
Adam Cohene8724c82012-04-19 17:11:40 -0700397 try {
Jim Millera75a8832013-02-07 16:53:32 -0800398 sService.updateAppWidgetOptions(appWidgetId, options, mContext.getUserId());
Adam Cohene8724c82012-04-19 17:11:40 -0700399 }
400 catch (RemoteException e) {
401 throw new RuntimeException("system server dead?", e);
402 }
403 }
404
405 /**
406 * Get the extras associated with a given widget instance.
407 *
408 * The extras can be used to embed additional information about this widget to be accessed
409 * by the associated widget's AppWidgetProvider.
410 *
Adam Cohend2097eb2012-05-01 18:10:28 -0700411 * @see #updateAppWidgetOptions(int, Bundle)
Adam Cohene8724c82012-04-19 17:11:40 -0700412 *
413 * @param appWidgetId The AppWidget instances for which to set the RemoteViews.
Adam Cohend2097eb2012-05-01 18:10:28 -0700414 * @return The options associated with the given widget instance.
Adam Cohene8724c82012-04-19 17:11:40 -0700415 */
Adam Cohend2097eb2012-05-01 18:10:28 -0700416 public Bundle getAppWidgetOptions(int appWidgetId) {
Adam Cohene8724c82012-04-19 17:11:40 -0700417 try {
Jim Millera75a8832013-02-07 16:53:32 -0800418 return sService.getAppWidgetOptions(appWidgetId, mContext.getUserId());
Adam Cohene8724c82012-04-19 17:11:40 -0700419 }
420 catch (RemoteException e) {
421 throw new RuntimeException("system server dead?", e);
422 }
423 }
424
425 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700426 * Set the RemoteViews to use for the specified appWidgetId.
427 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700428 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should
429 * contain a complete representation of the widget. For performing partial widget updates, see
430 * {@link #partiallyUpdateAppWidget(int, RemoteViews)}.
431 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700432 * <p>
433 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
434 * and outside of the handler.
435 * This method will only work when called from the uid that owns the AppWidget provider.
436 *
Adam Cohen311c79c2012-05-10 14:44:38 -0700437 * <p>
438 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to
Michael Jurkaf25ab442012-06-25 15:11:21 -0700439 * 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 -0700440 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700441 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
442 * @param views The RemoteViews object to show.
443 */
444 public void updateAppWidget(int appWidgetId, RemoteViews views) {
445 updateAppWidget(new int[] { appWidgetId }, views);
446 }
447
448 /**
Adam Cohen2dd21972010-08-15 18:20:04 -0700449 * Perform an incremental update or command on the widget(s) specified by appWidgetIds.
450 *
451 * This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the
Jim Millera75a8832013-02-07 16:53:32 -0800452 * RemoteViews object which is passed is understood to be an incomplete representation of the
Adam Cohenfbe44b72012-09-19 20:36:23 -0700453 * widget, and hence does not replace the cached representation of the widget. As of API
454 * level 17, the new properties set within the views objects will be appended to the cached
455 * representation of the widget, and hence will persist.
Adam Cohen2dd21972010-08-15 18:20:04 -0700456 *
457 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
458 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
459 *
460 * <p>
461 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
462 * and outside of the handler.
463 * This method will only work when called from the uid that owns the AppWidget provider.
464 *
Winson Chung66119882012-10-11 14:26:25 -0700465 * <p>
466 * This method will be ignored if a widget has not received a full update via
467 * {@link #updateAppWidget(int[], RemoteViews)}.
468 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700469 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews.
470 * @param views The RemoteViews object containing the incremental update / command.
471 */
472 public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) {
473 try {
Jim Millera75a8832013-02-07 16:53:32 -0800474 sService.partiallyUpdateAppWidgetIds(appWidgetIds, views, mContext.getUserId());
Adam Cohen2dd21972010-08-15 18:20:04 -0700475 } catch (RemoteException e) {
476 throw new RuntimeException("system server dead?", e);
477 }
478 }
479
480 /**
481 * Perform an incremental update or command on the widget specified by appWidgetId.
482 *
483 * This update differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews
484 * object which is passed is understood to be an incomplete representation of the widget, and
485 * hence is not cached by the AppWidgetService. Note that because these updates are not cached,
486 * any state that they modify that is not restored by restoreInstanceState will not persist in
487 * the case that the widgets are restored using the cached version in AppWidgetService.
488 *
489 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)},
490 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands.
491 *
492 * <p>
493 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
494 * and outside of the handler.
495 * This method will only work when called from the uid that owns the AppWidget provider.
496 *
Winson Chung66119882012-10-11 14:26:25 -0700497 * <p>
498 * This method will be ignored if a widget has not received a full update via
499 * {@link #updateAppWidget(int[], RemoteViews)}.
500 *
Adam Cohen2dd21972010-08-15 18:20:04 -0700501 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
502 * @param views The RemoteViews object containing the incremental update / command.
503 */
504 public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) {
505 partiallyUpdateAppWidget(new int[] { appWidgetId }, views);
506 }
507
508 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700509 * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider.
510 *
511 * <p>
512 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
513 * and outside of the handler.
514 * This method will only work when called from the uid that owns the AppWidget provider.
515 *
516 * @param provider The {@link ComponentName} for the {@link
517 * android.content.BroadcastReceiver BroadcastReceiver} provider
518 * for your AppWidget.
519 * @param views The RemoteViews object to show.
520 */
521 public void updateAppWidget(ComponentName provider, RemoteViews views) {
522 try {
Jim Millera75a8832013-02-07 16:53:32 -0800523 sService.updateAppWidgetProvider(provider, views, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700524 }
525 catch (RemoteException e) {
526 throw new RuntimeException("system server dead?", e);
527 }
528 }
529
530 /**
Winson Chung499cb9f2010-07-16 11:18:17 -0700531 * Notifies the specified collection view in all the specified AppWidget instances
John Spurlock77624cd2013-06-03 09:47:01 -0400532 * to invalidate their data.
Winson Chung499cb9f2010-07-16 11:18:17 -0700533 *
John Spurlock77624cd2013-06-03 09:47:01 -0400534 * @param appWidgetIds The AppWidget instances to notify of view data changes.
Winson Chung499cb9f2010-07-16 11:18:17 -0700535 * @param viewId The collection view id.
536 */
Winson Chung6394c0e2010-08-16 10:14:56 -0700537 public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) {
Winson Chung499cb9f2010-07-16 11:18:17 -0700538 try {
Jim Millera75a8832013-02-07 16:53:32 -0800539 sService.notifyAppWidgetViewDataChanged(appWidgetIds, viewId, mContext.getUserId());
Winson Chung499cb9f2010-07-16 11:18:17 -0700540 }
541 catch (RemoteException e) {
542 throw new RuntimeException("system server dead?", e);
543 }
544 }
545
546 /**
John Spurlock77624cd2013-06-03 09:47:01 -0400547 * Notifies the specified collection view in the specified AppWidget instance
548 * to invalidate its data.
Winson Chung499cb9f2010-07-16 11:18:17 -0700549 *
John Spurlock77624cd2013-06-03 09:47:01 -0400550 * @param appWidgetId The AppWidget instance to notify of view data changes.
551 * @param viewId The collection view id.
Winson Chung499cb9f2010-07-16 11:18:17 -0700552 */
Winson Chung6394c0e2010-08-16 10:14:56 -0700553 public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) {
554 notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId);
Winson Chung499cb9f2010-07-16 11:18:17 -0700555 }
556
557 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700558 * Return a list of the AppWidget providers that are currently installed.
559 */
560 public List<AppWidgetProviderInfo> getInstalledProviders() {
Adam Cohend9e5af32012-11-28 16:34:57 -0800561 return getInstalledProviders(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN);
562 }
563
564 /**
565 * Return a list of the AppWidget providers that are currently installed.
566 *
567 * @param categoryFilter Will only return providers which register as any of the specified
568 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}.
569 * @hide
570 */
571 public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) {
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700572 try {
Jim Millera75a8832013-02-07 16:53:32 -0800573 List<AppWidgetProviderInfo> providers = sService.getInstalledProviders(categoryFilter,
574 mContext.getUserId());
Patrick Dubroy5d140912010-07-12 10:25:27 -0700575 for (AppWidgetProviderInfo info : providers) {
576 // Converting complex to dp.
577 info.minWidth =
578 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
579 info.minHeight =
580 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
Adam Cohen324afba2011-07-22 11:51:45 -0700581 info.minResizeWidth =
582 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
583 info.minResizeHeight =
584 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
Patrick Dubroy5d140912010-07-12 10:25:27 -0700585 }
586 return providers;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700587 }
588 catch (RemoteException e) {
589 throw new RuntimeException("system server dead?", e);
590 }
591 }
592
593 /**
594 * Get the available info about the AppWidget.
595 *
596 * @return A appWidgetId. If the appWidgetId has not been bound to a provider yet, or
597 * you don't have access to that appWidgetId, null is returned.
598 */
599 public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
600 try {
Jim Millera75a8832013-02-07 16:53:32 -0800601 AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId,
602 mContext.getUserId());
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700603 if (info != null) {
604 // Converting complex to dp.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200605 info.minWidth =
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700606 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics);
607 info.minHeight =
608 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics);
Adam Cohen324afba2011-07-22 11:51:45 -0700609 info.minResizeWidth =
610 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics);
611 info.minResizeHeight =
612 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics);
Mitsuru Oshima8f25c422009-07-01 00:10:43 -0700613 }
614 return info;
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700615 }
616 catch (RemoteException e) {
617 throw new RuntimeException("system server dead?", e);
618 }
619 }
620
621 /**
622 * Set the component for a given appWidgetId.
623 *
Michael Jurka61a5b012012-04-13 10:39:45 -0700624 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
625 * widgets always for your component. This method is used by the AppWidget picker and
626 * should not be used by other apps.
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700627 *
628 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
629 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
630 * provider for this AppWidget.
Michael Jurka61a5b012012-04-13 10:39:45 -0700631 * @hide
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700632 */
633 public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
634 try {
Jim Millera75a8832013-02-07 16:53:32 -0800635 sService.bindAppWidgetId(appWidgetId, provider, null, mContext.getUserId());
Adam Cohen0aa2d422012-09-07 17:37:26 -0700636 }
637 catch (RemoteException e) {
638 throw new RuntimeException("system server dead?", e);
639 }
640 }
641
642 /**
643 * Set the component for a given appWidgetId.
644 *
645 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
646 * widgets always for your component. This method is used by the AppWidget picker and
647 * should not be used by other apps.
648 *
649 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
650 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
651 * provider for this AppWidget.
652 * @param options Bundle containing options for the AppWidget. See also
653 * {@link #updateAppWidgetOptions(int, Bundle)}
654 *
655 * @hide
656 */
657 public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) {
658 try {
Jim Millera75a8832013-02-07 16:53:32 -0800659 sService.bindAppWidgetId(appWidgetId, provider, options, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700660 }
661 catch (RemoteException e) {
662 throw new RuntimeException("system server dead?", e);
663 }
664 }
665
666 /**
Michael Jurka61a5b012012-04-13 10:39:45 -0700667 * Set the component for a given appWidgetId.
668 *
669 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
670 * widgets always for your component. Should be used by apps that host widgets; if this
671 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
672 * bind
673 *
674 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
675 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
676 * provider for this AppWidget.
677 * @return true if this component has permission to bind the AppWidget
678 */
679 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) {
680 if (mContext == null) {
681 return false;
682 }
683 try {
684 return sService.bindAppWidgetIdIfAllowed(
Jim Millera75a8832013-02-07 16:53:32 -0800685 mContext.getPackageName(), appWidgetId, provider, null, mContext.getUserId());
Adam Cohen0aa2d422012-09-07 17:37:26 -0700686 }
687 catch (RemoteException e) {
688 throw new RuntimeException("system server dead?", e);
689 }
690 }
691
692 /**
693 * Set the component for a given appWidgetId.
694 *
695 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding
696 * widgets always for your component. Should be used by apps that host widgets; if this
697 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to
698 * bind
699 *
700 * @param appWidgetId The AppWidget instance for which to set the RemoteViews.
701 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget
702 * provider for this AppWidget.
703 * @param options Bundle containing options for the AppWidget. See also
704 * {@link #updateAppWidgetOptions(int, Bundle)}
705 *
706 * @return true if this component has permission to bind the AppWidget
707 */
708 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider,
709 Bundle options) {
710 if (mContext == null) {
711 return false;
712 }
713 try {
Jim Millera75a8832013-02-07 16:53:32 -0800714 return sService.bindAppWidgetIdIfAllowed(mContext.getPackageName(), appWidgetId,
715 provider, options, mContext.getUserId());
Michael Jurka61a5b012012-04-13 10:39:45 -0700716 }
717 catch (RemoteException e) {
718 throw new RuntimeException("system server dead?", e);
719 }
720 }
721
722 /**
723 * Query if a given package was granted permission by the user to bind app widgets
724 *
725 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
726 *
727 * @param packageName The package for which the permission is being queried
728 * @return true if the package was granted permission by the user to bind app widgets
729 * @hide
730 */
731 public boolean hasBindAppWidgetPermission(String packageName) {
732 try {
Jim Millera75a8832013-02-07 16:53:32 -0800733 return sService.hasBindAppWidgetPermission(packageName, mContext.getUserId());
Michael Jurka61a5b012012-04-13 10:39:45 -0700734 }
735 catch (RemoteException e) {
736 throw new RuntimeException("system server dead?", e);
737 }
738 }
739
740 /**
741 * Changes any user-granted permission for the given package to bind app widgets
742 *
743 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission
744 *
745 * @param provider The package whose permission is being changed
746 * @param permission Whether to give the package permission to bind widgets
747 * @hide
748 */
749 public void setBindAppWidgetPermission(String packageName, boolean permission) {
750 try {
Jim Millera75a8832013-02-07 16:53:32 -0800751 sService.setBindAppWidgetPermission(packageName, permission, mContext.getUserId());
Michael Jurka61a5b012012-04-13 10:39:45 -0700752 }
753 catch (RemoteException e) {
754 throw new RuntimeException("system server dead?", e);
755 }
756 }
757
758 /**
Winson Chung81f39eb2011-01-11 18:05:01 -0800759 * Binds the RemoteViewsService for a given appWidgetId and intent.
760 *
761 * The appWidgetId specified must already be bound to the calling AppWidgetHost via
762 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
763 *
764 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
765 * @param intent The intent of the service which will be providing the data to the
766 * RemoteViewsAdapter.
767 * @param connection The callback interface to be notified when a connection is made or lost.
Amith Yamasanic566b432012-11-30 15:26:21 -0800768 * @param userHandle The user to bind to.
Winson Chung81f39eb2011-01-11 18:05:01 -0800769 * @hide
770 */
Amith Yamasanic566b432012-11-30 15:26:21 -0800771 public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection,
772 UserHandle userHandle) {
Winson Chung81f39eb2011-01-11 18:05:01 -0800773 try {
Amith Yamasanic566b432012-11-30 15:26:21 -0800774 sService.bindRemoteViewsService(appWidgetId, intent, connection,
775 userHandle.getIdentifier());
Winson Chung81f39eb2011-01-11 18:05:01 -0800776 }
777 catch (RemoteException e) {
778 throw new RuntimeException("system server dead?", e);
779 }
780 }
781
782 /**
783 * Unbinds the RemoteViewsService for a given appWidgetId and intent.
784 *
785 * The appWidgetId specified muse already be bound to the calling AppWidgetHost via
786 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}.
787 *
788 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService.
789 * @param intent The intent of the service which will be providing the data to the
790 * RemoteViewsAdapter.
Amith Yamasanic566b432012-11-30 15:26:21 -0800791 * @param userHandle The user to unbind from.
Winson Chung81f39eb2011-01-11 18:05:01 -0800792 * @hide
793 */
Amith Yamasanic566b432012-11-30 15:26:21 -0800794 public void unbindRemoteViewsService(int appWidgetId, Intent intent, UserHandle userHandle) {
Winson Chung81f39eb2011-01-11 18:05:01 -0800795 try {
Amith Yamasanic566b432012-11-30 15:26:21 -0800796 sService.unbindRemoteViewsService(appWidgetId, intent, userHandle.getIdentifier());
Winson Chung81f39eb2011-01-11 18:05:01 -0800797 }
798 catch (RemoteException e) {
799 throw new RuntimeException("system server dead?", e);
800 }
801 }
802
803 /**
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700804 * Get the list of appWidgetIds that have been bound to the given AppWidget
805 * provider.
Christian Mehlmauer10c543d2010-06-25 19:27:04 +0200806 *
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700807 * @param provider The {@link android.content.BroadcastReceiver} that is the
808 * AppWidget provider to find appWidgetIds for.
809 */
810 public int[] getAppWidgetIds(ComponentName provider) {
811 try {
Jim Millera75a8832013-02-07 16:53:32 -0800812 return sService.getAppWidgetIds(provider, mContext.getUserId());
The Android Open Source Projectc39a6e02009-03-11 12:11:56 -0700813 }
814 catch (RemoteException e) {
815 throw new RuntimeException("system server dead?", e);
816 }
817 }
818}
819