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