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