OSDN Git Service

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