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