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