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.AlarmManager; 21 import android.content.BroadcastReceiver; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.os.Bundle; 26 import android.provider.Settings; 27 import android.provider.Settings.SettingNotFoundException; 28 import android.support.v14.preference.PreferenceFragment; 29 import android.support.v7.preference.Preference; 30 import android.util.Log; 31 import android.view.View; 32 import android.view.View.OnClickListener; 33 import android.view.Window; 34 import android.view.inputmethod.InputMethodManager; 35 import android.widget.AdapterView; 36 import android.widget.AdapterView.OnItemClickListener; 37 import android.widget.Button; 38 import android.widget.CompoundButton; 39 import android.widget.CompoundButton.OnCheckedChangeListener; 40 import android.widget.DatePicker; 41 import android.widget.ListPopupWindow; 42 import android.widget.SimpleAdapter; 43 import android.widget.TimePicker; 44 45 import java.util.Calendar; 46 import java.util.TimeZone; 47 48 public class DateTimeSettingsSetupWizard extends Activity 49 implements OnClickListener, OnItemClickListener, OnCheckedChangeListener, 50 PreferenceFragment.OnPreferenceStartFragmentCallback { 51 private static final String TAG = DateTimeSettingsSetupWizard.class.getSimpleName(); 52 53 // force the first status of auto datetime flag. 54 private static final String EXTRA_INITIAL_AUTO_DATETIME_VALUE = 55 "extra_initial_auto_datetime_value"; 56 57 // If we have enough screen real estate, we use a radically different layout with 58 // big date and time pickers right on the screen, which requires very different handling. 59 // Otherwise, we use the standard date time settings fragment. 60 private boolean mUsingXLargeLayout; 61 62 /* Available only in XL */ 63 private CompoundButton mAutoDateTimeButton; 64 // private CompoundButton mAutoTimeZoneButton; 65 66 private Button mTimeZoneButton; 67 private ListPopupWindow mTimeZonePopup; 68 private SimpleAdapter mTimeZoneAdapter; 69 private TimeZone mSelectedTimeZone; 70 71 private TimePicker mTimePicker; 72 private DatePicker mDatePicker; 73 private InputMethodManager mInputMethodManager; 74 75 @Override onCreate(Bundle savedInstanceState)76 protected void onCreate(Bundle savedInstanceState) { 77 requestWindowFeature(Window.FEATURE_NO_TITLE); 78 super.onCreate(savedInstanceState); 79 setContentView(R.layout.date_time_settings_setupwizard); 80 81 // we know we've loaded the special xlarge layout because it has controls 82 // not present in the standard layout 83 mUsingXLargeLayout = findViewById(R.id.time_zone_button) != null; 84 if (mUsingXLargeLayout) { 85 initUiForXl(); 86 } else { 87 findViewById(R.id.next_button).setOnClickListener(this); 88 } 89 mTimeZoneAdapter = ZonePicker.constructTimezoneAdapter(this, false, 90 R.layout.date_time_setup_custom_list_item_2); 91 92 // For the normal view, disable Back since changes stick immediately 93 // and can't be canceled, and we already have a Next button. For xLarge, 94 // though, we save up our changes and set them upon Next, so Back can 95 // cancel. And also, in xlarge, we need the keyboard dismiss button 96 // to be available. 97 if (!mUsingXLargeLayout) { 98 final View layoutRoot = findViewById(R.id.layout_root); 99 layoutRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_BACK); 100 } 101 } 102 initUiForXl()103 public void initUiForXl() { 104 // Currently just comment out codes related to auto timezone. 105 // TODO: Remove them when we are sure they are unnecessary. 106 /* 107 final boolean autoTimeZoneEnabled = isAutoTimeZoneEnabled(); 108 mAutoTimeZoneButton = (CompoundButton)findViewById(R.id.time_zone_auto); 109 mAutoTimeZoneButton.setChecked(autoTimeZoneEnabled); 110 mAutoTimeZoneButton.setOnCheckedChangeListener(this); 111 mAutoTimeZoneButton.setText(autoTimeZoneEnabled ? R.string.zone_auto_summaryOn : 112 R.string.zone_auto_summaryOff);*/ 113 114 final TimeZone tz = TimeZone.getDefault(); 115 mSelectedTimeZone = tz; 116 mTimeZoneButton = (Button)findViewById(R.id.time_zone_button); 117 mTimeZoneButton.setText(tz.getDisplayName()); 118 mTimeZoneButton.setOnClickListener(this); 119 120 final boolean autoDateTimeEnabled; 121 final Intent intent = getIntent(); 122 if (intent.hasExtra(EXTRA_INITIAL_AUTO_DATETIME_VALUE)) { 123 autoDateTimeEnabled = intent.getBooleanExtra(EXTRA_INITIAL_AUTO_DATETIME_VALUE, false); 124 } else { 125 autoDateTimeEnabled = isAutoDateTimeEnabled(); 126 } 127 128 mAutoDateTimeButton = (CompoundButton)findViewById(R.id.date_time_auto_button); 129 mAutoDateTimeButton.setChecked(autoDateTimeEnabled); 130 mAutoDateTimeButton.setOnCheckedChangeListener(this); 131 132 mTimePicker = (TimePicker)findViewById(R.id.time_picker); 133 mTimePicker.setEnabled(!autoDateTimeEnabled); 134 mDatePicker = (DatePicker)findViewById(R.id.date_picker); 135 mDatePicker.setEnabled(!autoDateTimeEnabled); 136 mDatePicker.setCalendarViewShown(false); 137 DateTimeSettings.configureDatePicker(mDatePicker); 138 139 mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 140 141 ((Button)findViewById(R.id.next_button)).setOnClickListener(this); 142 final Button skipButton = (Button)findViewById(R.id.skip_button); 143 if (skipButton != null) { 144 skipButton.setOnClickListener(this); 145 } 146 } 147 148 @Override onResume()149 public void onResume() { 150 super.onResume(); 151 IntentFilter filter = new IntentFilter(); 152 filter.addAction(Intent.ACTION_TIME_TICK); 153 filter.addAction(Intent.ACTION_TIME_CHANGED); 154 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED); 155 registerReceiver(mIntentReceiver, filter, null, null); 156 } 157 158 @Override onPause()159 public void onPause() { 160 super.onPause(); 161 unregisterReceiver(mIntentReceiver); 162 } 163 164 @Override onClick(View view)165 public void onClick(View view) { 166 switch (view.getId()) { 167 case R.id.time_zone_button: { 168 showTimezonePicker(R.id.time_zone_button); 169 break; 170 } 171 case R.id.next_button: { 172 if (mSelectedTimeZone != null) { 173 final TimeZone systemTimeZone = TimeZone.getDefault(); 174 if (!systemTimeZone.equals(mSelectedTimeZone)) { 175 Log.i(TAG, "Another TimeZone is selected by a user. Changing system TimeZone."); 176 final AlarmManager alarm = (AlarmManager) 177 getSystemService(Context.ALARM_SERVICE); 178 alarm.setTimeZone(mSelectedTimeZone.getID()); 179 } 180 } 181 if (mAutoDateTimeButton != null) { 182 Settings.Global.putInt(getContentResolver(), Settings.Global.AUTO_TIME, 183 mAutoDateTimeButton.isChecked() ? 1 : 0); 184 if (!mAutoDateTimeButton.isChecked()) { 185 DateTimeSettings.setDate(this, mDatePicker.getYear(), mDatePicker.getMonth(), 186 mDatePicker.getDayOfMonth()); 187 DateTimeSettings.setTime(this, 188 mTimePicker.getCurrentHour(), mTimePicker.getCurrentMinute()); 189 } 190 } 191 } // $FALL-THROUGH$ 192 case R.id.skip_button: { 193 setResult(RESULT_OK); 194 finish(); 195 break; 196 } 197 } 198 } 199 200 @Override onCheckedChanged(CompoundButton buttonView, boolean isChecked)201 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 202 final boolean autoEnabled = isChecked; // just for readibility. 203 /*if (buttonView == mAutoTimeZoneButton) { 204 // In XL screen, we save all the state only when the next button is pressed. 205 if (!mUsingXLargeLayout) { 206 Settings.Global.putInt(getContentResolver(), 207 Settings.Global.AUTO_TIME_ZONE, 208 isChecked ? 1 : 0); 209 } 210 mTimeZone.setEnabled(!autoEnabled); 211 if (isChecked) { 212 findViewById(R.id.current_time_zone).setVisibility(View.VISIBLE); 213 findViewById(R.id.zone_picker).setVisibility(View.GONE); 214 } 215 } else */ 216 if (buttonView == mAutoDateTimeButton) { 217 Settings.Global.putInt(getContentResolver(), 218 Settings.Global.AUTO_TIME, 219 isChecked ? 1 : 0); 220 mTimePicker.setEnabled(!autoEnabled); 221 mDatePicker.setEnabled(!autoEnabled); 222 } 223 if (autoEnabled) { 224 final View focusedView = getCurrentFocus(); 225 if (focusedView != null) { 226 mInputMethodManager.hideSoftInputFromWindow(focusedView.getWindowToken(), 0); 227 focusedView.clearFocus(); 228 } 229 } 230 } 231 232 @Override onItemClick(AdapterView<?> parent, View view, int position, long id)233 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 234 final TimeZone tz = ZonePicker.obtainTimeZoneFromItem(parent.getItemAtPosition(position)); 235 if (mUsingXLargeLayout) { 236 mSelectedTimeZone = tz; 237 final Calendar now = Calendar.getInstance(tz); 238 if (mTimeZoneButton != null) { 239 mTimeZoneButton.setText(tz.getDisplayName()); 240 } 241 mDatePicker.updateDate(now.get(Calendar.YEAR), now.get(Calendar.MONTH), 242 now.get(Calendar.DAY_OF_MONTH)); 243 mTimePicker.setCurrentHour(now.get(Calendar.HOUR_OF_DAY)); 244 mTimePicker.setCurrentMinute(now.get(Calendar.MINUTE)); 245 } else { 246 // in prefs mode, we actually change the setting right now, as opposed to waiting 247 // until Next is pressed in xLarge mode 248 final AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 249 alarm.setTimeZone(tz.getID()); 250 DateTimeSettings settingsFragment = (DateTimeSettings) getFragmentManager(). 251 findFragmentById(R.id.date_time_settings_fragment); 252 settingsFragment.updateTimeAndDateDisplay(this); 253 } 254 mTimeZonePopup.dismiss(); 255 } 256 257 /** 258 * If this is called, that means we're in prefs style portrait mode for a large display 259 * and the user has tapped on the time zone preference. If we were a PreferenceActivity, 260 * we'd then launch the timezone fragment in a new activity, but we aren't, and here 261 * on a tablet display, we really want more of a popup picker look' like the one we use 262 * for the xlarge version of this activity. So we just take this opportunity to launch that. 263 * 264 * TODO: For phones, we might want to change this to do the "normal" opening 265 * of the zonepicker fragment in its own activity. Or we might end up just 266 * creating a separate DateTimeSettingsSetupWizardPhone activity that subclasses 267 * PreferenceActivity in the first place to handle all that automatically. 268 */ 269 @Override onPreferenceStartFragment(PreferenceFragment caller, Preference pref)270 public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) { 271 showTimezonePicker(R.id.timezone_dropdown_anchor); 272 return true; 273 } 274 showTimezonePicker(int anchorViewId)275 private void showTimezonePicker(int anchorViewId) { 276 View anchorView = findViewById(anchorViewId); 277 if (anchorView == null) { 278 Log.e(TAG, "Unable to find zone picker anchor view " + anchorViewId); 279 return; 280 } 281 mTimeZonePopup = new ListPopupWindow(this, null); 282 mTimeZonePopup.setWidth(anchorView.getWidth()); 283 mTimeZonePopup.setAnchorView(anchorView); 284 mTimeZonePopup.setAdapter(mTimeZoneAdapter); 285 mTimeZonePopup.setOnItemClickListener(this); 286 mTimeZonePopup.setModal(true); 287 mTimeZonePopup.show(); 288 } 289 isAutoDateTimeEnabled()290 private boolean isAutoDateTimeEnabled() { 291 try { 292 return Settings.Global.getInt(getContentResolver(), Settings.Global.AUTO_TIME) > 0; 293 } catch (SettingNotFoundException e) { 294 return true; 295 } 296 } 297 298 /* 299 private boolean isAutoTimeZoneEnabled() { 300 try { 301 return Settings.Global.getInt(getContentResolver(), 302 Settings.Global.AUTO_TIME_ZONE) > 0; 303 } catch (SettingNotFoundException e) { 304 return true; 305 } 306 }*/ 307 updateTimeAndDateDisplay()308 private void updateTimeAndDateDisplay() { 309 if (!mUsingXLargeLayout) { 310 return; 311 } 312 final Calendar now = Calendar.getInstance(); 313 mTimeZoneButton.setText(now.getTimeZone().getDisplayName()); 314 mDatePicker.updateDate(now.get(Calendar.YEAR), now.get(Calendar.MONTH), 315 now.get(Calendar.DAY_OF_MONTH)); 316 mTimePicker.setCurrentHour(now.get(Calendar.HOUR_OF_DAY)); 317 mTimePicker.setCurrentMinute(now.get(Calendar.MINUTE)); 318 } 319 320 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { 321 @Override 322 public void onReceive(Context context, Intent intent) { 323 updateTimeAndDateDisplay(); 324 } 325 }; 326 } 327