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