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