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