• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PreferenceManager(Activity activity, int firstRequestCode)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      */
PreferenceManager(Context context)156     private PreferenceManager(Context context) {
157         init(context);
158     }
159 
init(Context context)160     private void init(Context context) {
161         mContext = context;
162 
163         setSharedPreferencesName(getDefaultSharedPreferencesName(context));
164     }
165 
166     /**
167      * Sets the owning preference fragment
168      */
setFragment(PreferenceFragment fragment)169     void setFragment(PreferenceFragment fragment) {
170         mFragment = fragment;
171     }
172 
173     /**
174      * Returns the owning preference fragment, if any.
175      */
getFragment()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      */
queryIntentActivities(Intent queryIntent)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      */
inflateFromIntent(Intent queryIntent, PreferenceScreen rootPreferences)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      */
inflateFromResource(Context context, int resId, PreferenceScreen rootPreferences)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 
createPreferenceScreen(Context context)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      */
getNextId()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      */
getSharedPreferencesName()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      */
setSharedPreferencesName(String sharedPreferencesName)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      */
getSharedPreferencesMode()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      */
setSharedPreferencesMode(int sharedPreferencesMode)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      */
getSharedPreferences()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      */
getDefaultSharedPreferences(Context context)365     public static SharedPreferences getDefaultSharedPreferences(Context context) {
366         return context.getSharedPreferences(getDefaultSharedPreferencesName(context),
367                 getDefaultSharedPreferencesMode());
368     }
369 
getDefaultSharedPreferencesName(Context context)370     private static String getDefaultSharedPreferencesName(Context context) {
371         return context.getPackageName() + "_preferences";
372     }
373 
getDefaultSharedPreferencesMode()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      */
getPreferenceScreen()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      */
setPreferences(PreferenceScreen preferenceScreen)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      */
findPreference(CharSequence key)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      */
setDefaultValues(Context context, int resId, boolean readAgain)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      */
setDefaultValues(Context context, String sharedPreferencesName, int sharedPreferencesMode, int resId, boolean readAgain)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      */
getEditor()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      */
shouldCommit()505     boolean shouldCommit() {
506         return !mNoCommit;
507     }
508 
setNoCommit(boolean noCommit)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      */
getActivity()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      */
getContext()544     Context getContext() {
545         return mContext;
546     }
547 
548     /**
549      * Registers a listener.
550      *
551      * @see OnActivityResultListener
552      */
registerOnActivityResultListener(OnActivityResultListener listener)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      */
unregisterOnActivityResultListener(OnActivityResultListener listener)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      */
dispatchActivityResult(int requestCode, int resultCode, Intent data)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      */
registerOnActivityStopListener(OnActivityStopListener listener)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      */
unregisterOnActivityStopListener(OnActivityStopListener listener)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      */
dispatchActivityStop()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      */
registerOnActivityDestroyListener(OnActivityDestroyListener listener)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      */
unregisterOnActivityDestroyListener(OnActivityDestroyListener listener)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      */
dispatchActivityDestroy()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      */
getNextRequestCode()706     int getNextRequestCode() {
707         synchronized (this) {
708             return mNextRequestCode++;
709         }
710     }
711 
addPreferencesScreen(DialogInterface screen)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 
removePreferencesScreen(DialogInterface screen)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      */
dispatchNewIntent(Intent intent)739     void dispatchNewIntent(Intent intent) {
740         dismissAllScreens();
741     }
742 
dismissAllScreens()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      */
setOnPreferenceTreeClickListener(OnPreferenceTreeClickListener listener)768     void setOnPreferenceTreeClickListener(OnPreferenceTreeClickListener listener) {
769         mOnPreferenceTreeClickListener = listener;
770     }
771 
getOnPreferenceTreeClickListener()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          */
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)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          */
onActivityResult(int requestCode, int resultCode, Intent data)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          */
onActivityStop()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          */
onActivityDestroy()830         void onActivityDestroy();
831     }
832 
833 }
834