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