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     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 
     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     @Override
    181     protected boolean isValidFragment(String fragmentName) {
    182         // Exported activity but no headers we support.
    183         return false;
    184     }
    185 
    186     private void updateAutoSnoozeSummary(ListPreference listPref,
    187             String delay) {
    188         int i = Integer.parseInt(delay);
    189         if (i == -1) {
    190             listPref.setSummary(R.string.auto_silence_never);
    191         } else {
    192             listPref.setSummary(getString(R.string.auto_silence_summary, i));
    193         }
    194     }
    195 
    196     private void notifyHomeTimeZoneChanged() {
    197         Intent i = new Intent(Cities.WORLDCLOCK_UPDATE_INTENT);
    198         sendBroadcast(i);
    199     }
    200 
    201 
    202     private void refresh() {
    203         ListPreference listPref = (ListPreference) findPreference(KEY_AUTO_SILENCE);
    204         String delay = listPref.getValue();
    205         updateAutoSnoozeSummary(listPref, delay);
    206         listPref.setOnPreferenceChangeListener(this);
    207 
    208         listPref = (ListPreference) findPreference(KEY_CLOCK_STYLE);
    209         listPref.setSummary(listPref.getEntry());
    210         listPref.setOnPreferenceChangeListener(this);
    211 
    212         Preference pref = findPreference(KEY_AUTO_HOME_CLOCK);
    213         boolean state =((CheckBoxPreference) pref).isChecked();
    214         pref.setOnPreferenceChangeListener(this);
    215 
    216         listPref = (ListPreference)findPreference(KEY_HOME_TZ);
    217         listPref.setEnabled(state);
    218         listPref.setSummary(listPref.getEntry());
    219 
    220         listPref = (ListPreference) findPreference(KEY_VOLUME_BUTTONS);
    221         listPref.setSummary(listPref.getEntry());
    222         listPref.setOnPreferenceChangeListener(this);
    223 
    224         SnoozeLengthDialog snoozePref = (SnoozeLengthDialog) findPreference(KEY_ALARM_SNOOZE);
    225         snoozePref.setSummary();
    226     }
    227 
    228     private class TimeZoneRow implements Comparable<TimeZoneRow> {
    229         private static final boolean SHOW_DAYLIGHT_SAVINGS_INDICATOR = false;
    230 
    231         public final String mId;
    232         public final String mDisplayName;
    233         public final int mOffset;
    234 
    235         public TimeZoneRow(String id, String name) {
    236             mId = id;
    237             TimeZone tz = TimeZone.getTimeZone(id);
    238             boolean useDaylightTime = tz.useDaylightTime();
    239             mOffset = tz.getOffset(mTime);
    240             mDisplayName = buildGmtDisplayName(id, name, useDaylightTime);
    241         }
    242 
    243         @Override
    244         public int compareTo(TimeZoneRow another) {
    245             return mOffset - another.mOffset;
    246         }
    247 
    248         public String buildGmtDisplayName(String id, String displayName, boolean useDaylightTime) {
    249             int p = Math.abs(mOffset);
    250             StringBuilder name = new StringBuilder("(GMT");
    251             name.append(mOffset < 0 ? '-' : '+');
    252 
    253             name.append(p / DateUtils.HOUR_IN_MILLIS);
    254             name.append(':');
    255 
    256             int min = p / 60000;
    257             min %= 60;
    258 
    259             if (min < 10) {
    260                 name.append('0');
    261             }
    262             name.append(min);
    263             name.append(") ");
    264             name.append(displayName);
    265             if (useDaylightTime && SHOW_DAYLIGHT_SAVINGS_INDICATOR) {
    266                 name.append(" \u2600"); // Sun symbol
    267             }
    268             return name.toString();
    269         }
    270     }
    271 
    272 
    273     /**
    274      * Returns an array of ids/time zones. This returns a double indexed array
    275      * of ids and time zones for Calendar. It is an inefficient method and
    276      * shouldn't be called often, but can be used for one time generation of
    277      * this list.
    278      *
    279      * @return double array of tz ids and tz names
    280      */
    281     public CharSequence[][] getAllTimezones() {
    282         Resources resources = this.getResources();
    283         String[] ids = resources.getStringArray(R.array.timezone_values);
    284         String[] labels = resources.getStringArray(R.array.timezone_labels);
    285         int minLength = ids.length;
    286         if (ids.length != labels.length) {
    287             minLength = Math.min(minLength, labels.length);
    288             Log.e("Timezone ids and labels have different length!");
    289         }
    290         List<TimeZoneRow> timezones = new ArrayList<TimeZoneRow>();
    291         for (int i = 0; i < minLength; i++) {
    292             timezones.add(new TimeZoneRow(ids[i], labels[i]));
    293         }
    294         Collections.sort(timezones);
    295 
    296         CharSequence[][] timeZones = new CharSequence[2][timezones.size()];
    297         int i = 0;
    298         for (TimeZoneRow row : timezones) {
    299             timeZones[0][i] = row.mId;
    300             timeZones[1][i++] = row.mDisplayName;
    301         }
    302         return timeZones;
    303     }
    304 
    305 }
    306