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.content.ComponentName; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.os.Bundle; 23 import android.os.IBinder; 24 import android.os.RemoteException; 25 import android.os.ServiceManager; 26 import android.os.UserHandle; 27 import android.util.DisplayMetrics; 28 import android.util.TypedValue; 29 import android.widget.RemoteViews; 30 31 import com.android.internal.appwidget.IAppWidgetService; 32 33 import java.lang.ref.WeakReference; 34 import java.util.List; 35 import java.util.WeakHashMap; 36 37 /** 38 * Updates AppWidget state; gets information about installed AppWidget providers and other 39 * AppWidget related state. 40 * 41 * <div class="special reference"> 42 * <h3>Developer Guides</h3> 43 * <p>For more information about creating app widgets, read the 44 * <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a> developer guide.</p> 45 * </div> 46 */ 47 public class AppWidgetManager { 48 static final String TAG = "AppWidgetManager"; 49 50 /** 51 * Send this from your {@link AppWidgetHost} activity when you want to pick an AppWidget to display. 52 * The AppWidget picker activity will be launched. 53 * <p> 54 * You must supply the following extras: 55 * <table> 56 * <tr> 57 * <td>{@link #EXTRA_APPWIDGET_ID}</td> 58 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider 59 * once the user has selected one.</td> 60 * </tr> 61 * </table> 62 * 63 * <p> 64 * The system will respond with an onActivityResult call with the following extras in 65 * the intent: 66 * <table> 67 * <tr> 68 * <td>{@link #EXTRA_APPWIDGET_ID}</td> 69 * <td>The appWidgetId that you supplied in the original intent.</td> 70 * </tr> 71 * </table> 72 * <p> 73 * When you receive the result from the AppWidget pick activity, if the resultCode is 74 * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected. You should then 75 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its configuration 76 * activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete 77 * the appWidgetId. 78 * 79 * @see #ACTION_APPWIDGET_CONFIGURE 80 */ 81 public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK"; 82 83 /** 84 * Similar to ACTION_APPWIDGET_PICK, but used from keyguard 85 * @hide 86 */ 87 public static final String 88 ACTION_KEYGUARD_APPWIDGET_PICK = "android.appwidget.action.KEYGUARD_APPWIDGET_PICK"; 89 90 /** 91 * Send this from your {@link AppWidgetHost} activity when you want to bind an AppWidget to 92 * display and bindAppWidgetIdIfAllowed returns false. 93 * <p> 94 * You must supply the following extras: 95 * <table> 96 * <tr> 97 * <td>{@link #EXTRA_APPWIDGET_ID}</td> 98 * <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider 99 * you provide.</td> 100 * </tr> 101 * <tr> 102 * <td>{@link #EXTRA_APPWIDGET_PROVIDER}</td> 103 * <td>The BroadcastReceiver that will be the AppWidget provider for this AppWidget. 104 * </td> 105 * </tr> 106 * </table> 107 * 108 * <p> 109 * The system will respond with an onActivityResult call with the following extras in 110 * the intent: 111 * <table> 112 * <tr> 113 * <td>{@link #EXTRA_APPWIDGET_ID}</td> 114 * <td>The appWidgetId that you supplied in the original intent.</td> 115 * </tr> 116 * </table> 117 * <p> 118 * When you receive the result from the AppWidget bind activity, if the resultCode is 119 * {@link android.app.Activity#RESULT_OK}, the AppWidget has been bound. You should then 120 * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its 121 * configuration activity. If {@link android.app.Activity#RESULT_CANCELED} is returned, you 122 * should delete 123 * the appWidgetId. 124 * 125 * @see #ACTION_APPWIDGET_CONFIGURE 126 * 127 */ 128 public static final String ACTION_APPWIDGET_BIND = "android.appwidget.action.APPWIDGET_BIND"; 129 130 /** 131 * Sent when it is time to configure your AppWidget while it is being added to a host. 132 * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity 133 * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo meta-data}. 134 * 135 * <p> 136 * The intent will contain the following extras: 137 * <table> 138 * <tr> 139 * <td>{@link #EXTRA_APPWIDGET_ID}</td> 140 * <td>The appWidgetId to configure.</td> 141 * </tr> 142 * </table> 143 * 144 * <p>If you return {@link android.app.Activity#RESULT_OK} using 145 * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added, 146 * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget. 147 * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add 148 * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} broadcast. 149 */ 150 public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE"; 151 152 /** 153 * An intent extra that contains one appWidgetId. 154 * <p> 155 * The value will be an int that can be retrieved like this: 156 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID} 157 */ 158 public static final String EXTRA_APPWIDGET_ID = "appWidgetId"; 159 160 /** 161 * A bundle extra that contains the lower bound on the current width, in dips, of a widget instance. 162 */ 163 public static final String OPTION_APPWIDGET_MIN_WIDTH = "appWidgetMinWidth"; 164 165 /** 166 * A bundle extra that contains the lower bound on the current height, in dips, of a widget instance. 167 */ 168 public static final String OPTION_APPWIDGET_MIN_HEIGHT = "appWidgetMinHeight"; 169 170 /** 171 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. 172 */ 173 public static final String OPTION_APPWIDGET_MAX_WIDTH = "appWidgetMaxWidth"; 174 175 /** 176 * A bundle extra that contains the upper bound on the current width, in dips, of a widget instance. 177 */ 178 public static final String OPTION_APPWIDGET_MAX_HEIGHT = "appWidgetMaxHeight"; 179 180 /** 181 * A bundle extra that hints to the AppWidgetProvider the category of host that owns this 182 * this widget. Can have the value {@link 183 * AppWidgetProviderInfo#WIDGET_CATEGORY_HOME_SCREEN} or {@link 184 * AppWidgetProviderInfo#WIDGET_CATEGORY_KEYGUARD}. 185 */ 186 public static final String OPTION_APPWIDGET_HOST_CATEGORY = "appWidgetCategory"; 187 188 /** 189 * An intent extra which points to a bundle of extra information for a particular widget id. 190 * In particular this bundle can contain EXTRA_APPWIDGET_WIDTH and EXTRA_APPWIDGET_HEIGHT. 191 */ 192 public static final String EXTRA_APPWIDGET_OPTIONS = "appWidgetOptions"; 193 194 /** 195 * An intent extra that contains multiple appWidgetIds. 196 * <p> 197 * The value will be an int array that can be retrieved like this: 198 * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS} 199 */ 200 public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds"; 201 202 /** 203 * An intent extra that contains the component name of a AppWidget provider. 204 * <p> 205 * The value will be an ComponentName. 206 */ 207 public static final String EXTRA_APPWIDGET_PROVIDER = "appWidgetProvider"; 208 209 /** 210 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of 211 * {@link AppWidgetProviderInfo} objects to mix in to the list of AppWidgets that are 212 * installed. (This is how the launcher shows the search widget). 213 */ 214 public static final String EXTRA_CUSTOM_INFO = "customInfo"; 215 216 /** 217 * An intent extra to pass to the AppWidget picker containing a {@link java.util.List} of 218 * {@link android.os.Bundle} objects to mix in to the list of AppWidgets that are 219 * installed. It will be added to the extras object on the {@link android.content.Intent} 220 * that is returned from the picker activity. 221 * 222 * {@more} 223 */ 224 public static final String EXTRA_CUSTOM_EXTRAS = "customExtras"; 225 226 /** 227 * An intent extra to pass to the AppWidget picker which allows the picker to filter 228 * the list based on the {@link AppWidgetProviderInfo#widgetCategory}. 229 * 230 * @hide 231 */ 232 public static final String EXTRA_CATEGORY_FILTER = "categoryFilter"; 233 234 /** 235 * An intent extra to pass to the AppWidget picker to specify whether or not to sort 236 * the list of caller-specified extra AppWidgets along with the rest of the AppWidgets 237 * @hide 238 */ 239 public static final String EXTRA_CUSTOM_SORT = "customSort"; 240 241 /** 242 * A sentinel value that the AppWidget manager will never return as a appWidgetId. 243 */ 244 public static final int INVALID_APPWIDGET_ID = 0; 245 246 /** 247 * Sent when it is time to update your AppWidget. 248 * 249 * <p>This may be sent in response to a new instance for this AppWidget provider having 250 * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval} 251 * having lapsed, or the system booting. 252 * 253 * <p> 254 * The intent will contain the following extras: 255 * <table> 256 * <tr> 257 * <td>{@link #EXTRA_APPWIDGET_IDS}</td> 258 * <td>The appWidgetIds to update. This may be all of the AppWidgets created for this 259 * provider, or just a subset. The system tries to send updates for as few AppWidget 260 * instances as possible.</td> 261 * </tr> 262 * </table> 263 * 264 * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 265 */ 266 public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; 267 268 /** 269 * Sent when the custom extras for an AppWidget change. 270 * 271 * @see AppWidgetProvider#onAppWidgetOptionsChanged 272 * AppWidgetProvider.onAppWidgetOptionsChanged(Context context, 273 * AppWidgetManager appWidgetManager, int appWidgetId, Bundle newExtras) 274 */ 275 public static final String ACTION_APPWIDGET_OPTIONS_CHANGED = "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS"; 276 277 /** 278 * Sent when an instance of an AppWidget is deleted from its host. 279 * 280 * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds) 281 */ 282 public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"; 283 284 /** 285 * Sent when an instance of an AppWidget is removed from the last host. 286 * 287 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context) 288 */ 289 public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"; 290 291 /** 292 * Sent when an instance of an AppWidget is added to a host for the first time. 293 * This broadcast is sent at boot time if there is a AppWidgetHost installed with 294 * an instance for this provider. 295 * 296 * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context) 297 */ 298 public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED"; 299 300 /** 301 * Field for the manifest meta-data tag. 302 * 303 * @see AppWidgetProviderInfo 304 */ 305 public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider"; 306 307 static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache = 308 new WeakHashMap<Context, WeakReference<AppWidgetManager>>(); 309 static IAppWidgetService sService; 310 311 Context mContext; 312 313 private DisplayMetrics mDisplayMetrics; 314 315 /** 316 * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context 317 * Context} object. 318 */ getInstance(Context context)319 public static AppWidgetManager getInstance(Context context) { 320 synchronized (sManagerCache) { 321 if (sService == null) { 322 IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE); 323 sService = IAppWidgetService.Stub.asInterface(b); 324 } 325 326 WeakReference<AppWidgetManager> ref = sManagerCache.get(context); 327 AppWidgetManager result = null; 328 if (ref != null) { 329 result = ref.get(); 330 } 331 if (result == null) { 332 result = new AppWidgetManager(context); 333 sManagerCache.put(context, new WeakReference<AppWidgetManager>(result)); 334 } 335 return result; 336 } 337 } 338 AppWidgetManager(Context context)339 private AppWidgetManager(Context context) { 340 mContext = context; 341 mDisplayMetrics = context.getResources().getDisplayMetrics(); 342 } 343 344 /** 345 * Set the RemoteViews to use for the specified appWidgetIds. 346 * 347 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should 348 * contain a complete representation of the widget. For performing partial widget updates, see 349 * {@link #partiallyUpdateAppWidget(int[], RemoteViews)}. 350 * 351 * <p> 352 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 353 * and outside of the handler. 354 * This method will only work when called from the uid that owns the AppWidget provider. 355 * 356 * <p> 357 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to 358 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. 359 * 360 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. 361 * @param views The RemoteViews object to show. 362 */ updateAppWidget(int[] appWidgetIds, RemoteViews views)363 public void updateAppWidget(int[] appWidgetIds, RemoteViews views) { 364 try { 365 sService.updateAppWidgetIds(appWidgetIds, views); 366 } 367 catch (RemoteException e) { 368 throw new RuntimeException("system server dead?", e); 369 } 370 } 371 372 /** 373 * Update the extras for a given widget instance. 374 * 375 * The extras can be used to embed additional information about this widget to be accessed 376 * by the associated widget's AppWidgetProvider. 377 * 378 * @see #getAppWidgetOptions(int) 379 * 380 * @param appWidgetId The AppWidget instances for which to set the RemoteViews. 381 * @param options The options to associate with this widget 382 */ updateAppWidgetOptions(int appWidgetId, Bundle options)383 public void updateAppWidgetOptions(int appWidgetId, Bundle options) { 384 try { 385 sService.updateAppWidgetOptions(appWidgetId, options); 386 } 387 catch (RemoteException e) { 388 throw new RuntimeException("system server dead?", e); 389 } 390 } 391 392 /** 393 * Get the extras associated with a given widget instance. 394 * 395 * The extras can be used to embed additional information about this widget to be accessed 396 * by the associated widget's AppWidgetProvider. 397 * 398 * @see #updateAppWidgetOptions(int, Bundle) 399 * 400 * @param appWidgetId The AppWidget instances for which to set the RemoteViews. 401 * @return The options associated with the given widget instance. 402 */ getAppWidgetOptions(int appWidgetId)403 public Bundle getAppWidgetOptions(int appWidgetId) { 404 try { 405 return sService.getAppWidgetOptions(appWidgetId); 406 } 407 catch (RemoteException e) { 408 throw new RuntimeException("system server dead?", e); 409 } 410 } 411 412 /** 413 * Set the RemoteViews to use for the specified appWidgetId. 414 * 415 * Note that the RemoteViews parameter will be cached by the AppWidgetService, and hence should 416 * contain a complete representation of the widget. For performing partial widget updates, see 417 * {@link #partiallyUpdateAppWidget(int, RemoteViews)}. 418 * 419 * <p> 420 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 421 * and outside of the handler. 422 * This method will only work when called from the uid that owns the AppWidget provider. 423 * 424 * <p> 425 * The total Bitmap memory used by the RemoteViews object cannot exceed that required to 426 * fill the screen 1.5 times, ie. (screen width x screen height x 4 x 1.5) bytes. 427 * 428 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 429 * @param views The RemoteViews object to show. 430 */ updateAppWidget(int appWidgetId, RemoteViews views)431 public void updateAppWidget(int appWidgetId, RemoteViews views) { 432 updateAppWidget(new int[] { appWidgetId }, views); 433 } 434 435 /** 436 * Perform an incremental update or command on the widget(s) specified by appWidgetIds. 437 * 438 * This update differs from {@link #updateAppWidget(int[], RemoteViews)} in that the 439 * RemoteViews object which is passed is understood to be an incomplete representation of the 440 * widget, and hence does not replace the cached representation of the widget. As of API 441 * level 17, the new properties set within the views objects will be appended to the cached 442 * representation of the widget, and hence will persist. 443 * 444 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, 445 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. 446 * 447 * <p> 448 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 449 * and outside of the handler. 450 * This method will only work when called from the uid that owns the AppWidget provider. 451 * 452 * <p> 453 * This method will be ignored if a widget has not received a full update via 454 * {@link #updateAppWidget(int[], RemoteViews)}. 455 * 456 * @param appWidgetIds The AppWidget instances for which to set the RemoteViews. 457 * @param views The RemoteViews object containing the incremental update / command. 458 */ partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views)459 public void partiallyUpdateAppWidget(int[] appWidgetIds, RemoteViews views) { 460 try { 461 sService.partiallyUpdateAppWidgetIds(appWidgetIds, views); 462 } catch (RemoteException e) { 463 throw new RuntimeException("system server dead?", e); 464 } 465 } 466 467 /** 468 * Perform an incremental update or command on the widget specified by appWidgetId. 469 * 470 * This update differs from {@link #updateAppWidget(int, RemoteViews)} in that the RemoteViews 471 * object which is passed is understood to be an incomplete representation of the widget, and 472 * hence is not cached by the AppWidgetService. Note that because these updates are not cached, 473 * any state that they modify that is not restored by restoreInstanceState will not persist in 474 * the case that the widgets are restored using the cached version in AppWidgetService. 475 * 476 * Use with {@link RemoteViews#showNext(int)}, {@link RemoteViews#showPrevious(int)}, 477 * {@link RemoteViews#setScrollPosition(int, int)} and similar commands. 478 * 479 * <p> 480 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 481 * and outside of the handler. 482 * This method will only work when called from the uid that owns the AppWidget provider. 483 * 484 * <p> 485 * This method will be ignored if a widget has not received a full update via 486 * {@link #updateAppWidget(int[], RemoteViews)}. 487 * 488 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 489 * @param views The RemoteViews object containing the incremental update / command. 490 */ partiallyUpdateAppWidget(int appWidgetId, RemoteViews views)491 public void partiallyUpdateAppWidget(int appWidgetId, RemoteViews views) { 492 partiallyUpdateAppWidget(new int[] { appWidgetId }, views); 493 } 494 495 /** 496 * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider. 497 * 498 * <p> 499 * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast, 500 * and outside of the handler. 501 * This method will only work when called from the uid that owns the AppWidget provider. 502 * 503 * @param provider The {@link ComponentName} for the {@link 504 * android.content.BroadcastReceiver BroadcastReceiver} provider 505 * for your AppWidget. 506 * @param views The RemoteViews object to show. 507 */ updateAppWidget(ComponentName provider, RemoteViews views)508 public void updateAppWidget(ComponentName provider, RemoteViews views) { 509 try { 510 sService.updateAppWidgetProvider(provider, views); 511 } 512 catch (RemoteException e) { 513 throw new RuntimeException("system server dead?", e); 514 } 515 } 516 517 /** 518 * Notifies the specified collection view in all the specified AppWidget instances 519 * to invalidate their currently data. 520 * 521 * @param appWidgetIds The AppWidget instances for which to notify of view data changes. 522 * @param viewId The collection view id. 523 */ notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId)524 public void notifyAppWidgetViewDataChanged(int[] appWidgetIds, int viewId) { 525 try { 526 sService.notifyAppWidgetViewDataChanged(appWidgetIds, viewId); 527 } 528 catch (RemoteException e) { 529 throw new RuntimeException("system server dead?", e); 530 } 531 } 532 533 /** 534 * Notifies the specified collection view in all the specified AppWidget instance 535 * to invalidate it's currently data. 536 * 537 * @param appWidgetId The AppWidget instance for which to notify of view data changes. 538 * @param viewId The collection view id. 539 */ notifyAppWidgetViewDataChanged(int appWidgetId, int viewId)540 public void notifyAppWidgetViewDataChanged(int appWidgetId, int viewId) { 541 notifyAppWidgetViewDataChanged(new int[] { appWidgetId }, viewId); 542 } 543 544 /** 545 * Return a list of the AppWidget providers that are currently installed. 546 */ getInstalledProviders()547 public List<AppWidgetProviderInfo> getInstalledProviders() { 548 return getInstalledProviders(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN); 549 } 550 551 /** 552 * Return a list of the AppWidget providers that are currently installed. 553 * 554 * @param categoryFilter Will only return providers which register as any of the specified 555 * specified categories. See {@link AppWidgetProviderInfo#widgetCategory}. 556 * @hide 557 */ getInstalledProviders(int categoryFilter)558 public List<AppWidgetProviderInfo> getInstalledProviders(int categoryFilter) { 559 try { 560 List<AppWidgetProviderInfo> providers = sService.getInstalledProviders(categoryFilter); 561 for (AppWidgetProviderInfo info : providers) { 562 // Converting complex to dp. 563 info.minWidth = 564 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics); 565 info.minHeight = 566 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics); 567 info.minResizeWidth = 568 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics); 569 info.minResizeHeight = 570 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics); 571 } 572 return providers; 573 } 574 catch (RemoteException e) { 575 throw new RuntimeException("system server dead?", e); 576 } 577 } 578 579 /** 580 * Get the available info about the AppWidget. 581 * 582 * @return A appWidgetId. If the appWidgetId has not been bound to a provider yet, or 583 * you don't have access to that appWidgetId, null is returned. 584 */ getAppWidgetInfo(int appWidgetId)585 public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) { 586 try { 587 AppWidgetProviderInfo info = sService.getAppWidgetInfo(appWidgetId); 588 if (info != null) { 589 // Converting complex to dp. 590 info.minWidth = 591 TypedValue.complexToDimensionPixelSize(info.minWidth, mDisplayMetrics); 592 info.minHeight = 593 TypedValue.complexToDimensionPixelSize(info.minHeight, mDisplayMetrics); 594 info.minResizeWidth = 595 TypedValue.complexToDimensionPixelSize(info.minResizeWidth, mDisplayMetrics); 596 info.minResizeHeight = 597 TypedValue.complexToDimensionPixelSize(info.minResizeHeight, mDisplayMetrics); 598 } 599 return info; 600 } 601 catch (RemoteException e) { 602 throw new RuntimeException("system server dead?", e); 603 } 604 } 605 606 /** 607 * Set the component for a given appWidgetId. 608 * 609 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 610 * widgets always for your component. This method is used by the AppWidget picker and 611 * should not be used by other apps. 612 * 613 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 614 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 615 * provider for this AppWidget. 616 * @hide 617 */ bindAppWidgetId(int appWidgetId, ComponentName provider)618 public void bindAppWidgetId(int appWidgetId, ComponentName provider) { 619 try { 620 sService.bindAppWidgetId(appWidgetId, provider, null); 621 } 622 catch (RemoteException e) { 623 throw new RuntimeException("system server dead?", e); 624 } 625 } 626 627 /** 628 * Set the component for a given appWidgetId. 629 * 630 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 631 * widgets always for your component. This method is used by the AppWidget picker and 632 * should not be used by other apps. 633 * 634 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 635 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 636 * provider for this AppWidget. 637 * @param options Bundle containing options for the AppWidget. See also 638 * {@link #updateAppWidgetOptions(int, Bundle)} 639 * 640 * @hide 641 */ bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options)642 public void bindAppWidgetId(int appWidgetId, ComponentName provider, Bundle options) { 643 try { 644 sService.bindAppWidgetId(appWidgetId, provider, options); 645 } 646 catch (RemoteException e) { 647 throw new RuntimeException("system server dead?", e); 648 } 649 } 650 651 /** 652 * Set the component for a given appWidgetId. 653 * 654 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 655 * widgets always for your component. Should be used by apps that host widgets; if this 656 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to 657 * bind 658 * 659 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 660 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 661 * provider for this AppWidget. 662 * @return true if this component has permission to bind the AppWidget 663 */ bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider)664 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider) { 665 if (mContext == null) { 666 return false; 667 } 668 try { 669 return sService.bindAppWidgetIdIfAllowed( 670 mContext.getPackageName(), appWidgetId, provider, null); 671 } 672 catch (RemoteException e) { 673 throw new RuntimeException("system server dead?", e); 674 } 675 } 676 677 /** 678 * Set the component for a given appWidgetId. 679 * 680 * <p class="note">You need the BIND_APPWIDGET permission or the user must have enabled binding 681 * widgets always for your component. Should be used by apps that host widgets; if this 682 * method returns false, call {@link #ACTION_APPWIDGET_BIND} to request permission to 683 * bind 684 * 685 * @param appWidgetId The AppWidget instance for which to set the RemoteViews. 686 * @param provider The {@link android.content.BroadcastReceiver} that will be the AppWidget 687 * provider for this AppWidget. 688 * @param options Bundle containing options for the AppWidget. See also 689 * {@link #updateAppWidgetOptions(int, Bundle)} 690 * 691 * @return true if this component has permission to bind the AppWidget 692 */ bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider, Bundle options)693 public boolean bindAppWidgetIdIfAllowed(int appWidgetId, ComponentName provider, 694 Bundle options) { 695 if (mContext == null) { 696 return false; 697 } 698 try { 699 return sService.bindAppWidgetIdIfAllowed( 700 mContext.getPackageName(), appWidgetId, provider, options); 701 } 702 catch (RemoteException e) { 703 throw new RuntimeException("system server dead?", e); 704 } 705 } 706 707 /** 708 * Query if a given package was granted permission by the user to bind app widgets 709 * 710 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 711 * 712 * @param packageName The package for which the permission is being queried 713 * @return true if the package was granted permission by the user to bind app widgets 714 * @hide 715 */ hasBindAppWidgetPermission(String packageName)716 public boolean hasBindAppWidgetPermission(String packageName) { 717 try { 718 return sService.hasBindAppWidgetPermission(packageName); 719 } 720 catch (RemoteException e) { 721 throw new RuntimeException("system server dead?", e); 722 } 723 } 724 725 /** 726 * Changes any user-granted permission for the given package to bind app widgets 727 * 728 * <p class="note">You need the MODIFY_APPWIDGET_BIND_PERMISSIONS permission 729 * 730 * @param provider The package whose permission is being changed 731 * @param permission Whether to give the package permission to bind widgets 732 * @hide 733 */ setBindAppWidgetPermission(String packageName, boolean permission)734 public void setBindAppWidgetPermission(String packageName, boolean permission) { 735 try { 736 sService.setBindAppWidgetPermission(packageName, permission); 737 } 738 catch (RemoteException e) { 739 throw new RuntimeException("system server dead?", e); 740 } 741 } 742 743 /** 744 * Binds the RemoteViewsService for a given appWidgetId and intent. 745 * 746 * The appWidgetId specified must already be bound to the calling AppWidgetHost via 747 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}. 748 * 749 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService. 750 * @param intent The intent of the service which will be providing the data to the 751 * RemoteViewsAdapter. 752 * @param connection The callback interface to be notified when a connection is made or lost. 753 * @param userHandle The user to bind to. 754 * @hide 755 */ bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection, UserHandle userHandle)756 public void bindRemoteViewsService(int appWidgetId, Intent intent, IBinder connection, 757 UserHandle userHandle) { 758 try { 759 sService.bindRemoteViewsService(appWidgetId, intent, connection, 760 userHandle.getIdentifier()); 761 } 762 catch (RemoteException e) { 763 throw new RuntimeException("system server dead?", e); 764 } 765 } 766 767 /** 768 * Unbinds the RemoteViewsService for a given appWidgetId and intent. 769 * 770 * The appWidgetId specified muse already be bound to the calling AppWidgetHost via 771 * {@link android.appwidget.AppWidgetManager#bindAppWidgetId AppWidgetManager.bindAppWidgetId()}. 772 * 773 * @param appWidgetId The AppWidget instance for which to bind the RemoteViewsService. 774 * @param intent The intent of the service which will be providing the data to the 775 * RemoteViewsAdapter. 776 * @param userHandle The user to unbind from. 777 * @hide 778 */ unbindRemoteViewsService(int appWidgetId, Intent intent, UserHandle userHandle)779 public void unbindRemoteViewsService(int appWidgetId, Intent intent, UserHandle userHandle) { 780 try { 781 sService.unbindRemoteViewsService(appWidgetId, intent, userHandle.getIdentifier()); 782 } 783 catch (RemoteException e) { 784 throw new RuntimeException("system server dead?", e); 785 } 786 } 787 788 /** 789 * Get the list of appWidgetIds that have been bound to the given AppWidget 790 * provider. 791 * 792 * @param provider The {@link android.content.BroadcastReceiver} that is the 793 * AppWidget provider to find appWidgetIds for. 794 */ getAppWidgetIds(ComponentName provider)795 public int[] getAppWidgetIds(ComponentName provider) { 796 try { 797 return sService.getAppWidgetIds(provider); 798 } 799 catch (RemoteException e) { 800 throw new RuntimeException("system server dead?", e); 801 } 802 } 803 } 804 805