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.annotation.Nullable; 20import android.content.ComponentName; 21import android.content.Context; 22import android.content.Intent; 23import android.content.pm.ParceledListSlice; 24import android.os.Bundle; 25import android.os.IBinder; 26import android.os.Process; 27import android.os.RemoteException; 28import android.os.UserHandle; 29import android.util.DisplayMetrics; 30import android.util.TypedValue; 31import android.widget.RemoteViews; 32 33import com.android.internal.appwidget.IAppWidgetService; 34 35import java.util.Collections; 36import java.util.List; 37 38/** 39 * Updates AppWidget state; gets information about installed AppWidget providers and other 40 * AppWidget related state. 41 * 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> 47 */ 48public class 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 76 * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you 77 * should delete 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 * <tr> 107 * <td>{@link #EXTRA_APPWIDGET_PROVIDER_PROFILE}</td> 108 * <td>An optional handle to a user profile under which runs the provider 109 * for this AppWidget. 110 * </td> 111 * </tr> 112 * </table> 113 * 114 * <p> 115 * The system will respond with an onActivityResult call with the following extras in 116 * the intent: 117 * <table> 118 * <tr> 119 * <td>{@link #EXTRA_APPWIDGET_ID}</td> 120 * <td>The appWidgetId that you supplied in the original intent.</td> 121 * </tr> 122 * </table> 123 * <p> 124 * When you receive the result from the AppWidget bind activity, if the resultCode is 125 * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound. You should then 126 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its 127 * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you 128 * should delete the appWidgetId. 129 * 130 * @see #ACTION_APPWIDGET_CONFIGURE 131 * 132 */ 133 public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND"; 134 135 /** 136 * Sent when it is time to configure your AppWidget while it is being added to a host. 137 * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity 138 * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo 139 * meta-data}. 140 * 141 * <p> 142 * The intent will contain the following extras: 143 * <table> 144 * <tr> 145 * <td>{@link #EXTRA_APPWIDGET_ID}</td> 146 * <td>The appWidgetId to configure.</td> 147 * </tr> 148 * </table> 149 * 150 * <p>If you return {@link android.app.Activity#RESULT_OK} using 151 * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added, 152 * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget. 153 * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add 154 * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} 155 * broadcast. 156 */ 157 public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE"; 158 159 /** 160 * An intent extra that contains one appWidgetId. 161 * <p> 162 * The value will be an int that can be retrieved like this: 163 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID} 164 */ 165 public static final String EXTRA_APPWIDGET_ID = "appWidgetId"; 166 167 /** 168 * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance. 169 */ 170 public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth"; 171 172 /** 173 * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance. 174 */ 175 public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight"; 176 177 /** 178 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. 179 */ 180 public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth"; 181 182 /** 183 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. 184 */ 185 public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight"; 186 187 /** 188 * A bundle extra that hints to the AppWidgetProvider the category of host that owns this 189 * this widget. Can have the value {@link 190 * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link 191 * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD} or {@link 192 * AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}. 193 */ 194 public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory"; 195 196 /** 197 * An intent extra which points to a bundle of extra information for a particular widget id. 198 * In particular this bundle can contain {@link #OPTION_APPWIDGET_MIN_WIDTH}, 199 * {@link #OPTION_APPWIDGET_MIN_HEIGHT}, {@link #OPTION_APPWIDGET_MAX_WIDTH}, 200 * {@link #OPTION_APPWIDGET_MAX_HEIGHT}. 201 */ 202 public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions"; 203 204 /** 205 * An intent extra that contains multiple appWidgetIds. 206 * <p> 207 * The value will be an int array that can be retrieved like this: 208 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS} 209 */ 210 public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds"; 211 212 /** 213 * An intent extra that contains the component name of a AppWidget provider. 214 * <p> 215 * The value will be an {@link android.content.ComponentName}. 216 */ 217 public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider"; 218 219 /** 220 * An intent extra that contains the user handle of the profile under 221 * which an AppWidget provider is registered. 222 * <p> 223 * The value will be a {@link android.os.UserHandle}. 224 */ 225 public static final String EXTRA_APPWIDGET_PROVIDER_PROFILE = "appWidgetProviderProfile"; 226 227 /** 228 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of 229 * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are 230 * installed. (This is how the launcher shows the search widget). 231 */ 232 public static final String EXTRA_CUSTOM_INFO = "customInfo"; 233 234 /** 235 * An intent extra attached to the {@link #ACTION_APPWIDGET_HOST_RESTORED} broadcast, 236 * indicating the integer ID of the host whose widgets have just been restored. 237 */ 238 public static final String EXTRA_HOST_ID = "hostId"; 239 240 /** 241 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of 242 * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are 243 * installed. It will be added to the extras object on the {@link android.content.Intent} 244 * that is returned from the picker activity. 245 * 246 * {@more} 247 */ 248 public static final String EXTRA_CUSTOM_EXTRAS = "customExtras"; 249 250 /** 251 * An intent extra to pass to the AppWidget picker which allows the picker to filter 252 * the list based on the {@link AppWidgetProviderInfo#widgetCategory}. 253 * 254 * @hide 255 */ 256 public static final String EXTRA_CATEGORY_FILTER = "categoryFilter"; 257 258 /** 259 * An intent extra to pass to the AppWidget picker to specify whether or not to sort 260 * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets 261 * @hide 262 */ 263 public static final String EXTRA_CUSTOM_SORT = "customSort"; 264 265 /** 266 * A sentinel value that the AppWidget manager will never return as a appWidgetId. 267 */ 268 public static final int INVALID_APPWIDGET_ID = 0; 269 270 /** 271 * Sent when it is time to update your AppWidget. 272 * 273 * <p>This may be sent in response to a new instance for this AppWidget provider having 274 * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval} 275 * having lapsed, or the system booting. 276 * 277 * <p> 278 * The intent will contain the following extras: 279 * <table> 280 * <tr> 281 * <td>{@link #EXTRA_APPWIDGET_IDS}</td> 282 * <td>The appWidgetIds to update. This may be all of the AppWidgets created for this 283 * provider, or just a subset. The system tries to send updates for as few AppWidget 284 * instances as possible.</td> 285 * </tr> 286 * </table> 287 * 288 * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 289 */ 290 public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; 291 292 /** 293 * Sent when the custom extras for an AppWidget change. 294 * 295 * <p class="note">This is a protected intent that can only be sent 296 * by the system. 297 * 298 * @see AppWidgetProvider#onAppWidgetOptionsChanged 299 * AppWidgetProvider.onAppWidgetOptionsChanged(Context context, 300 * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras) 301 */ 302 public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS"; 303 304 /** 305 * Sent when an instance of an AppWidget is deleted from its host. 306 * 307 * <p class="note">This is a protected intent that can only be sent 308 * by the system. 309 * 310 * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds) 311 */ 312 public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"; 313 314 /** 315 * Sent when the last AppWidget of this provider is removed from the last host. 316 * 317 * <p class="note">This is a protected intent that can only be sent 318 * by the system. 319 * 320 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onDisabled(Context context) 321 */ 322 public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"; 323 324 /** 325 * Sent when an instance of an AppWidget is added to a host for the first time. 326 * This broadcast is sent at boot time if there is a AppWidgetHost installed with 327 * an instance for this provider. 328 * 329 * <p class="note">This is a protected intent that can only be sent 330 * by the system. 331 * 332 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context) 333 */ 334 public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED"; 335 336 /** 337 * Sent to an {@link AppWidgetProvider} after AppWidget state related to that provider has 338 * been restored from backup. The intent contains information about how to translate AppWidget 339 * ids from the restored data to their new equivalents. 340 * 341 * <p>The intent will contain the following extras: 342 * 343 * <table> 344 * <tr> 345 * <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td> 346 * <td>The set of appWidgetIds represented in a restored backup that have been successfully 347 * incorporated into the current environment. This may be all of the AppWidgets known 348 * to this application, or just a subset. Each entry in this array of appWidgetIds has 349 * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td> 350 * </tr> 351 * <tr> 352 * <td>{@link #EXTRA_APPWIDGET_IDS}</td> 353 * <td>The set of appWidgetIds now valid for this application. The app should look at 354 * its restored widget configuration and translate each appWidgetId in the 355 * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding 356 * index within this array.</td> 357 * </tr> 358 * </table> 359 * 360 * <p class="note">This is a protected intent that can only be sent 361 * by the system. 362 * 363 * @see #ACTION_APPWIDGET_HOST_RESTORED 364 */ 365 public static final String ACTION_APPWIDGET_RESTORED 366 = "android.appwidget.action.APPWIDGET_RESTORED"; 367 368 /** 369 * Sent to widget hosts after AppWidget state related to the host has been restored from 370 * backup. The intent contains information about how to translate AppWidget ids from the 371 * restored data to their new equivalents. If an application maintains multiple separate 372 * widget host instances, it will receive this broadcast separately for each one. 373 * 374 * <p>The intent will contain the following extras: 375 * 376 * <table> 377 * <tr> 378 * <td>{@link #EXTRA_APPWIDGET_OLD_IDS}</td> 379 * <td>The set of appWidgetIds represented in a restored backup that have been successfully 380 * incorporated into the current environment. This may be all of the AppWidgets known 381 * to this application, or just a subset. Each entry in this array of appWidgetIds has 382 * a corresponding entry in the {@link #EXTRA_APPWIDGET_IDS} extra.</td> 383 * </tr> 384 * <tr> 385 * <td>{@link #EXTRA_APPWIDGET_IDS}</td> 386 * <td>The set of appWidgetIds now valid for this application. The app should look at 387 * its restored widget configuration and translate each appWidgetId in the 388 * {@link #EXTRA_APPWIDGET_OLD_IDS} array to its new value found at the corresponding 389 * index within this array.</td> 390 * </tr> 391 * <tr> 392 * <td>{@link #EXTRA_HOST_ID}</td> 393 * <td>The integer ID of the widget host instance whose state has just been restored.</td> 394 * </tr> 395 * </table> 396 * 397 * <p class="note">This is a protected intent that can only be sent 398 * by the system. 399 * 400 * @see #ACTION_APPWIDGET_RESTORED 401 */ 402 public static final String ACTION_APPWIDGET_HOST_RESTORED 403 = "android.appwidget.action.APPWIDGET_HOST_RESTORED"; 404 405 /** 406 * An intent extra that contains multiple appWidgetIds. These are id values as 407 * they were provided to the application during a recent restore from backup. It is 408 * attached to the {@link #ACTION_APPWIDGET_RESTORED} broadcast intent. 409 * 410 * <p> 411 * The value will be an int array that can be retrieved like this: 412 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS} 413 */ 414 public static final String EXTRA_APPWIDGET_OLD_IDS = "appWidgetOldIds"; 415 416 /** 417 * Field for the manifest meta-data tag. 418 * 419 * @see AppWidgetProviderInfo 420 */ 421 public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider"; 422 423 private final String mPackageName; 424 425 private final IAppWidgetService mService; 426 427 private final DisplayMetrics mDisplayMetrics; 428 429 /** 430 * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context 431 * Context} object. 432 */ 433 public static AppWidgetManager getInstance(Context context) { 434 return (AppWidgetManager) context.getSystemService(Context.APPWIDGET_SERVICE); 435 } 436 437 /** 438 * Creates a new instance. 439 * 440 * @param context The current context in which to operate. 441 * @param service The backing system service. 442 * @hide 443 */ 444 public AppWidgetManager(Context context, IAppWidgetService service) { 445 mPackageName = context.getOpPackageName(); 446 mService = service; 447 mDisplayMetrics = context.getResources().getDisplayMetrics(); 448 } 449 450 /** 451 * Set the RemoteViews to use for the specified appWidgetIds. 452 * <p> 453 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should 454 * contain a complete representation of the widget. For performing partial widget updates, see 455 * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}. 456 * 457 * <p> 458 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 459 * and outside of the handler. 460 * This method will only work when called from the uid that owns the AppWidget provider. 461 * 462 * <p> 463 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to 464 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. 465 * 466 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. 467 * @param views The RemoteViews object to show. 468 */ 469 public void updateAppWidget(int[] appWidgetIds, RemoteViews views) { 470 if (mService == null) { 471 return; 472 } 473 try { 474 mService.updateAppWidgetIds(mPackageName, appWidgetIds, views); 475 } catch (RemoteException e) { 476 throw e.rethrowFromSystemServer(); 477 } 478 } 479 480 /** 481 * Update the extras for a given widget instance. 482 * <p> 483 * The extras can be used to embed additional information about this widget to be accessed 484 * by the associated widget's AppWidgetProvider. 485 * 486 * @see #getAppWidgetOptions(int) 487 * 488 * @param appWidgetId The AppWidget instances for which to set the RemoteViews. 489 * @param options The options to associate with this widget 490 */ 491 public void updateAppWidgetOptions(int appWidgetId, Bundle options) { 492 if (mService == null) { 493 return; 494 } 495 try { 496 mService.updateAppWidgetOptions(mPackageName, appWidgetId, options); 497 } catch (RemoteException e) { 498 throw e.rethrowFromSystemServer(); 499 } 500 } 501 502 /** 503 * Get the extras associated with a given widget instance. 504 * <p> 505 * The extras can be used to embed additional information about this widget to be accessed 506 * by the associated widget's AppWidgetProvider. 507 * 508 * @see #updateAppWidgetOptions(int, Bundle) 509 * 510 * @param appWidgetId The AppWidget instances for which to set the RemoteViews. 511 * @return The options associated with the given widget instance. 512 */ 513 public Bundle getAppWidgetOptions(int appWidgetId) { 514 if (mService == null) { 515 return Bundle.EMPTY; 516 } 517 try { 518 return mService.getAppWidgetOptions(mPackageName, appWidgetId); 519 } catch (RemoteException e) { 520 throw e.rethrowFromSystemServer(); 521 } 522 } 523 524 /** 525 * Set the RemoteViews to use for the specified appWidgetId. 526 * <p> 527 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should 528 * contain a complete representation of the widget. For performing partial widget updates, see 529 * {@link #partiallyUpdateAppWidget(int, RemoteViews)}. 530 * 531 * <p> 532 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 533 * and outside of the handler. 534 * This method will only work when called from the uid that owns the AppWidget provider. 535 * 536 * <p> 537 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to 538 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. 539 * 540 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 541 * @param views The RemoteViews object to show. 542 */ 543 public void updateAppWidget(int appWidgetId, RemoteViews views) { 544 if (mService == null) { 545 return; 546 } 547 updateAppWidget(new int[] { appWidgetId }, views); 548 } 549 550 /** 551 * Perform an incremental update or command on the widget(s) specified by appWidgetIds. 552 * <p> 553 * This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the 554 * RemoteViews object which is passed is understood to be an incomplete representation of the 555 * widget, and hence does not replace the cached representation of the widget. As of API 556 * level 17, the new properties set within the views objects will be appended to the cached 557 * representation of the widget, and hence will persist. 558 * 559 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, 560 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. 561 * 562 * <p> 563 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 564 * and outside of the handler. 565 * This method will only work when called from the uid that owns the AppWidget provider. 566 * 567 * <p> 568 * This method will be ignored if a widget has not received a full update via 569 * {@link #updateAppWidget(int[], RemoteViews)}. 570 * 571 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. 572 * @param views The RemoteViews object containing the incremental update / command. 573 */ 574 public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) { 575 if (mService == null) { 576 return; 577 } 578 try { 579 mService.partiallyUpdateAppWidgetIds(mPackageName, appWidgetIds, views); 580 } catch (RemoteException e) { 581 throw e.rethrowFromSystemServer(); 582 } 583 } 584 585 /** 586 * Perform an incremental update or command on the widget specified by appWidgetId. 587 * <p> 588 * This update differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews 589 * object which is passed is understood to be an incomplete representation of the widget, and 590 * hence is not cached by the AppWidgetService. Note that because these updates are not cached, 591 * any state that they modify that is not restored by restoreInstanceState will not persist in 592 * the case that the widgets are restored using the cached version in AppWidgetService. 593 * 594 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, 595 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. 596 * 597 * <p> 598 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 599 * and outside of the handler. 600 * This method will only work when called from the uid that owns the AppWidget provider. 601 * 602 * <p> 603 * This method will be ignored if a widget has not received a full update via 604 * {@link #updateAppWidget(int[], RemoteViews)}. 605 * 606 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 607 * @param views The RemoteViews object containing the incremental update / command. 608 */ 609 public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) { 610 if (mService == null) { 611 return; 612 } 613 partiallyUpdateAppWidget(new int[] { appWidgetId }, views); 614 } 615 616 /** 617 * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider. 618 * 619 * <p> 620 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 621 * and outside of the handler. 622 * This method will only work when called from the uid that owns the AppWidget provider. 623 * 624 * @param provider The {@link ComponentName} for the {@link 625 * android.content.BroadcastReceiver BroadcastReceiver} provider 626 * for your AppWidget. 627 * @param views The RemoteViews object to show. 628 */ 629 public void updateAppWidget(ComponentName provider, RemoteViews views) { 630 if (mService == null) { 631 return; 632 } 633 try { 634 mService.updateAppWidgetProvider(provider, views); 635 } catch (RemoteException e) { 636 throw e.rethrowFromSystemServer(); 637 } 638 } 639 640 /** 641 * Notifies the specified collection view in all the specified AppWidget instances 642 * to invalidate their data. 643 * 644 * @param appWidgetIds The AppWidget instances to notify of view data changes. 645 * @param viewId The collection view id. 646 */ 647 public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) { 648 if (mService == null) { 649 return; 650 } 651 try { 652 mService.notifyAppWidgetViewDataChanged(mPackageName, appWidgetIds, viewId); 653 } catch (RemoteException e) { 654 throw e.rethrowFromSystemServer(); 655 } 656 } 657 658 /** 659 * Notifies the specified collection view in the specified AppWidget instance 660 * to invalidate its data. 661 * 662 * @param appWidgetId The AppWidget instance to notify of view data changes. 663 * @param viewId The collection view id. 664 */ 665 public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) { 666 if (mService == null) { 667 return; 668 } 669 notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId); 670 } 671 672 /** 673 * Gets the AppWidget providers for the given user profile. User profile can only 674 * be the current user or a profile of the current user. For example, the current 675 * user may have a corporate profile. In this case the parent user profile has a 676 * child profile, the corporate one. 677 * 678 * @param profile The profile for which to get providers. Passing null is equivaled 679 * to passing only the current user handle. 680 * @return The intalled providers. 681 * 682 * @see android.os.Process#myUserHandle() 683 * @see android.os.UserManager#getUserProfiles() 684 */ 685 public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(@Nullable UserHandle profile) { 686 if (mService == null) { 687 return Collections.emptyList(); 688 } 689 return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN, 690 profile); 691 } 692 693 /** 694 * Return a list of the AppWidget providers that are currently installed. 695 */ 696 public List<AppWidgetProviderInfo> getInstalledProviders() { 697 if (mService == null) { 698 return Collections.emptyList(); 699 } 700 return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN, 701 null); 702 } 703 704 /** 705 * Gets the AppWidget providers for the current user. 706 * 707 * @param categoryFilter Will only return providers which register as any of the specified 708 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}. 709 * @return The intalled providers. 710 * 711 * @see android.os.Process#myUserHandle() 712 * @see android.os.UserManager#getUserProfiles() 713 * 714 * @hide 715 */ 716 public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) { 717 if (mService == null) { 718 return Collections.emptyList(); 719 } 720 return getInstalledProvidersForProfile(categoryFilter, null); 721 } 722 723 /** 724 * Gets the AppWidget providers for the given user profile. User profile can only 725 * be the current user or a profile of the current user. For example, the current 726 * user may have a corporate profile. In this case the parent user profile has a 727 * child profile, the corporate one. 728 * 729 * @param categoryFilter Will only return providers which register as any of the specified 730 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}. 731 * @param profile A profile of the current user which to be queried. The user 732 * is itself also a profile. If null, the providers only for the current user 733 * are returned. 734 * @return The intalled providers. 735 * 736 * @see android.os.Process#myUserHandle() 737 * @see android.os.UserManager#getUserProfiles() 738 * 739 * @hide 740 */ 741 public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter, 742 UserHandle profile) { 743 if (mService == null) { 744 return Collections.emptyList(); 745 } 746 747 if (profile == null) { 748 profile = Process.myUserHandle(); 749 } 750 751 try { 752 ParceledListSlice<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile( 753 categoryFilter, profile.getIdentifier()); 754 if (providers == null) { 755 return Collections.emptyList(); 756 } 757 for (AppWidgetProviderInfo info : providers.getList()) { 758 // Converting complex to dp. 759 convertSizesToPixels(info); 760 } 761 return providers.getList(); 762 } catch (RemoteException e) { 763 throw e.rethrowFromSystemServer(); 764 } 765 } 766 767 /** 768 * Get the available info about the AppWidget. 769 * 770 * @return A appWidgetId. If the appWidgetId has not been bound to a provider yet, or 771 * you don't have access to that appWidgetId, null is returned. 772 */ 773 public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) { 774 if (mService == null) { 775 return null; 776 } 777 try { 778 AppWidgetProviderInfo info = mService.getAppWidgetInfo(mPackageName, appWidgetId); 779 if (info != null) { 780 // Converting complex to dp. 781 convertSizesToPixels(info); 782 } 783 return info; 784 } catch (RemoteException e) { 785 throw e.rethrowFromSystemServer(); 786 } 787 } 788 789 /** 790 * Set the component for a given appWidgetId. 791 * 792 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 793 * widgets always for your component. This method is used by the AppWidget picker and 794 * should not be used by other apps. 795 * 796 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 797 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 798 * provider for this AppWidget. 799 * @hide 800 */ 801 public void bindAppWidgetId(int appWidgetId, ComponentName provider) { 802 if (mService == null) { 803 return; 804 } 805 bindAppWidgetId(appWidgetId, provider, null); 806 } 807 808 /** 809 * Set the component for a given appWidgetId. 810 * 811 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 812 * widgets always for your component. This method is used by the AppWidget picker and 813 * should not be used by other apps. 814 * 815 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 816 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 817 * provider for this AppWidget. 818 * @param options Bundle containing options for the AppWidget. See also 819 * {@link #updateAppWidgetOptions(int, Bundle)} 820 * 821 * @hide 822 */ 823 public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) { 824 if (mService == null) { 825 return; 826 } 827 bindAppWidgetIdIfAllowed(appWidgetId, Process.myUserHandle(), provider, options); 828 } 829 830 /** 831 * Set the component for a given appWidgetId. 832 * 833 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 834 * widgets always for your component. Should be used by apps that host widgets; if this 835 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to 836 * bind 837 * 838 * @param appWidgetId The AppWidget id under which to bind the provider. 839 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 840 * provider for this AppWidget. 841 * @return true if this component has permission to bind the AppWidget 842 */ 843 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) { 844 if (mService == null) { 845 return false; 846 } 847 return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, null); 848 } 849 850 /** 851 * Set the component for a given appWidgetId. 852 * 853 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 854 * widgets always for your component. Should be used by apps that host widgets; if this 855 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to 856 * bind 857 * 858 * @param appWidgetId The AppWidget id under which to bind the provider. 859 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 860 * provider for this AppWidget. 861 * @param options Bundle containing options for the AppWidget. See also 862 * {@link #updateAppWidgetOptions(int, Bundle)} 863 * 864 * @return true if this component has permission to bind the AppWidget 865 */ 866 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider, 867 Bundle options) { 868 if (mService == null) { 869 return false; 870 } 871 return bindAppWidgetIdIfAllowed(appWidgetId, UserHandle.myUserId(), provider, options); 872 } 873 874 /** 875 * Set the provider for a given appWidgetId if the caller has a permission. 876 * <p> 877 * <strong>Note:</strong> You need the {@link android.Manifest.permission#BIND_APPWIDGET} 878 * permission or the user must have enabled binding widgets always for your component. 879 * Should be used by apps that host widgets. If this method returns false, call {@link 880 * #ACTION_APPWIDGET_BIND} to request permission to bind. 881 * </p> 882 * 883 * @param appWidgetId The AppWidget id under which to bind the provider. 884 * @param user The user id in which the provider resides. 885 * @param provider The component name of the provider. 886 * @param options An optional Bundle containing options for the AppWidget. 887 * 888 * @return true if this component has permission to bind the AppWidget 889 */ 890 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, UserHandle user, 891 ComponentName provider, Bundle options) { 892 if (mService == null) { 893 return false; 894 } 895 return bindAppWidgetIdIfAllowed(appWidgetId, user.getIdentifier(), provider, options); 896 } 897 898 /** 899 * Query if a given package was granted permission by the user to bind app widgets 900 * 901 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 902 * 903 * @param packageName The package for which the permission is being queried 904 * @param userId The user id of the user under which the package runs. 905 * @return true if the package was granted permission by the user to bind app widgets 906 * @hide 907 */ 908 public boolean hasBindAppWidgetPermission(String packageName, int userId) { 909 if (mService == null) { 910 return false; 911 } 912 try { 913 return mService.hasBindAppWidgetPermission(packageName, userId); 914 } catch (RemoteException e) { 915 throw e.rethrowFromSystemServer(); 916 } 917 } 918 919 /** 920 * Query if a given package was granted permission by the user to bind app widgets 921 * 922 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 923 * 924 * @param packageName The package for which the permission is being queried 925 * @return true if the package was granted permission by the user to bind app widgets 926 * @hide 927 */ 928 public boolean hasBindAppWidgetPermission(String packageName) { 929 if (mService == null) { 930 return false; 931 } 932 try { 933 return mService.hasBindAppWidgetPermission(packageName, UserHandle.myUserId()); 934 } catch (RemoteException e) { 935 throw e.rethrowFromSystemServer(); 936 } 937 } 938 939 /** 940 * Changes any user-granted permission for the given package to bind app widgets 941 * 942 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 943 * 944 * @param packageName The package whose permission is being changed 945 * @param permission Whether to give the package permission to bind widgets 946 * 947 * @hide 948 */ 949 public void setBindAppWidgetPermission(String packageName, boolean permission) { 950 if (mService == null) { 951 return; 952 } 953 setBindAppWidgetPermission(packageName, UserHandle.myUserId(), permission); 954 } 955 956 /** 957 * Changes any user-granted permission for the given package to bind app widgets 958 * 959 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 960 * 961 * @param packageName The package whose permission is being changed 962 * @param userId The user under which the package is running. 963 * @param permission Whether to give the package permission to bind widgets 964 * 965 * @hide 966 */ 967 public void setBindAppWidgetPermission(String packageName, int userId, boolean permission) { 968 if (mService == null) { 969 return; 970 } 971 try { 972 mService.setBindAppWidgetPermission(packageName, userId, permission); 973 } catch (RemoteException e) { 974 throw e.rethrowFromSystemServer(); 975 } 976 } 977 978 /** 979 * Binds the RemoteViewsService for a given appWidgetId and intent. 980 * 981 * The appWidgetId specified must already be bound to the calling AppWidgetHost via 982 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}. 983 * 984 * @param packageName The package from which the binding is requested. 985 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService. 986 * @param intent The intent of the service which will be providing the data to the 987 * RemoteViewsAdapter. 988 * @param connection The callback interface to be notified when a connection is made or lost. 989 * @hide 990 */ 991 public void bindRemoteViewsService(String packageName, int appWidgetId, Intent intent, 992 IBinder connection) { 993 if (mService == null) { 994 return; 995 } 996 try { 997 mService.bindRemoteViewsService(packageName, appWidgetId, intent, connection); 998 } catch (RemoteException e) { 999 throw e.rethrowFromSystemServer(); 1000 } 1001 } 1002 1003 /** 1004 * Unbinds the RemoteViewsService for a given appWidgetId and intent. 1005 * 1006 * The appWidgetId specified muse already be bound to the calling AppWidgetHost via 1007 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}. 1008 * 1009 * @param packageName The package from which the binding is requested. 1010 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService. 1011 * @param intent The intent of the service which will be providing the data to the 1012 * RemoteViewsAdapter. 1013 * @hide 1014 */ 1015 public void unbindRemoteViewsService(String packageName, int appWidgetId, Intent intent) { 1016 if (mService == null) { 1017 return; 1018 } 1019 try { 1020 mService.unbindRemoteViewsService(packageName, appWidgetId, intent); 1021 } catch (RemoteException e) { 1022 throw e.rethrowFromSystemServer(); 1023 } 1024 } 1025 1026 /** 1027 * Get the list of appWidgetIds that have been bound to the given AppWidget 1028 * provider. 1029 * 1030 * @param provider The {@link android.content.BroadcastReceiver} that is the 1031 * AppWidget provider to find appWidgetIds for. 1032 */ 1033 public int[] getAppWidgetIds(ComponentName provider) { 1034 if (mService == null) { 1035 return new int[0]; 1036 } 1037 try { 1038 return mService.getAppWidgetIds(provider); 1039 } catch (RemoteException e) { 1040 throw e.rethrowFromSystemServer(); 1041 } 1042 } 1043 1044 /** 1045 * @hide 1046 */ 1047 public boolean isBoundWidgetPackage(String packageName, int userId) { 1048 if (mService == null) { 1049 return false; 1050 } 1051 try { 1052 return mService.isBoundWidgetPackage(packageName, userId); 1053 } catch (RemoteException e) { 1054 throw e.rethrowFromSystemServer(); 1055 } 1056 } 1057 1058 private boolean bindAppWidgetIdIfAllowed(int appWidgetId, int profileId, 1059 ComponentName provider, Bundle options) { 1060 if (mService == null) { 1061 return false; 1062 } 1063 try { 1064 return mService.bindAppWidgetId(mPackageName, appWidgetId, 1065 profileId, provider, options); 1066 } catch (RemoteException e) { 1067 throw e.rethrowFromSystemServer(); 1068 } 1069 } 1070 1071 private void convertSizesToPixels(AppWidgetProviderInfo info) { 1072 // Converting complex to dp. 1073 info.minWidth = TypedValue.complexToDimensionPixelSize(info.minWidth, 1074 mDisplayMetrics); 1075 info.minHeight = TypedValue.complexToDimensionPixelSize(info.minHeight, 1076 mDisplayMetrics); 1077 info.minResizeWidth = TypedValue.complexToDimensionPixelSize(info.minResizeWidth, 1078 mDisplayMetrics); 1079 info.minResizeHeight = TypedValue.complexToDimensionPixelSize(info.minResizeHeight, 1080 mDisplayMetrics); 1081 } 1082} 1083