AppWidgetManager.java revision adfe8b86e9178a553b6db9722340fa4ff5201cf1
1/* 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; 21import android.content.Intent; 22import android.os.Bundle; 23import android.os.IBinder; 24import android.os.RemoteException; 25import android.os.ServiceManager; 26import android.os.UserHandle; 27import android.util.DisplayMetrics; 28import android.util.TypedValue; 29import 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. 40 * 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> 46 */ 47public class AppWidgetManager { 48 static final String TAG = "AppWidgetManager"; 49 50 /** 51 * 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. 53 * <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 /** 84 * 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 /** 91 * Activity action to launch from your {@link AppWidgetHost} activity when you want to bind 92 * an AppWidget to display and bindAppWidgetIdIfAllowed returns false. 93 * <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 /** 131 * 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 /** 161 * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance. 162 */ 163 public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth"; 164 165 /** 166 * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance. 167 */ 168 public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight"; 169 170 /** 171 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. 172 */ 173 public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth"; 174 175 /** 176 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. 177 */ 178 public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight"; 179 180 /** 181 * 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 /** 189 * 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 */ 192 public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions"; 193 194 /** 195 * 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 /** 203 * 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 /** 210 * 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 attached to the {@link #ACTION_APPWIDGET_HOST_RESTORED} broadcast, 218 * indicating the integer ID of the host whose widgets have just been restored. 219 */ 220 public static final String EXTRA_HOST_ID = "hostId"; 221 222 /** 223 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of 224 * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are 225 * installed. It will be added to the extras object on the {@link android.content.Intent} 226 * that is returned from the picker activity. 227 * 228 * {@more} 229 */ 230 public static final String EXTRA_CUSTOM_EXTRAS = "customExtras"; 231 232 /** 233 * An intent extra to pass to the AppWidget picker which allows the picker to filter 234 * the list based on the {@link AppWidgetProviderInfo#widgetCategory}. 235 * 236 * @hide 237 */ 238 public static final String EXTRA_CATEGORY_FILTER = "categoryFilter"; 239 240 /** 241 * An intent extra to pass to the AppWidget picker to specify whether or not to sort 242 * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets 243 * @hide 244 */ 245 public static final String EXTRA_CUSTOM_SORT = "customSort"; 246 247 /** 248 * A sentinel value that the AppWidget manager will never return as a appWidgetId. 249 */ 250 public static final int INVALID_APPWIDGET_ID = 0; 251 252 /** 253 * Sent when it is time to update your AppWidget. 254 * 255 * <p>This may be sent in response to a new instance for this AppWidget provider having 256 * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval} 257 * having lapsed, or the system booting. 258 * 259 * <p> 260 * The intent will contain the following extras: 261 * <table> 262 * <tr> 263 * <td>{@link #EXTRA_APPWIDGET_IDS}</td> 264 * <td>The appWidgetIds to update. This may be all of the AppWidgets created for this 265 * provider, or just a subset. The system tries to send updates for as few AppWidget 266 * instances as possible.</td> 267 * </tr> 268 * </table> 269 * 270 * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 271 */ 272 public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; 273 274 /** 275 * Sent when the custom extras for an AppWidget change. 276 * 277 * <p class="note">This is a protected intent that can only be sent 278 * by the system. 279 * 280 * @see AppWidgetProvider#onAppWidgetOptionsChanged 281 * AppWidgetProvider.onAppWidgetOptionsChanged(Context context, 282 * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras) 283 */ 284 public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS"; 285 286 /** 287 * Sent when an instance of an AppWidget is deleted from its host. 288 * 289 * <p class="note">This is a protected intent that can only be sent 290 * by the system. 291 * 292 * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds) 293 */ 294 public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"; 295 296 /** 297 * Sent when an instance of an AppWidget is removed from the last host. 298 * 299 * <p class="note">This is a protected intent that can only be sent 300 * by the system. 301 * 302 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context) 303 */ 304 public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"; 305 306 /** 307 * Sent when an instance of an AppWidget is added to a host for the first time. 308 * This broadcast is sent at boot time if there is a AppWidgetHost installed with 309 * an instance for this provider. 310 * 311 * <p class="note">This is a protected intent that can only be sent 312 * by the system. 313 * 314 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context) 315 */ 316 public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED"; 317 318 /** 319 * Sent to providers after AppWidget state related to the provider has been restored from 320 * backup. The intent contains information about how to translate AppWidget ids from the 321 * restored data to their new equivalents. 322 * 323 * <p>The intent will contain the following extras: 324 * 325 * <table> 326 * <tr> 327 * <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td> 328 * <td>The set of appWidgetIds represented in a restored backup that have been successfully 329 * incorporated into the current environment. This may be all of the AppWidgets known 330 * to this application, or just a subset. Each entry in this array of appWidgetIds has 331 * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td> 332 * </tr> 333 * <tr> 334 * <td>{@link #EXTRA_APPWIDGET_IDS}</td> 335 * <td>The set of appWidgetIds now valid for this application. The app should look at 336 * its restored widget configuration and translate each appWidgetId in the 337 * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding 338 * index within this array.</td> 339 * </tr> 340 * </table> 341 * 342 * <p class="note">This is a protected intent that can only be sent 343 * by the system. 344 * 345 * @see {@link #ACTION_APPWIDGET_HOST_RESTORED} for the corresponding host broadcast 346 */ 347 public static final String ACTION_APPWIDGET_RESTORED 348 = "android.appwidget.action.APPWIDGET_RESTORED"; 349 350 /** 351 * Sent to widget hosts after AppWidget state related to the host has been restored from 352 * backup. The intent contains information about how to translate AppWidget ids from the 353 * restored data to their new equivalents. If an application maintains multiple separate 354 * widget hosts instances, it will receive this broadcast separately for each one. 355 * 356 * <p>The intent will contain the following extras: 357 * 358 * <table> 359 * <tr> 360 * <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td> 361 * <td>The set of appWidgetIds represented in a restored backup that have been successfully 362 * incorporated into the current environment. This may be all of the AppWidgets known 363 * to this application, or just a subset. Each entry in this array of appWidgetIds has 364 * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td> 365 * </tr> 366 * <tr> 367 * <td>{@link #EXTRA_APPWIDGET_IDS}</td> 368 * <td>The set of appWidgetIds now valid for this application. The app should look at 369 * its restored widget configuration and translate each appWidgetId in the 370 * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding 371 * index within this array.</td> 372 * </tr> 373 * <tr> 374 * <td>{@link #EXTRA_HOST_ID}</td> 375 * <td>The integer ID of the widget host instance whose state has just been restored.</td> 376 * </tr> 377 * </table> 378 * 379 * <p class="note">This is a protected intent that can only be sent 380 * by the system. 381 * 382 * @see {@link #ACTION_APPWIDGET_RESTORED} for the corresponding provider broadcast 383 */ 384 public static final String ACTION_APPWIDGET_HOST_RESTORED 385 = "android.appwidget.action.APPWIDGET_HOST_RESTORED"; 386 387 /** 388 * An intent extra that contains multiple appWidgetIds. These are id values as 389 * they were provided to the application during a recent restore from backup. It is 390 * attached to the {@link #ACTION_APPWIDGET_RESTORED} broadcast intent. 391 * 392 * <p> 393 * The value will be an int array that can be retrieved like this: 394 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS} 395 */ 396 public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds"; 397 398 /** 399 * Field for the manifest meta-data tag. 400 * 401 * @see AppWidgetProviderInfo 402 */ 403 public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider"; 404 405 static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache = 406 new WeakHashMap<Context, WeakReference<AppWidgetManager>>(); 407 static IAppWidgetService sService; 408 409 Context mContext; 410 411 private DisplayMetrics mDisplayMetrics; 412 413 /** 414 * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context 415 * Context} object. 416 */ 417 public static AppWidgetManager getInstance(Context context) { 418 synchronized (sManagerCache) { 419 if (sService == null) { 420 IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE); 421 sService = IAppWidgetService.Stub.asInterface(b); 422 } 423 424 WeakReference<AppWidgetManager> ref = sManagerCache.get(context); 425 AppWidgetManager result = null; 426 if (ref != null) { 427 result = ref.get(); 428 } 429 if (result == null) { 430 result = new AppWidgetManager(context); 431 sManagerCache.put(context, new WeakReference<AppWidgetManager>(result)); 432 } 433 return result; 434 } 435 } 436 437 private AppWidgetManager(Context context) { 438 mContext = context; 439 mDisplayMetrics = context.getResources().getDisplayMetrics(); 440 } 441 442 /** 443 * Set the RemoteViews to use for the specified appWidgetIds. 444 * 445 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should 446 * contain a complete representation of the widget. For performing partial widget updates, see 447 * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}. 448 * 449 * <p> 450 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 451 * and outside of the handler. 452 * This method will only work when called from the uid that owns the AppWidget provider. 453 * 454 * <p> 455 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to 456 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. 457 * 458 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. 459 * @param views The RemoteViews object to show. 460 */ 461 public void updateAppWidget(int[] appWidgetIds, RemoteViews views) { 462 try { 463 sService.updateAppWidgetIds(appWidgetIds, views, mContext.getUserId()); 464 } 465 catch (RemoteException e) { 466 throw new RuntimeException("system server dead?", e); 467 } 468 } 469 470 /** 471 * Update the extras for a given widget instance. 472 * 473 * The extras can be used to embed additional information about this widget to be accessed 474 * by the associated widget's AppWidgetProvider. 475 * 476 * @see #getAppWidgetOptions(int) 477 * 478 * @param appWidgetId The AppWidget instances for which to set the RemoteViews. 479 * @param options The options to associate with this widget 480 */ 481 public void updateAppWidgetOptions(int appWidgetId, Bundle options) { 482 try { 483 sService.updateAppWidgetOptions(appWidgetId, options, mContext.getUserId()); 484 } 485 catch (RemoteException e) { 486 throw new RuntimeException("system server dead?", e); 487 } 488 } 489 490 /** 491 * Get the extras associated with a given widget instance. 492 * 493 * The extras can be used to embed additional information about this widget to be accessed 494 * by the associated widget's AppWidgetProvider. 495 * 496 * @see #updateAppWidgetOptions(int, Bundle) 497 * 498 * @param appWidgetId The AppWidget instances for which to set the RemoteViews. 499 * @return The options associated with the given widget instance. 500 */ 501 public Bundle getAppWidgetOptions(int appWidgetId) { 502 try { 503 return sService.getAppWidgetOptions(appWidgetId, mContext.getUserId()); 504 } 505 catch (RemoteException e) { 506 throw new RuntimeException("system server dead?", e); 507 } 508 } 509 510 /** 511 * Set the RemoteViews to use for the specified appWidgetId. 512 * 513 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should 514 * contain a complete representation of the widget. For performing partial widget updates, see 515 * {@link #partiallyUpdateAppWidget(int, RemoteViews)}. 516 * 517 * <p> 518 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 519 * and outside of the handler. 520 * This method will only work when called from the uid that owns the AppWidget provider. 521 * 522 * <p> 523 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to 524 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. 525 * 526 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 527 * @param views The RemoteViews object to show. 528 */ 529 public void updateAppWidget(int appWidgetId, RemoteViews views) { 530 updateAppWidget(new int[] { appWidgetId }, views); 531 } 532 533 /** 534 * Perform an incremental update or command on the widget(s) specified by appWidgetIds. 535 * 536 * This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the 537 * RemoteViews object which is passed is understood to be an incomplete representation of the 538 * widget, and hence does not replace the cached representation of the widget. As of API 539 * level 17, the new properties set within the views objects will be appended to the cached 540 * representation of the widget, and hence will persist. 541 * 542 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, 543 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. 544 * 545 * <p> 546 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 547 * and outside of the handler. 548 * This method will only work when called from the uid that owns the AppWidget provider. 549 * 550 * <p> 551 * This method will be ignored if a widget has not received a full update via 552 * {@link #updateAppWidget(int[], RemoteViews)}. 553 * 554 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. 555 * @param views The RemoteViews object containing the incremental update / command. 556 */ 557 public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) { 558 try { 559 sService.partiallyUpdateAppWidgetIds(appWidgetIds, views, mContext.getUserId()); 560 } catch (RemoteException e) { 561 throw new RuntimeException("system server dead?", e); 562 } 563 } 564 565 /** 566 * Perform an incremental update or command on the widget specified by appWidgetId. 567 * 568 * This update differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews 569 * object which is passed is understood to be an incomplete representation of the widget, and 570 * hence is not cached by the AppWidgetService. Note that because these updates are not cached, 571 * any state that they modify that is not restored by restoreInstanceState will not persist in 572 * the case that the widgets are restored using the cached version in AppWidgetService. 573 * 574 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, 575 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. 576 * 577 * <p> 578 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 579 * and outside of the handler. 580 * This method will only work when called from the uid that owns the AppWidget provider. 581 * 582 * <p> 583 * This method will be ignored if a widget has not received a full update via 584 * {@link #updateAppWidget(int[], RemoteViews)}. 585 * 586 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 587 * @param views The RemoteViews object containing the incremental update / command. 588 */ 589 public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) { 590 partiallyUpdateAppWidget(new int[] { appWidgetId }, views); 591 } 592 593 /** 594 * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider. 595 * 596 * <p> 597 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 598 * and outside of the handler. 599 * This method will only work when called from the uid that owns the AppWidget provider. 600 * 601 * @param provider The {@link ComponentName} for the {@link 602 * android.content.BroadcastReceiver BroadcastReceiver} provider 603 * for your AppWidget. 604 * @param views The RemoteViews object to show. 605 */ 606 public void updateAppWidget(ComponentName provider, RemoteViews views) { 607 try { 608 sService.updateAppWidgetProvider(provider, views, mContext.getUserId()); 609 } 610 catch (RemoteException e) { 611 throw new RuntimeException("system server dead?", e); 612 } 613 } 614 615 /** 616 * Notifies the specified collection view in all the specified AppWidget instances 617 * to invalidate their data. 618 * 619 * @param appWidgetIds The AppWidget instances to notify of view data changes. 620 * @param viewId The collection view id. 621 */ 622 public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) { 623 try { 624 sService.notifyAppWidgetViewDataChanged(appWidgetIds, viewId, mContext.getUserId()); 625 } 626 catch (RemoteException e) { 627 throw new RuntimeException("system server dead?", e); 628 } 629 } 630 631 /** 632 * Notifies the specified collection view in the specified AppWidget instance 633 * to invalidate its data. 634 * 635 * @param appWidgetId The AppWidget instance to notify of view data changes. 636 * @param viewId The collection view id. 637 */ 638 public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) { 639 notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId); 640 } 641 642 /** 643 * Return a list of the AppWidget providers that are currently installed. 644 */ 645 public List<AppWidgetProviderInfo> getInstalledProviders() { 646 return getInstalledProviders(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN); 647 } 648 649 /** 650 * Return a list of the AppWidget providers that are currently installed. 651 * 652 * @param categoryFilter Will only return providers which register as any of the specified 653 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}. 654 * @hide 655 */ 656 public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) { 657 try { 658 List<AppWidgetProviderInfo> providers = sService.getInstalledProviders(categoryFilter, 659 mContext.getUserId()); 660 for (AppWidgetProviderInfo info : providers) { 661 // Converting complex to dp. 662 info.minWidth = 663 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics); 664 info.minHeight = 665 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics); 666 info.minResizeWidth = 667 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics); 668 info.minResizeHeight = 669 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics); 670 } 671 return providers; 672 } 673 catch (RemoteException e) { 674 throw new RuntimeException("system server dead?", e); 675 } 676 } 677 678 /** 679 * Get the available info about the AppWidget. 680 * 681 * @return A appWidgetId. If the appWidgetId has not been bound to a provider yet, or 682 * you don't have access to that appWidgetId, null is returned. 683 */ 684 public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) { 685 try { 686 AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId, 687 mContext.getUserId()); 688 if (info != null) { 689 // Converting complex to dp. 690 info.minWidth = 691 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics); 692 info.minHeight = 693 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics); 694 info.minResizeWidth = 695 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics); 696 info.minResizeHeight = 697 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics); 698 } 699 return info; 700 } 701 catch (RemoteException e) { 702 throw new RuntimeException("system server dead?", e); 703 } 704 } 705 706 /** 707 * Set the component for a given appWidgetId. 708 * 709 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 710 * widgets always for your component. This method is used by the AppWidget picker and 711 * should not be used by other apps. 712 * 713 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 714 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 715 * provider for this AppWidget. 716 * @hide 717 */ 718 public void bindAppWidgetId(int appWidgetId, ComponentName provider) { 719 try { 720 sService.bindAppWidgetId(appWidgetId, provider, null, mContext.getUserId()); 721 } 722 catch (RemoteException e) { 723 throw new RuntimeException("system server dead?", e); 724 } 725 } 726 727 /** 728 * Set the component for a given appWidgetId. 729 * 730 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 731 * widgets always for your component. This method is used by the AppWidget picker and 732 * should not be used by other apps. 733 * 734 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 735 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 736 * provider for this AppWidget. 737 * @param options Bundle containing options for the AppWidget. See also 738 * {@link #updateAppWidgetOptions(int, Bundle)} 739 * 740 * @hide 741 */ 742 public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) { 743 try { 744 sService.bindAppWidgetId(appWidgetId, provider, options, mContext.getUserId()); 745 } 746 catch (RemoteException e) { 747 throw new RuntimeException("system server dead?", e); 748 } 749 } 750 751 /** 752 * Set the component for a given appWidgetId. 753 * 754 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 755 * widgets always for your component. Should be used by apps that host widgets; if this 756 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to 757 * bind 758 * 759 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 760 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 761 * provider for this AppWidget. 762 * @return true if this component has permission to bind the AppWidget 763 */ 764 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) { 765 if (mContext == null) { 766 return false; 767 } 768 try { 769 return sService.bindAppWidgetIdIfAllowed( 770 mContext.getPackageName(), appWidgetId, provider, null, mContext.getUserId()); 771 } 772 catch (RemoteException e) { 773 throw new RuntimeException("system server dead?", e); 774 } 775 } 776 777 /** 778 * Set the component for a given appWidgetId. 779 * 780 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 781 * widgets always for your component. Should be used by apps that host widgets; if this 782 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to 783 * bind 784 * 785 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 786 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 787 * provider for this AppWidget. 788 * @param options Bundle containing options for the AppWidget. See also 789 * {@link #updateAppWidgetOptions(int, Bundle)} 790 * 791 * @return true if this component has permission to bind the AppWidget 792 */ 793 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider, 794 Bundle options) { 795 if (mContext == null) { 796 return false; 797 } 798 try { 799 return sService.bindAppWidgetIdIfAllowed(mContext.getPackageName(), appWidgetId, 800 provider, options, mContext.getUserId()); 801 } 802 catch (RemoteException e) { 803 throw new RuntimeException("system server dead?", e); 804 } 805 } 806 807 /** 808 * Query if a given package was granted permission by the user to bind app widgets 809 * 810 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 811 * 812 * @param packageName The package for which the permission is being queried 813 * @return true if the package was granted permission by the user to bind app widgets 814 * @hide 815 */ 816 public boolean hasBindAppWidgetPermission(String packageName) { 817 try { 818 return sService.hasBindAppWidgetPermission(packageName, mContext.getUserId()); 819 } 820 catch (RemoteException e) { 821 throw new RuntimeException("system server dead?", e); 822 } 823 } 824 825 /** 826 * Changes any user-granted permission for the given package to bind app widgets 827 * 828 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 829 * 830 * @param provider The package whose permission is being changed 831 * @param permission Whether to give the package permission to bind widgets 832 * @hide 833 */ 834 public void setBindAppWidgetPermission(String packageName, boolean permission) { 835 try { 836 sService.setBindAppWidgetPermission(packageName, permission, mContext.getUserId()); 837 } 838 catch (RemoteException e) { 839 throw new RuntimeException("system server dead?", e); 840 } 841 } 842 843 /** 844 * Binds the RemoteViewsService for a given appWidgetId and intent. 845 * 846 * The appWidgetId specified must already be bound to the calling AppWidgetHost via 847 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}. 848 * 849 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService. 850 * @param intent The intent of the service which will be providing the data to the 851 * RemoteViewsAdapter. 852 * @param connection The callback interface to be notified when a connection is made or lost. 853 * @param userHandle The user to bind to. 854 * @hide 855 */ 856 public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection, 857 UserHandle userHandle) { 858 try { 859 sService.bindRemoteViewsService(appWidgetId, intent, connection, 860 userHandle.getIdentifier()); 861 } 862 catch (RemoteException e) { 863 throw new RuntimeException("system server dead?", e); 864 } 865 } 866 867 /** 868 * Unbinds the RemoteViewsService for a given appWidgetId and intent. 869 * 870 * The appWidgetId specified muse already be bound to the calling AppWidgetHost via 871 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}. 872 * 873 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService. 874 * @param intent The intent of the service which will be providing the data to the 875 * RemoteViewsAdapter. 876 * @param userHandle The user to unbind from. 877 * @hide 878 */ 879 public void unbindRemoteViewsService(int appWidgetId, Intent intent, UserHandle userHandle) { 880 try { 881 sService.unbindRemoteViewsService(appWidgetId, intent, userHandle.getIdentifier()); 882 } 883 catch (RemoteException e) { 884 throw new RuntimeException("system server dead?", e); 885 } 886 } 887 888 /** 889 * Get the list of appWidgetIds that have been bound to the given AppWidget 890 * provider. 891 * 892 * @param provider The {@link android.content.BroadcastReceiver} that is the 893 * AppWidget provider to find appWidgetIds for. 894 */ 895 public int[] getAppWidgetIds(ComponentName provider) { 896 try { 897 return sService.getAppWidgetIds(provider, mContext.getUserId()); 898 } 899 catch (RemoteException e) { 900 throw new RuntimeException("system server dead?", e); 901 } 902 } 903} 904 905