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