Home | History | Annotate | Download | only in preference
      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 
     17 package android.preference;
     18 
     19 import android.app.Activity;
     20 import android.content.Context;
     21 import android.content.DialogInterface;
     22 import android.content.Intent;
     23 import android.content.SharedPreferences;
     24 import android.content.pm.ActivityInfo;
     25 import android.content.pm.PackageManager;
     26 import android.content.pm.ResolveInfo;
     27 import android.content.pm.PackageManager.NameNotFoundException;
     28 import android.content.res.XmlResourceParser;
     29 import android.os.Bundle;
     30 import android.util.Log;
     31 
     32 import java.util.ArrayList;
     33 import java.util.HashSet;
     34 import 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  */
     46 public 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