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