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