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; 18 19 import android.app.ActionBar; 20 import android.content.Intent; 21 import android.content.res.Resources; 22 import android.media.AudioManager; 23 import android.os.Bundle; 24 import android.preference.CheckBoxPreference; 25 import android.preference.ListPreference; 26 import android.preference.Preference; 27 import android.preference.PreferenceActivity; 28 import android.preference.PreferenceScreen; 29 import android.provider.Settings; 30 import android.text.format.DateUtils; 31 import android.view.Menu; 32 import android.view.MenuItem; 33 34 import com.android.deskclock.worldclock.Cities; 35 36 import java.util.ArrayList; 37 import java.util.Collections; 38 import java.util.List; 39 import java.util.TimeZone; 40 41 /** 42 * Settings for the Alarm Clock. 43 */ 44 public class SettingsActivity extends PreferenceActivity 45 implements Preference.OnPreferenceChangeListener { 46 47 private static final int ALARM_STREAM_TYPE_BIT = 48 1 << AudioManager.STREAM_ALARM; 49 50 public static final String KEY_ALARM_IN_SILENT_MODE = 51 "alarm_in_silent_mode"; 52 public static final String KEY_ALARM_SNOOZE = 53 "snooze_duration"; 54 public static final String KEY_VOLUME_BEHAVIOR = 55 "volume_button_setting"; 56 public static final String KEY_AUTO_SILENCE = 57 "auto_silence"; 58 public static final String KEY_CLOCK_STYLE = 59 "clock_style"; 60 public static final String KEY_HOME_TZ = 61 "home_time_zone"; 62 public static final String KEY_AUTO_HOME_CLOCK = 63 "automatic_home_clock"; 64 public static final String KEY_VOLUME_BUTTONS = 65 "volume_button_setting"; 66 67 public static final String DEFAULT_VOLUME_BEHAVIOR = "0"; 68 public static final String VOLUME_BEHAVIOR_SNOOZE = "1"; 69 public static final String VOLUME_BEHAVIOR_DISMISS = "2"; 70 71 72 private static CharSequence[][] mTimezones; 73 private long mTime; 74 75 76 @Override 77 protected void onCreate(Bundle savedInstanceState) { 78 super.onCreate(savedInstanceState); 79 addPreferencesFromResource(R.xml.settings); 80 81 ActionBar actionBar = getActionBar(); 82 if (actionBar != null) { 83 actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP); 84 } 85 86 // We don't want to reconstruct the timezone list every single time 87 // onResume() is called so we do it once in onCreate 88 ListPreference listPref; 89 listPref = (ListPreference) findPreference(KEY_HOME_TZ); 90 if (mTimezones == null) { 91 mTime = System.currentTimeMillis(); 92 mTimezones = getAllTimezones(); 93 } 94 95 listPref.setEntryValues(mTimezones[0]); 96 listPref.setEntries(mTimezones[1]); 97 listPref.setSummary(listPref.getEntry()); 98 listPref.setOnPreferenceChangeListener(this); 99 } 100 101 @Override 102 protected void onResume() { 103 super.onResume(); 104 getWindow().getDecorView().setBackgroundColor(Utils.getCurrentHourColor()); 105 refresh(); 106 } 107 108 @Override 109 public boolean onOptionsItemSelected (MenuItem item) { 110 switch (item.getItemId()) { 111 case android.R.id.home: 112 finish(); 113 return true; 114 default: 115 break; 116 } 117 return super.onOptionsItemSelected(item); 118 } 119 120 121 @Override 122 public boolean onCreateOptionsMenu (Menu menu) { 123 getMenuInflater().inflate(R.menu.settings_menu, menu); 124 MenuItem help = menu.findItem(R.id.menu_item_help); 125 if (help != null) { 126 Utils.prepareHelpMenuItem(this, help); 127 } 128 return super.onCreateOptionsMenu(menu); 129 } 130 131 @Override 132 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, 133 Preference preference) { 134 if (KEY_ALARM_IN_SILENT_MODE.equals(preference.getKey())) { 135 CheckBoxPreference pref = (CheckBoxPreference) preference; 136 int ringerModeStreamTypes = Settings.System.getInt( 137 getContentResolver(), 138 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0); 139 140 if (pref.isChecked()) { 141 ringerModeStreamTypes &= ~ALARM_STREAM_TYPE_BIT; 142 } else { 143 ringerModeStreamTypes |= ALARM_STREAM_TYPE_BIT; 144 } 145 146 Settings.System.putInt(getContentResolver(), 147 Settings.System.MODE_RINGER_STREAMS_AFFECTED, 148 ringerModeStreamTypes); 149 150 return true; 151 } 152 153 return super.onPreferenceTreeClick(preferenceScreen, preference); 154 } 155 156 @Override 157 public boolean onPreferenceChange(Preference pref, Object newValue) { 158 if (KEY_AUTO_SILENCE.equals(pref.getKey())) { 159 final ListPreference listPref = (ListPreference) pref; 160 String delay = (String) newValue; 161 updateAutoSnoozeSummary(listPref, delay); 162 } else if (KEY_CLOCK_STYLE.equals(pref.getKey())) { 163 final ListPreference listPref = (ListPreference) pref; 164 final int idx = listPref.findIndexOfValue((String) newValue); 165 listPref.setSummary(listPref.getEntries()[idx]); 166 } else if (KEY_HOME_TZ.equals(pref.getKey())) { 167 final ListPreference listPref = (ListPreference) pref; 168 final int idx = listPref.findIndexOfValue((String) newValue); 169 listPref.setSummary(listPref.getEntries()[idx]); 170 notifyHomeTimeZoneChanged(); 171 } else if (KEY_AUTO_HOME_CLOCK.equals(pref.getKey())) { 172 boolean state =((CheckBoxPreference) pref).isChecked(); 173 Preference homeTimeZone = findPreference(KEY_HOME_TZ); 174 homeTimeZone.setEnabled(!state); 175 notifyHomeTimeZoneChanged(); 176 } else if (KEY_VOLUME_BUTTONS.equals(pref.getKey())) { 177 final ListPreference listPref = (ListPreference) pref; 178 final int idx = listPref.findIndexOfValue((String) newValue); 179 listPref.setSummary(listPref.getEntries()[idx]); 180 } 181 return true; 182 } 183 184 @Override 185 protected boolean isValidFragment(String fragmentName) { 186 // Exported activity but no headers we support. 187 return false; 188 } 189 190 private void updateAutoSnoozeSummary(ListPreference listPref, 191 String delay) { 192 int i = Integer.parseInt(delay); 193 if (i == -1) { 194 listPref.setSummary(R.string.auto_silence_never); 195 } else { 196 listPref.setSummary(getString(R.string.auto_silence_summary, i)); 197 } 198 } 199 200 private void notifyHomeTimeZoneChanged() { 201 Intent i = new Intent(Cities.WORLDCLOCK_UPDATE_INTENT); 202 sendBroadcast(i); 203 } 204 205 206 private void refresh() { 207 ListPreference listPref = (ListPreference) findPreference(KEY_AUTO_SILENCE); 208 String delay = listPref.getValue(); 209 updateAutoSnoozeSummary(listPref, delay); 210 listPref.setOnPreferenceChangeListener(this); 211 212 listPref = (ListPreference) findPreference(KEY_CLOCK_STYLE); 213 listPref.setSummary(listPref.getEntry()); 214 listPref.setOnPreferenceChangeListener(this); 215 216 Preference pref = findPreference(KEY_AUTO_HOME_CLOCK); 217 boolean state =((CheckBoxPreference) pref).isChecked(); 218 pref.setOnPreferenceChangeListener(this); 219 220 listPref = (ListPreference)findPreference(KEY_HOME_TZ); 221 listPref.setEnabled(state); 222 listPref.setSummary(listPref.getEntry()); 223 224 listPref = (ListPreference) findPreference(KEY_VOLUME_BUTTONS); 225 listPref.setSummary(listPref.getEntry()); 226 listPref.setOnPreferenceChangeListener(this); 227 228 SnoozeLengthDialog snoozePref = (SnoozeLengthDialog) findPreference(KEY_ALARM_SNOOZE); 229 snoozePref.setSummary(); 230 } 231 232 private class TimeZoneRow implements Comparable<TimeZoneRow> { 233 private static final boolean SHOW_DAYLIGHT_SAVINGS_INDICATOR = false; 234 235 public final String mId; 236 public final String mDisplayName; 237 public final int mOffset; 238 239 public TimeZoneRow(String id, String name) { 240 mId = id; 241 TimeZone tz = TimeZone.getTimeZone(id); 242 boolean useDaylightTime = tz.useDaylightTime(); 243 mOffset = tz.getOffset(mTime); 244 mDisplayName = buildGmtDisplayName(id, name, useDaylightTime); 245 } 246 247 @Override 248 public int compareTo(TimeZoneRow another) { 249 return mOffset - another.mOffset; 250 } 251 252 public String buildGmtDisplayName(String id, String displayName, boolean useDaylightTime) { 253 int p = Math.abs(mOffset); 254 StringBuilder name = new StringBuilder("(GMT"); 255 name.append(mOffset < 0 ? '-' : '+'); 256 257 name.append(p / DateUtils.HOUR_IN_MILLIS); 258 name.append(':'); 259 260 int min = p / 60000; 261 min %= 60; 262 263 if (min < 10) { 264 name.append('0'); 265 } 266 name.append(min); 267 name.append(") "); 268 name.append(displayName); 269 if (useDaylightTime && SHOW_DAYLIGHT_SAVINGS_INDICATOR) { 270 name.append(" \u2600"); // Sun symbol 271 } 272 return name.toString(); 273 } 274 } 275 276 277 /** 278 * Returns an array of ids/time zones. This returns a double indexed array 279 * of ids and time zones for Calendar. It is an inefficient method and 280 * shouldn't be called often, but can be used for one time generation of 281 * this list. 282 * 283 * @return double array of tz ids and tz names 284 */ 285 public CharSequence[][] getAllTimezones() { 286 Resources resources = this.getResources(); 287 String[] ids = resources.getStringArray(R.array.timezone_values); 288 String[] labels = resources.getStringArray(R.array.timezone_labels); 289 int minLength = ids.length; 290 if (ids.length != labels.length) { 291 minLength = Math.min(minLength, labels.length); 292 LogUtils.e("Timezone ids and labels have different length!"); 293 } 294 List<TimeZoneRow> timezones = new ArrayList<TimeZoneRow>(); 295 for (int i = 0; i < minLength; i++) { 296 timezones.add(new TimeZoneRow(ids[i], labels[i])); 297 } 298 Collections.sort(timezones); 299 300 CharSequence[][] timeZones = new CharSequence[2][timezones.size()]; 301 int i = 0; 302 for (TimeZoneRow row : timezones) { 303 timeZones[0][i] = row.mId; 304 timeZones[1][i++] = row.mDisplayName; 305 } 306 return timeZones; 307 } 308 309 } 310