GeneralPreferences.java revision 9d8a376b89fcc36c44d4df0c5cbf6991306131c4
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 com.android.calendar;
18
19import android.app.Activity;
20import android.app.backup.BackupManager;
21import android.content.Context;
22import android.content.SharedPreferences;
23import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
24import android.os.Bundle;
25import android.os.Vibrator;
26import android.preference.CheckBoxPreference;
27import android.preference.ListPreference;
28import android.preference.Preference;
29import android.preference.Preference.OnPreferenceChangeListener;
30import android.preference.PreferenceCategory;
31import android.preference.PreferenceFragment;
32import android.preference.PreferenceManager;
33import android.preference.PreferenceScreen;
34import android.preference.RingtonePreference;
35import android.provider.Calendar.CalendarCache;
36import android.provider.SearchRecentSuggestions;
37import android.text.TextUtils;
38import android.widget.Toast;
39
40public class GeneralPreferences extends PreferenceFragment implements
41        OnSharedPreferenceChangeListener, OnPreferenceChangeListener {
42    // The name of the shared preferences file. This name must be maintained for historical
43    // reasons, as it's what PreferenceManager assigned the first time the file was created.
44    static final String SHARED_PREFS_NAME = "com.android.calendar_preferences";
45
46    // Preference keys
47    public static final String KEY_HIDE_DECLINED = "preferences_hide_declined";
48    public static final String KEY_WEEK_START_DAY = "preferences_week_start_day";
49    public static final String KEY_SHOW_WEEK_NUM = "preferences_show_week_num";
50    public static final String KEY_DAYS_PER_WEEK = "preferences_days_per_week";
51
52    public static final String KEY_CLEAR_SEARCH_HISTORY = "preferences_clear_search_history";
53
54    public static final String KEY_ALERTS_CATEGORY = "preferences_alerts_category";
55    public static final String KEY_ALERTS = "preferences_alerts";
56    public static final String KEY_ALERTS_VIBRATE = "preferences_alerts_vibrate";
57    public static final String KEY_ALERTS_VIBRATE_WHEN = "preferences_alerts_vibrateWhen";
58    public static final String KEY_ALERTS_RINGTONE = "preferences_alerts_ringtone";
59    public static final String KEY_ALERTS_POPUP = "preferences_alerts_popup";
60
61    public static final String KEY_DEFAULT_REMINDER = "preferences_default_reminder";
62    public static final int NO_REMINDER = -1;
63    public static final String NO_REMINDER_STRING = "-1";
64    public static final int REMINDER_DEFAULT_TIME = 10; // in minutes
65
66    public static final String KEY_DEFAULT_CELL_HEIGHT = "preferences_default_cell_height";
67
68    /** Key to SharePreference for default view (CalendarController.ViewType) */
69    public static final String KEY_START_VIEW = "preferred_startView";
70    /**
71     *  Key to SharePreference for default detail view (CalendarController.ViewType)
72     *  Typically used by widget
73     */
74    public static final String KEY_DETAILED_VIEW = "preferred_detailedView";
75    public static final String KEY_DEFAULT_CALENDAR = "preference_defaultCalendar";
76
77    // These must be in sync with the array preferences_week_start_day_values
78    public static final String WEEK_START_DEFAULT = "-1";
79    public static final String WEEK_START_SATURDAY = "7";
80    public static final String WEEK_START_SUNDAY = "1";
81    public static final String WEEK_START_MONDAY = "2";
82
83    // These keys are kept to enable migrating users from previous versions
84    private static final String KEY_ALERTS_TYPE = "preferences_alerts_type";
85    private static final String ALERT_TYPE_ALERTS = "0";
86    private static final String ALERT_TYPE_STATUS_BAR = "1";
87    private static final String ALERT_TYPE_OFF = "2";
88    static final String KEY_HOME_TZ_ENABLED = "preferences_home_tz_enabled";
89    static final String KEY_HOME_TZ = "preferences_home_tz";
90
91    // Default preference values
92    public static final int DEFAULT_START_VIEW = CalendarController.ViewType.WEEK;
93    public static final int DEFAULT_DETAILED_VIEW = CalendarController.ViewType.DAY;
94    public static final boolean DEFAULT_SHOW_WEEK_NUM = false;
95
96    CheckBoxPreference mAlert;
97    ListPreference mVibrateWhen;
98    RingtonePreference mRingtone;
99    CheckBoxPreference mPopup;
100    CheckBoxPreference mUseHomeTZ;
101    ListPreference mHomeTZ;
102    ListPreference mWeekStart;
103    ListPreference mDefaultReminder;
104
105    private static CharSequence[][] mTimezones;
106
107    /** Return a properly configured SharedPreferences instance */
108    public static SharedPreferences getSharedPreferences(Context context) {
109        return context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
110    }
111
112    /** Set the default shared preferences in the proper context */
113    public static void setDefaultValues(Context context) {
114        PreferenceManager.setDefaultValues(context, SHARED_PREFS_NAME, Context.MODE_PRIVATE,
115                R.xml.general_preferences, false);
116    }
117
118    @Override
119    public void onCreate(Bundle icicle) {
120        super.onCreate(icicle);
121
122        final Activity activity = getActivity();
123
124        // Make sure to always use the same preferences file regardless of the package name
125        // we're running under
126        final PreferenceManager preferenceManager = getPreferenceManager();
127        final SharedPreferences sharedPreferences = getSharedPreferences(activity);
128        preferenceManager.setSharedPreferencesName(SHARED_PREFS_NAME);
129
130        // Load the preferences from an XML resource
131        addPreferencesFromResource(R.xml.general_preferences);
132
133        final PreferenceScreen preferenceScreen = getPreferenceScreen();
134        mAlert = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS);
135        mVibrateWhen = (ListPreference) preferenceScreen.findPreference(KEY_ALERTS_VIBRATE_WHEN);
136        Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
137        if (vibrator == null || !vibrator.hasVibrator()) {
138            PreferenceCategory mAlertGroup = (PreferenceCategory) preferenceScreen
139                    .findPreference(KEY_ALERTS_CATEGORY);
140            mAlertGroup.removePreference(mVibrateWhen);
141        }
142
143        mRingtone = (RingtonePreference) preferenceScreen.findPreference(KEY_ALERTS_RINGTONE);
144        mPopup = (CheckBoxPreference) preferenceScreen.findPreference(KEY_ALERTS_POPUP);
145        mUseHomeTZ = (CheckBoxPreference) preferenceScreen.findPreference(KEY_HOME_TZ_ENABLED);
146        mWeekStart = (ListPreference) preferenceScreen.findPreference(KEY_WEEK_START_DAY);
147        mDefaultReminder = (ListPreference) preferenceScreen.findPreference(KEY_DEFAULT_REMINDER);
148        mHomeTZ = (ListPreference) preferenceScreen.findPreference(KEY_HOME_TZ);
149        String tz = mHomeTZ.getValue();
150
151        mWeekStart.setSummary(mWeekStart.getEntry());
152        mDefaultReminder.setSummary(mDefaultReminder.getEntry());
153
154        if (mTimezones == null) {
155            mTimezones = (new TimezoneAdapter(activity, tz)).getAllTimezones();
156        }
157        mHomeTZ.setEntryValues(mTimezones[0]);
158        mHomeTZ.setEntries(mTimezones[1]);
159        CharSequence tzName = mHomeTZ.getEntry();
160        if (TextUtils.isEmpty(tzName)) {
161            tzName = Utils.getTimeZone(activity, null);
162        }
163        mHomeTZ.setSummary(tzName);
164
165        migrateOldPreferences(sharedPreferences);
166
167        updateChildPreferences();
168    }
169
170    @Override
171    public void onResume() {
172        super.onResume();
173        getPreferenceScreen().getSharedPreferences()
174                .registerOnSharedPreferenceChangeListener(this);
175        setPreferenceListeners(this);
176    }
177
178    /**
179     * Sets up all the preference change listeners to use the specified
180     * listener.
181     */
182    private void setPreferenceListeners(OnPreferenceChangeListener listener) {
183        mUseHomeTZ.setOnPreferenceChangeListener(listener);
184        mHomeTZ.setOnPreferenceChangeListener(listener);
185        mWeekStart.setOnPreferenceChangeListener(listener);
186        mDefaultReminder.setOnPreferenceChangeListener(listener);
187        mRingtone.setOnPreferenceChangeListener(listener);
188    }
189
190    @Override
191    public void onPause() {
192        super.onPause();
193        getPreferenceScreen().getSharedPreferences()
194                .unregisterOnSharedPreferenceChangeListener(this);
195        setPreferenceListeners(null);
196    }
197
198    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
199        if (key.equals(KEY_ALERTS)) {
200            updateChildPreferences();
201        }
202        Activity a = getActivity();
203        if (a != null) {
204            BackupManager.dataChanged(a.getPackageName());
205        }
206    }
207
208    /**
209     * Handles time zone preference changes
210     */
211    @Override
212    public boolean onPreferenceChange(Preference preference, Object newValue) {
213        String tz;
214        if (preference == mUseHomeTZ) {
215            if ((Boolean)newValue) {
216                tz = mHomeTZ.getValue();
217            } else {
218                tz = CalendarCache.TIMEZONE_TYPE_AUTO;
219            }
220            Utils.setTimeZone(getActivity(), tz);
221            return true;
222        } else if (preference == mHomeTZ) {
223            tz = (String) newValue;
224            // We set the value here so we can read back the entry
225            mHomeTZ.setValue(tz);
226            mHomeTZ.setSummary(mHomeTZ.getEntry());
227            Utils.setTimeZone(getActivity(), tz);
228        } else if (preference == mWeekStart) {
229            mWeekStart.setValue((String) newValue);
230            mWeekStart.setSummary(mWeekStart.getEntry());
231        } else if (preference == mDefaultReminder) {
232            mDefaultReminder.setValue((String) newValue);
233            mDefaultReminder.setSummary(mDefaultReminder.getEntry());
234        } else if (preference == mRingtone) {
235            // TODO update this after b/3417832 is fixed
236            return true;
237        } else {
238            return true;
239        }
240        return false;
241    }
242
243    /**
244     * If necessary, upgrades previous versions of preferences to the current
245     * set of keys and values.
246     * @param prefs the preferences to upgrade
247     */
248    private void migrateOldPreferences(SharedPreferences prefs) {
249        // If needed, migrate vibration setting from a previous version
250        if (!prefs.contains(KEY_ALERTS_VIBRATE_WHEN) &&
251                prefs.contains(KEY_ALERTS_VIBRATE)) {
252            int stringId = prefs.getBoolean(KEY_ALERTS_VIBRATE, false) ?
253                    R.string.prefDefault_alerts_vibrate_true :
254                    R.string.prefDefault_alerts_vibrate_false;
255            mVibrateWhen.setValue(getActivity().getString(stringId));
256        }
257        // If needed, migrate the old alerts type settin
258        if (!prefs.contains(KEY_ALERTS) && prefs.contains(KEY_ALERTS_TYPE)) {
259            String type = prefs.getString(KEY_ALERTS_TYPE, ALERT_TYPE_STATUS_BAR);
260            if (type.equals(ALERT_TYPE_OFF)) {
261                mAlert.setChecked(false);
262                mPopup.setChecked(false);
263                mPopup.setEnabled(false);
264            } else if (type.equals(ALERT_TYPE_STATUS_BAR)) {
265                mAlert.setChecked(true);
266                mPopup.setChecked(false);
267                mPopup.setEnabled(true);
268            } else if (type.equals(ALERT_TYPE_ALERTS)) {
269                mAlert.setChecked(true);
270                mPopup.setChecked(true);
271                mPopup.setEnabled(true);
272            }
273            // clear out the old setting
274            prefs.edit().remove(KEY_ALERTS_TYPE).commit();
275        }
276    }
277
278    /**
279     * Keeps the dependent settings in sync with the parent preference, so for
280     * example, when notifications are turned off, we disable the preferences
281     * for configuring the exact notification behavior.
282     */
283    private void updateChildPreferences() {
284        if (mAlert.isChecked()) {
285            mVibrateWhen.setEnabled(true);
286            mRingtone.setEnabled(true);
287            mPopup.setEnabled(true);
288        } else {
289            mVibrateWhen.setValue(
290                    getActivity().getString(R.string.prefDefault_alerts_vibrate_false));
291            mVibrateWhen.setEnabled(false);
292            mRingtone.setEnabled(false);
293            mPopup.setEnabled(false);
294        }
295    }
296
297
298    @Override
299    public boolean onPreferenceTreeClick(
300            PreferenceScreen preferenceScreen, Preference preference) {
301        final String key = preference.getKey();
302        if (key.equals(KEY_CLEAR_SEARCH_HISTORY)) {
303            SearchRecentSuggestions suggestions = new SearchRecentSuggestions(getActivity(),
304                    CalendarRecentSuggestionsProvider.AUTHORITY,
305                    CalendarRecentSuggestionsProvider.MODE);
306            suggestions.clearHistory();
307            Toast.makeText(getActivity(), R.string.search_history_cleared,
308                    Toast.LENGTH_SHORT).show();
309            return true;
310        }
311        return false;
312    }
313
314}
315