blob: 5c8c8e93e7366815071f614ee9a4a81a3847e953 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019import android.app.Activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import 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
Amith Yamasani82e7bc12010-09-23 15:07:58 -070032import java.util.ArrayList;
33import java.util.HashSet;
34import java.util.List;
35
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036/**
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 /**
Amith Yamasani82e7bc12010-09-23 15:07:58 -070063 * Fragment that owns this instance.
64 */
65 private PreferenceFragment mFragment;
66
67 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 * 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
Justin Koh37ae5582012-10-25 15:26:36 -0700141 /**
142 * @hide
143 */
144 public PreferenceManager(Activity activity, int firstRequestCode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 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 private PreferenceManager(Context context) {
160 init(context);
161 }
162
163 private void init(Context context) {
164 mContext = context;
165
166 setSharedPreferencesName(getDefaultSharedPreferencesName(context));
167 }
Amith Yamasani82e7bc12010-09-23 15:07:58 -0700168
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 /**
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).
Owen Linf9b702e2009-08-27 18:30:05 +0800264 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 */
Owen Linf9b702e2009-08-27 18:30:05 +0800266 public PreferenceScreen inflateFromResource(Context context, int resId,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 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 /**
Scott Mainbbb3f412012-03-09 19:10:40 -0800421 * 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 * be called by the application's main activity.
424 * <p>
Scott Mainbbb3f412012-03-09 19:10:40 -0800425 *
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 * {@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.
Scott Mainbbb3f412012-03-09 19:10:40 -0800434 * <p class="note">
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 * 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.
Scott Mainbbb3f412012-03-09 19:10:40 -0800452 *
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.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 *
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
Brad Fitzpatrickdd644c12010-10-10 10:58:47 -0700487 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 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 }
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 }
Brad Fitzpatrickdd644c12010-10-10 10:58:47 -0700531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 private void setNoCommit(boolean noCommit) {
533 if (!noCommit && mEditor != null) {
Brad Fitzpatrickdd644c12010-10-10 10:58:47 -0700534 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 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 mNoCommit = noCommit;
544 }
Brad Fitzpatrickdd644c12010-10-10 10:58:47 -0700545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 /**
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 */
625 void registerOnActivityStopListener(OnActivityStopListener listener) {
626 synchronized (this) {
627 if (mActivityStopListeners == null) {
628 mActivityStopListeners = new ArrayList<OnActivityStopListener>();
629 }
630
631 if (!mActivityStopListeners.contains(listener)) {
632 mActivityStopListeners.add(listener);
633 }
634 }
635 }
636
637 /**
638 * Unregisters a listener.
639 *
640 * @see OnActivityStopListener
641 */
642 void unregisterOnActivityStopListener(OnActivityStopListener listener) {
643 synchronized (this) {
644 if (mActivityStopListeners != null) {
645 mActivityStopListeners.remove(listener);
646 }
647 }
648 }
649
650 /**
651 * Called by the {@link PreferenceManager} to dispatch the activity stop
652 * event.
653 */
654 void dispatchActivityStop() {
655 List<OnActivityStopListener> list;
656
657 synchronized (this) {
658 if (mActivityStopListeners == null) return;
659 list = new ArrayList<OnActivityStopListener>(mActivityStopListeners);
660 }
661
662 final int N = list.size();
663 for (int i = 0; i < N; i++) {
664 list.get(i).onActivityStop();
665 }
666 }
667
668 /**
669 * Registers a listener.
670 *
671 * @see OnActivityDestroyListener
672 */
673 void registerOnActivityDestroyListener(OnActivityDestroyListener listener) {
674 synchronized (this) {
675 if (mActivityDestroyListeners == null) {
676 mActivityDestroyListeners = new ArrayList<OnActivityDestroyListener>();
677 }
678
679 if (!mActivityDestroyListeners.contains(listener)) {
680 mActivityDestroyListeners.add(listener);
681 }
682 }
683 }
684
685 /**
686 * Unregisters a listener.
687 *
688 * @see OnActivityDestroyListener
689 */
690 void unregisterOnActivityDestroyListener(OnActivityDestroyListener listener) {
691 synchronized (this) {
692 if (mActivityDestroyListeners != null) {
693 mActivityDestroyListeners.remove(listener);
694 }
695 }
696 }
697
698 /**
699 * Called by the {@link PreferenceManager} to dispatch the activity destroy
700 * event.
701 */
702 void dispatchActivityDestroy() {
703 List<OnActivityDestroyListener> list = null;
704
705 synchronized (this) {
706 if (mActivityDestroyListeners != null) {
707 list = new ArrayList<OnActivityDestroyListener>(mActivityDestroyListeners);
708 }
709 }
710
711 if (list != null) {
712 final int N = list.size();
713 for (int i = 0; i < N; i++) {
714 list.get(i).onActivityDestroy();
715 }
716 }
717
718 // Dismiss any PreferenceScreens still showing
719 dismissAllScreens();
720 }
721
722 /**
723 * Returns a request code that is unique for the activity. Each subsequent
724 * call to this method should return another unique request code.
725 *
726 * @return A unique request code that will never be used by anyone other
727 * than the caller of this method.
728 */
729 int getNextRequestCode() {
730 synchronized (this) {
731 return mNextRequestCode++;
732 }
733 }
734
735 void addPreferencesScreen(DialogInterface screen) {
736 synchronized (this) {
737
738 if (mPreferencesScreens == null) {
739 mPreferencesScreens = new ArrayList<DialogInterface>();
740 }
741
742 mPreferencesScreens.add(screen);
743 }
744 }
745
746 void removePreferencesScreen(DialogInterface screen) {
747 synchronized (this) {
748
749 if (mPreferencesScreens == null) {
750 return;
751 }
752
753 mPreferencesScreens.remove(screen);
754 }
755 }
756
757 /**
758 * Called by {@link PreferenceActivity} to dispatch the new Intent event.
759 *
760 * @param intent The new Intent.
761 */
762 void dispatchNewIntent(Intent intent) {
763 dismissAllScreens();
764 }
765
766 private void dismissAllScreens() {
767 // Remove any of the previously shown preferences screens
768 ArrayList<DialogInterface> screensToDismiss;
769
770 synchronized (this) {
771
772 if (mPreferencesScreens == null) {
773 return;
774 }
775
776 screensToDismiss = new ArrayList<DialogInterface>(mPreferencesScreens);
777 mPreferencesScreens.clear();
778 }
779
780 for (int i = screensToDismiss.size() - 1; i >= 0; i--) {
781 screensToDismiss.get(i).dismiss();
782 }
783 }
784
785 /**
786 * Sets the callback to be invoked when a {@link Preference} in the
787 * hierarchy rooted at this {@link PreferenceManager} is clicked.
788 *
789 * @param listener The callback to be invoked.
790 */
791 void setOnPreferenceTreeClickListener(OnPreferenceTreeClickListener listener) {
792 mOnPreferenceTreeClickListener = listener;
793 }
794
795 OnPreferenceTreeClickListener getOnPreferenceTreeClickListener() {
796 return mOnPreferenceTreeClickListener;
797 }
798
799 /**
800 * Interface definition for a callback to be invoked when a
801 * {@link Preference} in the hierarchy rooted at this {@link PreferenceScreen} is
802 * clicked.
Fabrice Di Meglioad2fcfe2014-01-20 11:10:52 -0800803 *
804 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 */
Fabrice Di Meglioad2fcfe2014-01-20 11:10:52 -0800806 public interface OnPreferenceTreeClickListener {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 /**
808 * Called when a preference in the tree rooted at this
809 * {@link PreferenceScreen} has been clicked.
810 *
811 * @param preferenceScreen The {@link PreferenceScreen} that the
812 * preference is located in.
813 * @param preference The preference that was clicked.
814 * @return Whether the click was handled.
815 */
816 boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference);
817 }
818
819 /**
820 * Interface definition for a class that will be called when the container's activity
821 * receives an activity result.
822 */
823 public interface OnActivityResultListener {
824
825 /**
826 * See Activity's onActivityResult.
827 *
828 * @return Whether the request code was handled (in which case
829 * subsequent listeners will not be called.
830 */
831 boolean onActivityResult(int requestCode, int resultCode, Intent data);
832 }
833
834 /**
835 * Interface definition for a class that will be called when the container's activity
836 * is stopped.
837 */
838 public interface OnActivityStopListener {
839
840 /**
841 * See Activity's onStop.
842 */
843 void onActivityStop();
844 }
845
846 /**
847 * Interface definition for a class that will be called when the container's activity
848 * is destroyed.
849 */
850 public interface OnActivityDestroyListener {
851
852 /**
853 * See Activity's onDestroy.
854 */
855 void onActivityDestroy();
856 }
857
858}