Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2008 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.settings;
     18 
     19 import android.app.Dialog;
     20 import android.app.DatePickerDialog;
     21 import android.app.TimePickerDialog;
     22 import android.content.BroadcastReceiver;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.IntentFilter;
     26 import android.content.SharedPreferences;
     27 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
     28 import android.os.Bundle;
     29 import android.os.SystemClock;
     30 import android.preference.CheckBoxPreference;
     31 import android.preference.ListPreference;
     32 import android.preference.Preference;
     33 import android.preference.PreferenceActivity;
     34 import android.preference.PreferenceScreen;
     35 import android.provider.Settings;
     36 import android.provider.Settings.SettingNotFoundException;
     37 import android.text.format.DateFormat;
     38 import android.widget.DatePicker;
     39 import android.widget.TimePicker;
     40 
     41 import java.util.Calendar;
     42 import java.util.Date;
     43 import java.util.TimeZone;
     44 
     45 public class DateTimeSettings
     46         extends PreferenceActivity
     47         implements OnSharedPreferenceChangeListener,
     48                 TimePickerDialog.OnTimeSetListener , DatePickerDialog.OnDateSetListener {
     49 
     50     private static final String HOURS_12 = "12";
     51     private static final String HOURS_24 = "24";
     52 
     53     private Calendar mDummyDate;
     54     private static final String KEY_DATE_FORMAT = "date_format";
     55     private static final String KEY_AUTO_TIME = "auto_time";
     56 
     57     private static final int DIALOG_DATEPICKER = 0;
     58     private static final int DIALOG_TIMEPICKER = 1;
     59 
     60     private CheckBoxPreference mAutoPref;
     61     private Preference mTimePref;
     62     private Preference mTime24Pref;
     63     private Preference mTimeZone;
     64     private Preference mDatePref;
     65     private ListPreference mDateFormat;
     66 
     67     @Override
     68     protected void onCreate(Bundle icicle) {
     69         super.onCreate(icicle);
     70 
     71         addPreferencesFromResource(R.xml.date_time_prefs);
     72 
     73         initUI();
     74     }
     75 
     76     private void initUI() {
     77         boolean autoEnabled = getAutoState();
     78 
     79         mDummyDate = Calendar.getInstance();
     80         mDummyDate.set(mDummyDate.get(Calendar.YEAR), 11, 31, 13, 0, 0);
     81 
     82         mAutoPref = (CheckBoxPreference) findPreference(KEY_AUTO_TIME);
     83         mAutoPref.setChecked(autoEnabled);
     84         mTimePref = findPreference("time");
     85         mTime24Pref = findPreference("24 hour");
     86         mTimeZone = findPreference("timezone");
     87         mDatePref = findPreference("date");
     88         mDateFormat = (ListPreference) findPreference(KEY_DATE_FORMAT);
     89 
     90         String [] dateFormats = getResources().getStringArray(R.array.date_format_values);
     91         String [] formattedDates = new String[dateFormats.length];
     92         String currentFormat = getDateFormat();
     93         // Initialize if DATE_FORMAT is not set in the system settings
     94         // This can happen after a factory reset (or data wipe)
     95         if (currentFormat == null) {
     96             currentFormat = "";
     97         }
     98         for (int i = 0; i < formattedDates.length; i++) {
     99             String formatted =
    100                 DateFormat.getDateFormatForSetting(this, dateFormats[i]).
    101                     format(mDummyDate.getTime());
    102 
    103             if (dateFormats[i].length() == 0) {
    104                 formattedDates[i] = getResources().
    105                     getString(R.string.normal_date_format, formatted);
    106             } else {
    107                 formattedDates[i] = formatted;
    108             }
    109         }
    110 
    111         mDateFormat.setEntries(formattedDates);
    112         mDateFormat.setEntryValues(R.array.date_format_values);
    113         mDateFormat.setValue(currentFormat);
    114 
    115         mTimePref.setEnabled(!autoEnabled);
    116         mDatePref.setEnabled(!autoEnabled);
    117         mTimeZone.setEnabled(!autoEnabled);
    118     }
    119 
    120 
    121     @Override
    122     protected void onResume() {
    123         super.onResume();
    124 
    125         getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    126 
    127         ((CheckBoxPreference)mTime24Pref).setChecked(is24Hour());
    128 
    129         // Register for time ticks and other reasons for time change
    130         IntentFilter filter = new IntentFilter();
    131         filter.addAction(Intent.ACTION_TIME_TICK);
    132         filter.addAction(Intent.ACTION_TIME_CHANGED);
    133         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
    134         registerReceiver(mIntentReceiver, filter, null, null);
    135 
    136         updateTimeAndDateDisplay();
    137     }
    138 
    139     @Override
    140     protected void onPause() {
    141         super.onPause();
    142         unregisterReceiver(mIntentReceiver);
    143         getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    144     }
    145 
    146     private void updateTimeAndDateDisplay() {
    147         java.text.DateFormat shortDateFormat = DateFormat.getDateFormat(this);
    148         Date now = Calendar.getInstance().getTime();
    149         Date dummyDate = mDummyDate.getTime();
    150         mTimePref.setSummary(DateFormat.getTimeFormat(this).format(now));
    151         mTimeZone.setSummary(getTimeZoneText());
    152         mDatePref.setSummary(shortDateFormat.format(now));
    153         mDateFormat.setSummary(shortDateFormat.format(dummyDate));
    154     }
    155 
    156     public void onDateSet(DatePicker view, int year, int month, int day) {
    157         Calendar c = Calendar.getInstance();
    158 
    159         c.set(Calendar.YEAR, year);
    160         c.set(Calendar.MONTH, month);
    161         c.set(Calendar.DAY_OF_MONTH, day);
    162         long when = c.getTimeInMillis();
    163 
    164         if (when / 1000 < Integer.MAX_VALUE) {
    165             SystemClock.setCurrentTimeMillis(when);
    166         }
    167         updateTimeAndDateDisplay();
    168     }
    169 
    170     public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
    171         Calendar c = Calendar.getInstance();
    172 
    173         c.set(Calendar.HOUR_OF_DAY, hourOfDay);
    174         c.set(Calendar.MINUTE, minute);
    175         long when = c.getTimeInMillis();
    176 
    177         if (when / 1000 < Integer.MAX_VALUE) {
    178             SystemClock.setCurrentTimeMillis(when);
    179         }
    180         updateTimeAndDateDisplay();
    181 
    182         // We don't need to call timeUpdated() here because the TIME_CHANGED
    183         // broadcast is sent by the AlarmManager as a side effect of setting the
    184         // SystemClock time.
    185     }
    186 
    187     public void onSharedPreferenceChanged(SharedPreferences preferences, String key) {
    188         if (key.equals(KEY_DATE_FORMAT)) {
    189             String format = preferences.getString(key,
    190                     getResources().getString(R.string.default_date_format));
    191             Settings.System.putString(getContentResolver(),
    192                     Settings.System.DATE_FORMAT, format);
    193             updateTimeAndDateDisplay();
    194         } else if (key.equals(KEY_AUTO_TIME)) {
    195             boolean autoEnabled = preferences.getBoolean(key, true);
    196             Settings.System.putInt(getContentResolver(),
    197                     Settings.System.AUTO_TIME,
    198                     autoEnabled ? 1 : 0);
    199             mTimePref.setEnabled(!autoEnabled);
    200             mDatePref.setEnabled(!autoEnabled);
    201             mTimeZone.setEnabled(!autoEnabled);
    202         }
    203     }
    204 
    205     @Override
    206     public Dialog onCreateDialog(int id) {
    207         Dialog d;
    208 
    209         switch (id) {
    210         case DIALOG_DATEPICKER: {
    211             final Calendar calendar = Calendar.getInstance();
    212             d = new DatePickerDialog(
    213                 this,
    214                 this,
    215                 calendar.get(Calendar.YEAR),
    216                 calendar.get(Calendar.MONTH),
    217                 calendar.get(Calendar.DAY_OF_MONTH));
    218             d.setTitle(getResources().getString(R.string.date_time_changeDate_text));
    219             break;
    220         }
    221         case DIALOG_TIMEPICKER: {
    222             final Calendar calendar = Calendar.getInstance();
    223             d = new TimePickerDialog(
    224                     this,
    225                     this,
    226                     calendar.get(Calendar.HOUR_OF_DAY),
    227                     calendar.get(Calendar.MINUTE),
    228                     DateFormat.is24HourFormat(this));
    229             d.setTitle(getResources().getString(R.string.date_time_changeTime_text));
    230             break;
    231         }
    232         default:
    233             d = null;
    234             break;
    235         }
    236 
    237         return d;
    238     }
    239 
    240     @Override
    241     public void onPrepareDialog(int id, Dialog d) {
    242         switch (id) {
    243         case DIALOG_DATEPICKER: {
    244             DatePickerDialog datePicker = (DatePickerDialog)d;
    245             final Calendar calendar = Calendar.getInstance();
    246             datePicker.updateDate(
    247                     calendar.get(Calendar.YEAR),
    248                     calendar.get(Calendar.MONTH),
    249                     calendar.get(Calendar.DAY_OF_MONTH));
    250             break;
    251         }
    252         case DIALOG_TIMEPICKER: {
    253             TimePickerDialog timePicker = (TimePickerDialog)d;
    254             final Calendar calendar = Calendar.getInstance();
    255             timePicker.updateTime(
    256                     calendar.get(Calendar.HOUR_OF_DAY),
    257                     calendar.get(Calendar.MINUTE));
    258             break;
    259         }
    260         default:
    261             break;
    262         }
    263     }
    264 
    265     @Override
    266     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
    267         if (preference == mDatePref) {
    268             showDialog(DIALOG_DATEPICKER);
    269         } else if (preference == mTimePref) {
    270             // The 24-hour mode may have changed, so recreate the dialog
    271             removeDialog(DIALOG_TIMEPICKER);
    272             showDialog(DIALOG_TIMEPICKER);
    273         } else if (preference == mTime24Pref) {
    274             set24Hour(((CheckBoxPreference)mTime24Pref).isChecked());
    275             updateTimeAndDateDisplay();
    276             timeUpdated();
    277         } else if (preference == mTimeZone) {
    278             Intent intent = new Intent();
    279             intent.setClass(this, ZoneList.class);
    280             startActivityForResult(intent, 0);
    281         }
    282         return false;
    283     }
    284 
    285     @Override
    286     protected void onActivityResult(int requestCode, int resultCode,
    287             Intent data) {
    288         updateTimeAndDateDisplay();
    289     }
    290 
    291     private void timeUpdated() {
    292         Intent timeChanged = new Intent(Intent.ACTION_TIME_CHANGED);
    293         sendBroadcast(timeChanged);
    294     }
    295 
    296     /*  Get & Set values from the system settings  */
    297 
    298     private boolean is24Hour() {
    299         return DateFormat.is24HourFormat(this);
    300     }
    301 
    302     private void set24Hour(boolean is24Hour) {
    303         Settings.System.putString(getContentResolver(),
    304                 Settings.System.TIME_12_24,
    305                 is24Hour? HOURS_24 : HOURS_12);
    306     }
    307 
    308     private String getDateFormat() {
    309         return Settings.System.getString(getContentResolver(),
    310                 Settings.System.DATE_FORMAT);
    311     }
    312 
    313     private boolean getAutoState() {
    314         try {
    315             return Settings.System.getInt(getContentResolver(),
    316                 Settings.System.AUTO_TIME) > 0;
    317         } catch (SettingNotFoundException snfe) {
    318             return true;
    319         }
    320     }
    321 
    322     private void setDateFormat(String format) {
    323         if (format.length() == 0) {
    324             format = null;
    325         }
    326 
    327         Settings.System.putString(getContentResolver(), Settings.System.DATE_FORMAT, format);
    328     }
    329 
    330     /*  Helper routines to format timezone */
    331 
    332     private String getTimeZoneText() {
    333         TimeZone    tz = java.util.Calendar.getInstance().getTimeZone();
    334         boolean daylight = tz.inDaylightTime(new Date());
    335         StringBuilder sb = new StringBuilder();
    336 
    337         sb.append(formatOffset(tz.getRawOffset() +
    338                                (daylight ? tz.getDSTSavings() : 0))).
    339             append(", ").
    340             append(tz.getDisplayName(daylight, TimeZone.LONG));
    341 
    342         return sb.toString();
    343     }
    344 
    345     private char[] formatOffset(int off) {
    346         off = off / 1000 / 60;
    347 
    348         char[] buf = new char[9];
    349         buf[0] = 'G';
    350         buf[1] = 'M';
    351         buf[2] = 'T';
    352 
    353         if (off < 0) {
    354             buf[3] = '-';
    355             off = -off;
    356         } else {
    357             buf[3] = '+';
    358         }
    359 
    360         int hours = off / 60;
    361         int minutes = off % 60;
    362 
    363         buf[4] = (char) ('0' + hours / 10);
    364         buf[5] = (char) ('0' + hours % 10);
    365 
    366         buf[6] = ':';
    367 
    368         buf[7] = (char) ('0' + minutes / 10);
    369         buf[8] = (char) ('0' + minutes % 10);
    370 
    371         return buf;
    372     }
    373 
    374     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
    375         @Override
    376         public void onReceive(Context context, Intent intent) {
    377             updateTimeAndDateDisplay();
    378         }
    379     };
    380 }
    381