1/* 2 * Copyright (C) 2007 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.preference; 18 19import android.app.Activity; 20import android.content.Context; 21import android.content.DialogInterface; 22import android.content.Intent; 23import android.content.SharedPreferences; 24import android.content.pm.ActivityInfo; 25import android.content.pm.PackageManager; 26import android.content.pm.ResolveInfo; 27import android.content.pm.PackageManager.NameNotFoundException; 28import android.content.res.XmlResourceParser; 29import android.os.Bundle; 30import android.util.Log; 31 32import java.util.ArrayList; 33import java.util.HashSet; 34import java.util.List; 35 36/** 37 * Used to help create {@link Preference} hierarchies 38 * from activities or XML. 39 * <p> 40 * In most cases, clients should use 41 * {@link PreferenceActivity#addPreferencesFromIntent} or 42 * {@link PreferenceActivity#addPreferencesFromResource(int)}. 43 * 44 * @see PreferenceActivity 45 */ 46public class PreferenceManager { 47 48 private static final String TAG = "PreferenceManager"; 49 50 /** 51 * The Activity meta-data key for its XML preference hierarchy. 52 */ 53 public static final String METADATA_KEY_PREFERENCES = "android.preference"; 54 55 public static final String KEY_HAS_SET_DEFAULT_VALUES = "_has_set_default_values"; 56 57 /** 58 * @see #getActivity() 59 */ 60 private Activity mActivity; 61 62 /** 63 * Fragment that owns this instance. 64 */ 65 private PreferenceFragment mFragment; 66 67 /** 68 * The context to use. This should always be set. 69 * 70 * @see #mActivity 71 */ 72 private Context mContext; 73 74 /** 75 * The counter for unique IDs. 76 */ 77 private long mNextId = 0; 78 79 /** 80 * The counter for unique request codes. 81 */ 82 private int mNextRequestCode; 83 84 /** 85 * Cached shared preferences. 86 */ 87 private SharedPreferences mSharedPreferences; 88 89 /** 90 * If in no-commit mode, the shared editor to give out (which will be 91 * committed when exiting no-commit mode). 92 */ 93 private SharedPreferences.Editor mEditor; 94 95 /** 96 * Blocks commits from happening on the shared editor. This is used when 97 * inflating the hierarchy. Do not set this directly, use {@link #setNoCommit(boolean)} 98 */ 99 private boolean mNoCommit; 100 101 /** 102 * The SharedPreferences name that will be used for all {@link Preference}s 103 * managed by this instance. 104 */ 105 private String mSharedPreferencesName; 106 107 /** 108 * The SharedPreferences mode that will be used for all {@link Preference}s 109 * managed by this instance. 110 */ 111 private int mSharedPreferencesMode; 112 113 /** 114 * The {@link PreferenceScreen} at the root of the preference hierarchy. 115 */ 116 private PreferenceScreen mPreferenceScreen; 117 118 /** 119 * List of activity result listeners. 120 */ 121 private List<OnActivityResultListener> mActivityResultListeners; 122 123 /** 124 * List of activity stop listeners. 125 */ 126 private List<OnActivityStopListener> mActivityStopListeners; 127 128 /** 129 * List of activity destroy listeners. 130 */ 131 private List<OnActivityDestroyListener> mActivityDestroyListeners; 132 133 /** 134 * List of dialogs that should be dismissed when we receive onNewIntent in 135 * our PreferenceActivity. 136 */ 137 private List<DialogInterface> mPreferencesScreens; 138 139 private OnPreferenceTreeClickListener mOnPreferenceTreeClickListener; 140 141 PreferenceManager(Activity activity, int firstRequestCode) { 142 mActivity = activity; 143 mNextRequestCode = firstRequestCode; 144 145 init(activity); 146 } 147 148 /** 149 * This constructor should ONLY be used when getting default values from 150 * an XML preference hierarchy. 151 * <p> 152 * The {@link PreferenceManager#PreferenceManager(Activity)} 153 * should be used ANY time a preference will be displayed, since some preference 154 * types need an Activity for managed queries. 155 */ 156 private PreferenceManager(Context context) { 157 init(context); 158 } 159 160 private void init(Context context) { 161 mContext = context; 162 163 setSharedPreferencesName(getDefaultSharedPreferencesName(context)); 164 } 165 166 /** 167 * Sets the owning preference fragment 168 */ 169 void setFragment(PreferenceFragment fragment) { 170 mFragment = fragment; 171 } 172 173 /** 174 * Returns the owning preference fragment, if any. 175 */ 176 PreferenceFragment getFragment() { 177 return mFragment; 178 } 179 180 /** 181 * Returns a list of {@link Activity} (indirectly) that match a given 182 * {@link Intent}. 183 * 184 * @param queryIntent The Intent to match. 185 * @return The list of {@link ResolveInfo} that point to the matched 186 * activities. 187 */ 188 private List<ResolveInfo> queryIntentActivities(Intent queryIntent) { 189 return mContext.getPackageManager().queryIntentActivities(queryIntent, 190 PackageManager.GET_META_DATA); 191 } 192 193 /** 194 * Inflates a preference hierarchy from the preference hierarchies of 195 * {@link Activity Activities} that match the given {@link Intent}. An 196 * {@link Activity} defines its preference hierarchy with meta-data using 197 * the {@link #METADATA_KEY_PREFERENCES} key. 198 * <p> 199 * If a preference hierarchy is given, the new preference hierarchies will 200 * be merged in. 201 * 202 * @param queryIntent The intent to match activities. 203 * @param rootPreferences Optional existing hierarchy to merge the new 204 * hierarchies into. 205 * @return The root hierarchy (if one was not provided, the new hierarchy's 206 * root). 207 */ 208 PreferenceScreen inflateFromIntent(Intent queryIntent, PreferenceScreen rootPreferences) { 209 final List<ResolveInfo> activities = queryIntentActivities(queryIntent); 210 final HashSet<String> inflatedRes = new HashSet<String>(); 211 212 for (int i = activities.size() - 1; i >= 0; i--) { 213 final ActivityInfo activityInfo = activities.get(i).activityInfo; 214 final Bundle metaData = activityInfo.metaData; 215 216 if ((metaData == null) || !metaData.containsKey(METADATA_KEY_PREFERENCES)) { 217 continue; 218 } 219 220 // Need to concat the package with res ID since the same res ID 221 // can be re-used across contexts 222 final String uniqueResId = activityInfo.packageName + ":" 223 + activityInfo.metaData.getInt(METADATA_KEY_PREFERENCES); 224 225 if (!inflatedRes.contains(uniqueResId)) { 226 inflatedRes.add(uniqueResId); 227 228 final Context context; 229 try { 230 context = mContext.createPackageContext(activityInfo.packageName, 0); 231 } catch (NameNotFoundException e) { 232 Log.w(TAG, "Could not create context for " + activityInfo.packageName + ": " 233 + Log.getStackTraceString(e)); 234 continue; 235 } 236 237 final PreferenceInflater inflater = new PreferenceInflater(context, this); 238 final XmlResourceParser parser = activityInfo.loadXmlMetaData(context 239 .getPackageManager(), METADATA_KEY_PREFERENCES); 240 rootPreferences = (PreferenceScreen) inflater 241 .inflate(parser, rootPreferences, true); 242 parser.close(); 243 } 244 } 245 246 rootPreferences.onAttachedToHierarchy(this); 247 248 return rootPreferences; 249 } 250 251 /** 252 * Inflates a preference hierarchy from XML. If a preference hierarchy is 253 * given, the new preference hierarchies will be merged in. 254 * 255 * @param context The context of the resource. 256 * @param resId The resource ID of the XML to inflate. 257 * @param rootPreferences Optional existing hierarchy to merge the new 258 * hierarchies into. 259 * @return The root hierarchy (if one was not provided, the new hierarchy's 260 * root). 261 * @hide 262 */ 263 public PreferenceScreen inflateFromResource(Context context, int resId, 264 PreferenceScreen rootPreferences) { 265 // Block commits 266 setNoCommit(true); 267 268 final PreferenceInflater inflater = new PreferenceInflater(context, this); 269 rootPreferences = (PreferenceScreen) inflater.inflate(resId, rootPreferences, true); 270 rootPreferences.onAttachedToHierarchy(this); 271 272 // Unblock commits 273 setNoCommit(false); 274 275 return rootPreferences; 276 } 277 278 public PreferenceScreen createPreferenceScreen(Context context) { 279 final PreferenceScreen preferenceScreen = new PreferenceScreen(context, null); 280 preferenceScreen.onAttachedToHierarchy(this); 281 return preferenceScreen; 282 } 283 284 /** 285 * Called by a preference to get a unique ID in its hierarchy. 286 * 287 * @return A unique ID. 288 */ 289 long getNextId() { 290 synchronized (this) { 291 return mNextId++; 292 } 293 } 294 295 /** 296 * Returns the current name of the SharedPreferences file that preferences managed by 297 * this will use. 298 * 299 * @return The name that can be passed to {@link Context#getSharedPreferences(String, int)}. 300 * @see Context#getSharedPreferences(String, int) 301 */ 302 public String getSharedPreferencesName() { 303 return mSharedPreferencesName; 304 } 305 306 /** 307 * Sets the name of the SharedPreferences file that preferences managed by this 308 * will use. 309 * 310 * @param sharedPreferencesName The name of the SharedPreferences file. 311 * @see Context#getSharedPreferences(String, int) 312 */ 313 public void setSharedPreferencesName(String sharedPreferencesName) { 314 mSharedPreferencesName = sharedPreferencesName; 315 mSharedPreferences = null; 316 } 317 318 /** 319 * Returns the current mode of the SharedPreferences file that preferences managed by 320 * this will use. 321 * 322 * @return The mode that can be passed to {@link Context#getSharedPreferences(String, int)}. 323 * @see Context#getSharedPreferences(String, int) 324 */ 325 public int getSharedPreferencesMode() { 326 return mSharedPreferencesMode; 327 } 328 329 /** 330 * Sets the mode of the SharedPreferences file that preferences managed by this 331 * will use. 332 * 333 * @param sharedPreferencesMode The mode of the SharedPreferences file. 334 * @see Context#getSharedPreferences(String, int) 335 */ 336 public void setSharedPreferencesMode(int sharedPreferencesMode) { 337 mSharedPreferencesMode = sharedPreferencesMode; 338 mSharedPreferences = null; 339 } 340 341 /** 342 * Gets a SharedPreferences instance that preferences managed by this will 343 * use. 344 * 345 * @return A SharedPreferences instance pointing to the file that contains 346 * the values of preferences that are managed by this. 347 */ 348 public SharedPreferences getSharedPreferences() { 349 if (mSharedPreferences == null) { 350 mSharedPreferences = mContext.getSharedPreferences(mSharedPreferencesName, 351 mSharedPreferencesMode); 352 } 353 354 return mSharedPreferences; 355 } 356 357 /** 358 * Gets a SharedPreferences instance that points to the default file that is 359 * used by the preference framework in the given context. 360 * 361 * @param context The context of the preferences whose values are wanted. 362 * @return A SharedPreferences instance that can be used to retrieve and 363 * listen to values of the preferences. 364 */ 365 public static SharedPreferences getDefaultSharedPreferences(Context context) { 366 return context.getSharedPreferences(getDefaultSharedPreferencesName(context), 367 getDefaultSharedPreferencesMode()); 368 } 369 370 private static String getDefaultSharedPreferencesName(Context context) { 371 return context.getPackageName() + "_preferences"; 372 } 373 374 private static int getDefaultSharedPreferencesMode() { 375 return Context.MODE_PRIVATE; 376 } 377 378 /** 379 * Returns the root of the preference hierarchy managed by this class. 380 * 381 * @return The {@link PreferenceScreen} object that is at the root of the hierarchy. 382 */ 383 PreferenceScreen getPreferenceScreen() { 384 return mPreferenceScreen; 385 } 386 387 /** 388 * Sets the root of the preference hierarchy. 389 * 390 * @param preferenceScreen The root {@link PreferenceScreen} of the preference hierarchy. 391 * @return Whether the {@link PreferenceScreen} given is different than the previous. 392 */ 393 boolean setPreferences(PreferenceScreen preferenceScreen) { 394 if (preferenceScreen != mPreferenceScreen) { 395 mPreferenceScreen = preferenceScreen; 396 return true; 397 } 398 399 return false; 400 } 401 402 /** 403 * Finds a {@link Preference} based on its key. 404 * 405 * @param key The key of the preference to retrieve. 406 * @return The {@link Preference} with the key, or null. 407 * @see PreferenceGroup#findPreference(CharSequence) 408 */ 409 public Preference findPreference(CharSequence key) { 410 if (mPreferenceScreen == null) { 411 return null; 412 } 413 414 return mPreferenceScreen.findPreference(key); 415 } 416 417 /** 418 * Sets the default values from a preference hierarchy in XML. This should 419 * be called by the application's main activity. 420 * <p> 421 * If {@code readAgain} is false, this will only set the default values if this 422 * method has never been called in the past (or the 423 * {@link #KEY_HAS_SET_DEFAULT_VALUES} in the default value shared 424 * preferences file is false). To attempt to set the default values again 425 * bypassing this check, set {@code readAgain} to true. 426 * 427 * @param context The context of the shared preferences. 428 * @param resId The resource ID of the preference hierarchy XML file. 429 * @param readAgain Whether to re-read the default values. 430 * <p> 431 * Note: this will NOT reset preferences back to their default 432 * values. For that functionality, use 433 * {@link PreferenceManager#getDefaultSharedPreferences(Context)} 434 * and clear it followed by a call to this method with this 435 * parameter set to true. 436 */ 437 public static void setDefaultValues(Context context, int resId, boolean readAgain) { 438 439 // Use the default shared preferences name and mode 440 setDefaultValues(context, getDefaultSharedPreferencesName(context), 441 getDefaultSharedPreferencesMode(), resId, readAgain); 442 } 443 444 /** 445 * Similar to {@link #setDefaultValues(Context, int, boolean)} but allows 446 * the client to provide the filename and mode of the shared preferences 447 * file. 448 * 449 * @see #setDefaultValues(Context, int, boolean) 450 * @see #setSharedPreferencesName(String) 451 * @see #setSharedPreferencesMode(int) 452 */ 453 public static void setDefaultValues(Context context, String sharedPreferencesName, 454 int sharedPreferencesMode, int resId, boolean readAgain) { 455 final SharedPreferences defaultValueSp = context.getSharedPreferences( 456 KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE); 457 458 if (readAgain || !defaultValueSp.getBoolean(KEY_HAS_SET_DEFAULT_VALUES, false)) { 459 final PreferenceManager pm = new PreferenceManager(context); 460 pm.setSharedPreferencesName(sharedPreferencesName); 461 pm.setSharedPreferencesMode(sharedPreferencesMode); 462 pm.inflateFromResource(context, resId, null); 463 464 SharedPreferences.Editor editor = 465 defaultValueSp.edit().putBoolean(KEY_HAS_SET_DEFAULT_VALUES, true); 466 try { 467 editor.apply(); 468 } catch (AbstractMethodError unused) { 469 // The app injected its own pre-Gingerbread 470 // SharedPreferences.Editor implementation without 471 // an apply method. 472 editor.commit(); 473 } 474 } 475 } 476 477 /** 478 * Returns an editor to use when modifying the shared preferences. 479 * <p> 480 * Do NOT commit unless {@link #shouldCommit()} returns true. 481 * 482 * @return An editor to use to write to shared preferences. 483 * @see #shouldCommit() 484 */ 485 SharedPreferences.Editor getEditor() { 486 487 if (mNoCommit) { 488 if (mEditor == null) { 489 mEditor = getSharedPreferences().edit(); 490 } 491 492 return mEditor; 493 } else { 494 return getSharedPreferences().edit(); 495 } 496 } 497 498 /** 499 * Whether it is the client's responsibility to commit on the 500 * {@link #getEditor()}. This will return false in cases where the writes 501 * should be batched, for example when inflating preferences from XML. 502 * 503 * @return Whether the client should commit. 504 */ 505 boolean shouldCommit() { 506 return !mNoCommit; 507 } 508 509 private void setNoCommit(boolean noCommit) { 510 if (!noCommit && mEditor != null) { 511 try { 512 mEditor.apply(); 513 } catch (AbstractMethodError unused) { 514 // The app injected its own pre-Gingerbread 515 // SharedPreferences.Editor implementation without 516 // an apply method. 517 mEditor.commit(); 518 } 519 } 520 mNoCommit = noCommit; 521 } 522 523 /** 524 * Returns the activity that shows the preferences. This is useful for doing 525 * managed queries, but in most cases the use of {@link #getContext()} is 526 * preferred. 527 * <p> 528 * This will return null if this class was instantiated with a Context 529 * instead of Activity. For example, when setting the default values. 530 * 531 * @return The activity that shows the preferences. 532 * @see #mContext 533 */ 534 Activity getActivity() { 535 return mActivity; 536 } 537 538 /** 539 * Returns the context. This is preferred over {@link #getActivity()} when 540 * possible. 541 * 542 * @return The context. 543 */ 544 Context getContext() { 545 return mContext; 546 } 547 548 /** 549 * Registers a listener. 550 * 551 * @see OnActivityResultListener 552 */ 553 void registerOnActivityResultListener(OnActivityResultListener listener) { 554 synchronized (this) { 555 if (mActivityResultListeners == null) { 556 mActivityResultListeners = new ArrayList<OnActivityResultListener>(); 557 } 558 559 if (!mActivityResultListeners.contains(listener)) { 560 mActivityResultListeners.add(listener); 561 } 562 } 563 } 564 565 /** 566 * Unregisters a listener. 567 * 568 * @see OnActivityResultListener 569 */ 570 void unregisterOnActivityResultListener(OnActivityResultListener listener) { 571 synchronized (this) { 572 if (mActivityResultListeners != null) { 573 mActivityResultListeners.remove(listener); 574 } 575 } 576 } 577 578 /** 579 * Called by the {@link PreferenceManager} to dispatch a subactivity result. 580 */ 581 void dispatchActivityResult(int requestCode, int resultCode, Intent data) { 582 List<OnActivityResultListener> list; 583 584 synchronized (this) { 585 if (mActivityResultListeners == null) return; 586 list = new ArrayList<OnActivityResultListener>(mActivityResultListeners); 587 } 588 589 final int N = list.size(); 590 for (int i = 0; i < N; i++) { 591 if (list.get(i).onActivityResult(requestCode, resultCode, data)) { 592 break; 593 } 594 } 595 } 596 597 /** 598 * Registers a listener. 599 * 600 * @see OnActivityStopListener 601 */ 602 void registerOnActivityStopListener(OnActivityStopListener listener) { 603 synchronized (this) { 604 if (mActivityStopListeners == null) { 605 mActivityStopListeners = new ArrayList<OnActivityStopListener>(); 606 } 607 608 if (!mActivityStopListeners.contains(listener)) { 609 mActivityStopListeners.add(listener); 610 } 611 } 612 } 613 614 /** 615 * Unregisters a listener. 616 * 617 * @see OnActivityStopListener 618 */ 619 void unregisterOnActivityStopListener(OnActivityStopListener listener) { 620 synchronized (this) { 621 if (mActivityStopListeners != null) { 622 mActivityStopListeners.remove(listener); 623 } 624 } 625 } 626 627 /** 628 * Called by the {@link PreferenceManager} to dispatch the activity stop 629 * event. 630 */ 631 void dispatchActivityStop() { 632 List<OnActivityStopListener> list; 633 634 synchronized (this) { 635 if (mActivityStopListeners == null) return; 636 list = new ArrayList<OnActivityStopListener>(mActivityStopListeners); 637 } 638 639 final int N = list.size(); 640 for (int i = 0; i < N; i++) { 641 list.get(i).onActivityStop(); 642 } 643 } 644 645 /** 646 * Registers a listener. 647 * 648 * @see OnActivityDestroyListener 649 */ 650 void registerOnActivityDestroyListener(OnActivityDestroyListener listener) { 651 synchronized (this) { 652 if (mActivityDestroyListeners == null) { 653 mActivityDestroyListeners = new ArrayList<OnActivityDestroyListener>(); 654 } 655 656 if (!mActivityDestroyListeners.contains(listener)) { 657 mActivityDestroyListeners.add(listener); 658 } 659 } 660 } 661 662 /** 663 * Unregisters a listener. 664 * 665 * @see OnActivityDestroyListener 666 */ 667 void unregisterOnActivityDestroyListener(OnActivityDestroyListener listener) { 668 synchronized (this) { 669 if (mActivityDestroyListeners != null) { 670 mActivityDestroyListeners.remove(listener); 671 } 672 } 673 } 674 675 /** 676 * Called by the {@link PreferenceManager} to dispatch the activity destroy 677 * event. 678 */ 679 void dispatchActivityDestroy() { 680 List<OnActivityDestroyListener> list = null; 681 682 synchronized (this) { 683 if (mActivityDestroyListeners != null) { 684 list = new ArrayList<OnActivityDestroyListener>(mActivityDestroyListeners); 685 } 686 } 687 688 if (list != null) { 689 final int N = list.size(); 690 for (int i = 0; i < N; i++) { 691 list.get(i).onActivityDestroy(); 692 } 693 } 694 695 // Dismiss any PreferenceScreens still showing 696 dismissAllScreens(); 697 } 698 699 /** 700 * Returns a request code that is unique for the activity. Each subsequent 701 * call to this method should return another unique request code. 702 * 703 * @return A unique request code that will never be used by anyone other 704 * than the caller of this method. 705 */ 706 int getNextRequestCode() { 707 synchronized (this) { 708 return mNextRequestCode++; 709 } 710 } 711 712 void addPreferencesScreen(DialogInterface screen) { 713 synchronized (this) { 714 715 if (mPreferencesScreens == null) { 716 mPreferencesScreens = new ArrayList<DialogInterface>(); 717 } 718 719 mPreferencesScreens.add(screen); 720 } 721 } 722 723 void removePreferencesScreen(DialogInterface screen) { 724 synchronized (this) { 725 726 if (mPreferencesScreens == null) { 727 return; 728 } 729 730 mPreferencesScreens.remove(screen); 731 } 732 } 733 734 /** 735 * Called by {@link PreferenceActivity} to dispatch the new Intent event. 736 * 737 * @param intent The new Intent. 738 */ 739 void dispatchNewIntent(Intent intent) { 740 dismissAllScreens(); 741 } 742 743 private void dismissAllScreens() { 744 // Remove any of the previously shown preferences screens 745 ArrayList<DialogInterface> screensToDismiss; 746 747 synchronized (this) { 748 749 if (mPreferencesScreens == null) { 750 return; 751 } 752 753 screensToDismiss = new ArrayList<DialogInterface>(mPreferencesScreens); 754 mPreferencesScreens.clear(); 755 } 756 757 for (int i = screensToDismiss.size() - 1; i >= 0; i--) { 758 screensToDismiss.get(i).dismiss(); 759 } 760 } 761 762 /** 763 * Sets the callback to be invoked when a {@link Preference} in the 764 * hierarchy rooted at this {@link PreferenceManager} is clicked. 765 * 766 * @param listener The callback to be invoked. 767 */ 768 void setOnPreferenceTreeClickListener(OnPreferenceTreeClickListener listener) { 769 mOnPreferenceTreeClickListener = listener; 770 } 771 772 OnPreferenceTreeClickListener getOnPreferenceTreeClickListener() { 773 return mOnPreferenceTreeClickListener; 774 } 775 776 /** 777 * Interface definition for a callback to be invoked when a 778 * {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is 779 * clicked. 780 */ 781 interface OnPreferenceTreeClickListener { 782 /** 783 * Called when a preference in the tree rooted at this 784 * {@link PreferenceScreen} has been clicked. 785 * 786 * @param preferenceScreen The {@link PreferenceScreen} that the 787 * preference is located in. 788 * @param preference The preference that was clicked. 789 * @return Whether the click was handled. 790 */ 791 boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference); 792 } 793 794 /** 795 * Interface definition for a class that will be called when the container's activity 796 * receives an activity result. 797 */ 798 public interface OnActivityResultListener { 799 800 /** 801 * See Activity's onActivityResult. 802 * 803 * @return Whether the request code was handled (in which case 804 * subsequent listeners will not be called. 805 */ 806 boolean onActivityResult(int requestCode, int resultCode, Intent data); 807 } 808 809 /** 810 * Interface definition for a class that will be called when the container's activity 811 * is stopped. 812 */ 813 public interface OnActivityStopListener { 814 815 /** 816 * See Activity's onStop. 817 */ 818 void onActivityStop(); 819 } 820 821 /** 822 * Interface definition for a class that will be called when the container's activity 823 * is destroyed. 824 */ 825 public interface OnActivityDestroyListener { 826 827 /** 828 * See Activity's onDestroy. 829 */ 830 void onActivityDestroy(); 831 } 832 833} 834