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