OSDN Git Service

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