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