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