1 /* 2 * Copyright (C) 2009 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.deskclock.settings; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.content.res.Resources; 23 import android.media.AudioManager; 24 import android.os.Bundle; 25 import android.preference.ListPreference; 26 import android.preference.Preference; 27 import android.preference.PreferenceFragment; 28 import android.preference.RingtonePreference; 29 import android.preference.SwitchPreference; 30 import android.provider.Settings; 31 import android.text.format.DateUtils; 32 import android.view.Menu; 33 import android.view.MenuItem; 34 35 import com.android.deskclock.BaseActivity; 36 import com.android.deskclock.LogUtils; 37 import com.android.deskclock.R; 38 import com.android.deskclock.Utils; 39 import com.android.deskclock.actionbarmenu.ActionBarMenuManager; 40 import com.android.deskclock.actionbarmenu.MenuItemControllerFactory; 41 import com.android.deskclock.actionbarmenu.NavUpMenuItemController; 42 import com.android.deskclock.data.DataModel; 43 44 import java.util.ArrayList; 45 import java.util.Collections; 46 import java.util.List; 47 import java.util.Locale; 48 import java.util.TimeZone; 49 50 /** 51 * Settings for the Alarm Clock. 52 */ 53 public final class SettingsActivity extends BaseActivity { 54 55 public static final String KEY_ALARM_SNOOZE = "snooze_duration"; 56 public static final String KEY_ALARM_VOLUME = "volume_setting"; 57 public static final String KEY_ALARM_CRESCENDO = "alarm_crescendo_duration"; 58 public static final String KEY_TIMER_CRESCENDO = "timer_crescendo_duration"; 59 public static final String KEY_TIMER_RINGTONE = "timer_ringtone"; 60 public static final String KEY_AUTO_SILENCE = "auto_silence"; 61 public static final String KEY_CLOCK_STYLE = "clock_style"; 62 public static final String KEY_HOME_TZ = "home_time_zone"; 63 public static final String KEY_AUTO_HOME_CLOCK = "automatic_home_clock"; 64 public static final String KEY_DATE_TIME = "date_time"; 65 public static final String KEY_VOLUME_BUTTONS = "volume_button_setting"; 66 public static final String KEY_WEEK_START = "week_start"; 67 68 public static final String TIMEZONE_LOCALE = "tz_locale"; 69 70 public static final String DEFAULT_VOLUME_BEHAVIOR = "0"; 71 public static final String VOLUME_BEHAVIOR_SNOOZE = "1"; 72 public static final String VOLUME_BEHAVIOR_DISMISS = "2"; 73 74 private final ActionBarMenuManager mActionBarMenuManager = new ActionBarMenuManager(this); 75 76 @Override 77 protected void onCreate(Bundle savedInstanceState) { 78 super.onCreate(savedInstanceState); 79 setVolumeControlStream(AudioManager.STREAM_ALARM); 80 setContentView(R.layout.settings); 81 mActionBarMenuManager.addMenuItemController(new NavUpMenuItemController(this)) 82 .addMenuItemController(MenuItemControllerFactory.getInstance() 83 .buildMenuItemControllers(this)); 84 } 85 86 @Override 87 public boolean onCreateOptionsMenu(Menu menu) { 88 mActionBarMenuManager.createOptionsMenu(menu, getMenuInflater()); 89 return true; 90 } 91 92 @Override 93 public boolean onPrepareOptionsMenu(Menu menu) { 94 mActionBarMenuManager.prepareShowMenu(menu); 95 return true; 96 } 97 98 @Override 99 public boolean onOptionsItemSelected(MenuItem item) { 100 if (mActionBarMenuManager.handleMenuItemClick(item)) { 101 return true; 102 } 103 return super.onOptionsItemSelected(item); 104 } 105 106 public static class PrefsFragment extends PreferenceFragment 107 implements Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener { 108 @Override 109 public void onCreate(Bundle savedInstanceState) { 110 super.onCreate(savedInstanceState); 111 112 addPreferencesFromResource(R.xml.settings); 113 loadTimeZoneList(); 114 } 115 116 @Override 117 public void onActivityCreated(Bundle savedInstanceState) { 118 super.onActivityCreated(savedInstanceState); 119 120 // By default, do not recreate the DeskClock activity 121 getActivity().setResult(RESULT_CANCELED); 122 123 } 124 125 @Override 126 public void onResume() { 127 super.onResume(); 128 129 refresh(); 130 } 131 132 @Override 133 public boolean onPreferenceChange(Preference pref, Object newValue) { 134 final int idx; 135 switch (pref.getKey()) { 136 case KEY_AUTO_SILENCE: 137 final ListPreference autoSilencePref = (ListPreference) pref; 138 String delay = (String) newValue; 139 updateAutoSnoozeSummary(autoSilencePref, delay); 140 break; 141 case KEY_CLOCK_STYLE: 142 final ListPreference clockStylePref = (ListPreference) pref; 143 idx = clockStylePref.findIndexOfValue((String) newValue); 144 clockStylePref.setSummary(clockStylePref.getEntries()[idx]); 145 break; 146 case KEY_HOME_TZ: 147 final ListPreference homeTimezonePref = (ListPreference) pref; 148 idx = homeTimezonePref.findIndexOfValue((String) newValue); 149 homeTimezonePref.setSummary(homeTimezonePref.getEntries()[idx]); 150 break; 151 case KEY_AUTO_HOME_CLOCK: 152 final boolean autoHomeClockEnabled = ((SwitchPreference) pref).isChecked(); 153 final Preference homeTimeZonePref = findPreference(KEY_HOME_TZ); 154 homeTimeZonePref.setEnabled(!autoHomeClockEnabled); 155 break; 156 case KEY_VOLUME_BUTTONS: 157 final ListPreference volumeButtonsPref = (ListPreference) pref; 158 final int index = volumeButtonsPref.findIndexOfValue((String) newValue); 159 volumeButtonsPref.setSummary(volumeButtonsPref.getEntries()[index]); 160 break; 161 case KEY_WEEK_START: 162 final ListPreference weekStartPref = (ListPreference) 163 findPreference(KEY_WEEK_START); 164 idx = weekStartPref.findIndexOfValue((String) newValue); 165 weekStartPref.setSummary(weekStartPref.getEntries()[idx]); 166 break; 167 case KEY_TIMER_RINGTONE: 168 final RingtonePreference timerRingtonePref = (RingtonePreference) 169 findPreference(KEY_TIMER_RINGTONE); 170 timerRingtonePref.setSummary(DataModel.getDataModel().getTimerRingtoneTitle()); 171 break; 172 } 173 // Set result so DeskClock knows to refresh itself 174 getActivity().setResult(RESULT_OK); 175 return true; 176 } 177 178 @Override 179 public boolean onPreferenceClick(Preference pref) { 180 final Activity activity = getActivity(); 181 if (activity == null) { 182 return false; 183 } 184 185 switch (pref.getKey()) { 186 case KEY_DATE_TIME: 187 final Intent dialogIntent = new Intent(Settings.ACTION_DATE_SETTINGS); 188 dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 189 startActivity(dialogIntent); 190 return true; 191 case KEY_ALARM_VOLUME: 192 final AudioManager audioManager = 193 (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE); 194 audioManager.adjustStreamVolume(AudioManager.STREAM_ALARM, 195 AudioManager.ADJUST_SAME, AudioManager.FLAG_SHOW_UI); 196 return true; 197 default: 198 return false; 199 } 200 } 201 202 /** 203 * Reconstruct the timezone list. 204 */ 205 private void loadTimeZoneList() { 206 final CharSequence[][] timezones = getAllTimezones(); 207 final ListPreference homeTimezonePref = (ListPreference) findPreference(KEY_HOME_TZ); 208 homeTimezonePref.setEntryValues(timezones[0]); 209 homeTimezonePref.setEntries(timezones[1]); 210 homeTimezonePref.setSummary(homeTimezonePref.getEntry()); 211 homeTimezonePref.setOnPreferenceChangeListener(this); 212 } 213 214 /** 215 * Returns an array of ids/time zones. This returns a double indexed array 216 * of ids and time zones for Calendar. It is an inefficient method and 217 * shouldn't be called often, but can be used for one time generation of 218 * this list. 219 * 220 * @return double array of tz ids and tz names 221 */ 222 public CharSequence[][] getAllTimezones() { 223 final Resources res = getResources(); 224 final String[] ids = res.getStringArray(R.array.timezone_values); 225 final String[] labels = res.getStringArray(R.array.timezone_labels); 226 227 int minLength = ids.length; 228 if (ids.length != labels.length) { 229 minLength = Math.min(minLength, labels.length); 230 LogUtils.e("Timezone ids and labels have different length!"); 231 } 232 233 final long currentTimeMillis = System.currentTimeMillis(); 234 final List<TimeZoneRow> timezones = new ArrayList<>(minLength); 235 for (int i = 0; i < minLength; i++) { 236 timezones.add(new TimeZoneRow(ids[i], labels[i], currentTimeMillis)); 237 } 238 Collections.sort(timezones); 239 240 final CharSequence[][] timeZones = new CharSequence[2][timezones.size()]; 241 int i = 0; 242 for (TimeZoneRow row : timezones) { 243 timeZones[0][i] = row.mId; 244 timeZones[1][i++] = row.mDisplayName; 245 } 246 return timeZones; 247 } 248 249 private void refresh() { 250 final ListPreference autoSilencePref = 251 (ListPreference) findPreference(KEY_AUTO_SILENCE); 252 String delay = autoSilencePref.getValue(); 253 updateAutoSnoozeSummary(autoSilencePref, delay); 254 autoSilencePref.setOnPreferenceChangeListener(this); 255 256 final ListPreference clockStylePref = (ListPreference) findPreference(KEY_CLOCK_STYLE); 257 clockStylePref.setSummary(clockStylePref.getEntry()); 258 clockStylePref.setOnPreferenceChangeListener(this); 259 260 final Preference autoHomeClockPref = findPreference(KEY_AUTO_HOME_CLOCK); 261 final boolean autoHomeClockEnabled = ((SwitchPreference) autoHomeClockPref).isChecked(); 262 autoHomeClockPref.setOnPreferenceChangeListener(this); 263 264 final ListPreference homeTimezonePref = (ListPreference) findPreference(KEY_HOME_TZ); 265 homeTimezonePref.setEnabled(autoHomeClockEnabled); 266 homeTimezonePref.setSummary(homeTimezonePref.getEntry()); 267 homeTimezonePref.setOnPreferenceChangeListener(this); 268 269 final ListPreference volumeButtonsPref = 270 (ListPreference) findPreference(KEY_VOLUME_BUTTONS); 271 volumeButtonsPref.setSummary(volumeButtonsPref.getEntry()); 272 volumeButtonsPref.setOnPreferenceChangeListener(this); 273 274 final Preference volumePref = findPreference(KEY_ALARM_VOLUME); 275 volumePref.setOnPreferenceClickListener(this); 276 277 final SnoozeLengthDialog snoozePref = 278 (SnoozeLengthDialog) findPreference(KEY_ALARM_SNOOZE); 279 snoozePref.setSummary(); 280 281 final CrescendoLengthDialog alarmCrescendoPref = 282 (CrescendoLengthDialog) findPreference(KEY_ALARM_CRESCENDO); 283 alarmCrescendoPref.setSummary(); 284 285 final CrescendoLengthDialog timerCrescendoPref = 286 (CrescendoLengthDialog) findPreference(KEY_TIMER_CRESCENDO); 287 timerCrescendoPref.setSummary(); 288 289 final Preference dateAndTimeSetting = findPreference(KEY_DATE_TIME); 290 dateAndTimeSetting.setOnPreferenceClickListener(this); 291 292 final ListPreference weekStartPref = (ListPreference) findPreference(KEY_WEEK_START); 293 // Set the default value programmatically 294 final String value = weekStartPref.getValue(); 295 final int idx = weekStartPref.findIndexOfValue( 296 value == null ? String.valueOf(Utils.DEFAULT_WEEK_START) : value); 297 weekStartPref.setValueIndex(idx); 298 weekStartPref.setSummary(weekStartPref.getEntries()[idx]); 299 weekStartPref.setOnPreferenceChangeListener(this); 300 301 final RingtonePreference timerRingtonePref = 302 (RingtonePreference) findPreference(KEY_TIMER_RINGTONE); 303 timerRingtonePref.setSummary(DataModel.getDataModel().getTimerRingtoneTitle()); 304 timerRingtonePref.setOnPreferenceChangeListener(this); 305 } 306 307 private void updateAutoSnoozeSummary(ListPreference listPref, String delay) { 308 int i = Integer.parseInt(delay); 309 if (i == -1) { 310 listPref.setSummary(R.string.auto_silence_never); 311 } else { 312 listPref.setSummary(Utils.getNumberFormattedQuantityString(getActivity(), 313 R.plurals.auto_silence_summary, i)); 314 } 315 } 316 317 private static class TimeZoneRow implements Comparable<TimeZoneRow> { 318 319 private static final boolean SHOW_DAYLIGHT_SAVINGS_INDICATOR = false; 320 321 public final String mId; 322 public final String mDisplayName; 323 public final int mOffset; 324 325 public TimeZoneRow(String id, String name, long currentTimeMillis) { 326 final TimeZone tz = TimeZone.getTimeZone(id); 327 final boolean useDaylightTime = tz.useDaylightTime(); 328 mId = id; 329 mOffset = tz.getOffset(currentTimeMillis); 330 mDisplayName = buildGmtDisplayName(name, useDaylightTime); 331 } 332 333 @Override 334 public int compareTo(TimeZoneRow another) { 335 return mOffset - another.mOffset; 336 } 337 338 public String buildGmtDisplayName(String displayName, boolean useDaylightTime) { 339 final int p = Math.abs(mOffset); 340 final StringBuilder name = new StringBuilder("(GMT"); 341 name.append(mOffset < 0 ? '-' : '+'); 342 343 name.append(p / DateUtils.HOUR_IN_MILLIS); 344 name.append(':'); 345 346 int min = p / 60000; 347 min %= 60; 348 349 if (min < 10) { 350 name.append('0'); 351 } 352 name.append(min); 353 name.append(") "); 354 name.append(displayName); 355 if (useDaylightTime && SHOW_DAYLIGHT_SAVINGS_INDICATOR) { 356 name.append(" \u2600"); // Sun symbol 357 } 358 return name.toString(); 359 } 360 } 361 } 362 } 363