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