blob: 32a7b0a440ed988587b28b6c9642306183ca5f72 [file] [log] [blame]
The Android Open Source Project5fedae02009-03-03 19:32:15 -08001/*
2 * Copyright (C) 2007 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
Daniel Sandlerfa954242009-10-16 16:12:30 -040017package com.android.deskclock;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080018
Patrick Scott90c48332009-11-23 14:46:44 -050019import android.app.AlertDialog;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080020import android.content.Context;
Patrick Scott90c48332009-11-23 14:46:44 -050021import android.content.DialogInterface;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080022import android.content.Intent;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080023import android.os.Bundle;
Patrick Scott6064d3f2010-03-03 10:23:16 -050024import android.os.Handler;
Patrick Scottbed2fe92010-12-07 13:50:50 -050025import android.os.Vibrator;
The Android Open Source Project185d1792009-03-05 14:34:37 -080026import android.preference.CheckBoxPreference;
27import android.preference.EditTextPreference;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080028import android.preference.Preference;
29import android.preference.PreferenceActivity;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080030import android.preference.PreferenceScreen;
31import android.text.format.DateFormat;
Patrick Scottb83db522009-04-30 08:23:05 -040032import android.view.LayoutInflater;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080033import android.view.Menu;
34import android.view.MenuItem;
Patrick Scottb83db522009-04-30 08:23:05 -040035import android.view.View;
36import android.view.ViewGroup.LayoutParams;
37import android.widget.Button;
38import android.widget.FrameLayout;
39import android.widget.LinearLayout;
40import android.widget.ListView;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080041import android.widget.TimePicker;
42import android.widget.Toast;
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -070043import android.widget.TimePicker.OnTimeChangedListener;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080044
45/**
46 * Manages each alarm
47 */
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -070048public class SetAlarm extends PreferenceActivity implements Preference.OnPreferenceChangeListener,
49 OnTimeChangedListener {
The Android Open Source Project5fedae02009-03-03 19:32:15 -080050
The Android Open Source Project185d1792009-03-05 14:34:37 -080051 private EditTextPreference mLabel;
Patrick Scott90c48332009-11-23 14:46:44 -050052 private CheckBoxPreference mEnabledPref;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080053 private Preference mTimePref;
54 private AlarmPreference mAlarmPref;
55 private CheckBoxPreference mVibratePref;
56 private RepeatPreference mRepeatPref;
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -070057 private TimePicker mTimePicker;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080058
Patrick Scott7495b002009-09-30 15:05:55 -040059 private int mId;
Patrick Scott7495b002009-09-30 15:05:55 -040060 private int mHour;
61 private int mMinutes;
Patrick Scott69b223a2010-02-26 08:18:46 -050062 private boolean mTimePickerCancelled;
Patrick Scott6064d3f2010-03-03 10:23:16 -050063 private Alarm mOriginalAlarm;
The Android Open Source Project5fedae02009-03-03 19:32:15 -080064
The Android Open Source Project5fedae02009-03-03 19:32:15 -080065 @Override
66 protected void onCreate(Bundle icicle) {
67 super.onCreate(icicle);
68
Patrick Scottfe8dd392010-01-20 12:50:10 -050069 // Override the default content view.
70 setContentView(R.layout.set_alarm);
71
The Android Open Source Project5fedae02009-03-03 19:32:15 -080072 addPreferencesFromResource(R.xml.alarm_prefs);
Patrick Scottb83db522009-04-30 08:23:05 -040073
74 // Get each preference so we can retrieve the value later.
The Android Open Source Project185d1792009-03-05 14:34:37 -080075 mLabel = (EditTextPreference) findPreference("label");
76 mLabel.setOnPreferenceChangeListener(
77 new Preference.OnPreferenceChangeListener() {
78 public boolean onPreferenceChange(Preference p,
79 Object newValue) {
Patrick Scott6064d3f2010-03-03 10:23:16 -050080 String val = (String) newValue;
Patrick Scottb83db522009-04-30 08:23:05 -040081 // Set the summary based on the new label.
Patrick Scott6064d3f2010-03-03 10:23:16 -050082 p.setSummary(val);
83 if (val != null && !val.equals(mLabel.getText())) {
84 // Call through to the generic listener.
85 return SetAlarm.this.onPreferenceChange(p,
86 newValue);
87 }
The Android Open Source Project185d1792009-03-05 14:34:37 -080088 return true;
89 }
90 });
Patrick Scott90c48332009-11-23 14:46:44 -050091 mEnabledPref = (CheckBoxPreference) findPreference("enabled");
Patrick Scott6064d3f2010-03-03 10:23:16 -050092 mEnabledPref.setOnPreferenceChangeListener(
93 new Preference.OnPreferenceChangeListener() {
94 public boolean onPreferenceChange(Preference p,
95 Object newValue) {
96 // Pop a toast when enabling alarms.
97 if (!mEnabledPref.isChecked()) {
98 popAlarmSetToast(SetAlarm.this, mHour, mMinutes,
99 mRepeatPref.getDaysOfWeek());
100 }
101 return SetAlarm.this.onPreferenceChange(p, newValue);
102 }
103 });
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800104 mTimePref = findPreference("time");
105 mAlarmPref = (AlarmPreference) findPreference("alarm");
Patrick Scott6064d3f2010-03-03 10:23:16 -0500106 mAlarmPref.setOnPreferenceChangeListener(this);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800107 mVibratePref = (CheckBoxPreference) findPreference("vibrate");
Patrick Scott6064d3f2010-03-03 10:23:16 -0500108 mVibratePref.setOnPreferenceChangeListener(this);
Patrick Scottbed2fe92010-12-07 13:50:50 -0500109 Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
110 if (!v.hasVibrator()) {
111 getPreferenceScreen().removePreference(mVibratePref);
112 }
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800113 mRepeatPref = (RepeatPreference) findPreference("setRepeat");
Patrick Scott6064d3f2010-03-03 10:23:16 -0500114 mRepeatPref.setOnPreferenceChangeListener(this);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800115
116 Intent i = getIntent();
Patrick Scott77f14bd2010-12-15 11:15:52 -0500117 Alarm alarm = i.getParcelableExtra(Alarms.ALARM_INTENT_EXTRA);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800118
Patrick Scott77f14bd2010-12-15 11:15:52 -0500119 if (alarm == null) {
120 // No alarm means create a new alarm.
Patrick Scotte46be902010-01-27 08:58:13 -0500121 alarm = new Alarm();
Patrick Scottd56e7eb2009-10-12 08:35:36 -0400122 }
Patrick Scott6064d3f2010-03-03 10:23:16 -0500123 mOriginalAlarm = alarm;
124
Patrick Scott77f14bd2010-12-15 11:15:52 -0500125 // Populate the prefs with the original alarm data. updatePrefs also
126 // sets mId so it must be called before checking mId below.
Patrick Scott6064d3f2010-03-03 10:23:16 -0500127 updatePrefs(mOriginalAlarm);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800128
Patrick Scottb83db522009-04-30 08:23:05 -0400129 // We have to do this to get the save/cancel buttons to highlight on
130 // their own.
131 getListView().setItemsCanFocus(true);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800132
Patrick Scottb83db522009-04-30 08:23:05 -0400133 // Attach actions to each button.
Patrick Scottfe8dd392010-01-20 12:50:10 -0500134 Button b = (Button) findViewById(R.id.alarm_save);
Patrick Scottb83db522009-04-30 08:23:05 -0400135 b.setOnClickListener(new View.OnClickListener() {
136 public void onClick(View v) {
137 saveAlarm();
138 finish();
139 }
140 });
Patrick Scott6064d3f2010-03-03 10:23:16 -0500141 final Button revert = (Button) findViewById(R.id.alarm_revert);
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -0700142 revert.setEnabled(true);
Patrick Scott6064d3f2010-03-03 10:23:16 -0500143 revert.setOnClickListener(new View.OnClickListener() {
Erik73327b32011-08-24 09:48:58 -0700144 public void onClick(View v) {
145 int newId = mId;
146 updatePrefs(mOriginalAlarm);
147 // "Revert" on a newly created alarm should delete it.
148 if (mOriginalAlarm.id == -1) {
149 Alarms.deleteAlarm(SetAlarm.this, newId);
150 } else {
151 saveAlarm();
Patrick Scottb83db522009-04-30 08:23:05 -0400152 }
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -0700153 revert.setEnabled(true);
Erik73327b32011-08-24 09:48:58 -0700154 finish();
155 }
Patrick Scottb83db522009-04-30 08:23:05 -0400156 });
Patrick Scottfe8dd392010-01-20 12:50:10 -0500157 b = (Button) findViewById(R.id.alarm_delete);
Patrick Scottc9c1acd2010-02-17 09:03:11 -0500158 if (mId == -1) {
159 b.setEnabled(false);
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -0700160 b.setVisibility(View.GONE);
Patrick Scottc9c1acd2010-02-17 09:03:11 -0500161 } else {
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -0700162 b.setVisibility(View.VISIBLE);
Patrick Scottc9c1acd2010-02-17 09:03:11 -0500163 b.setOnClickListener(new View.OnClickListener() {
Patrick Scott90c48332009-11-23 14:46:44 -0500164 public void onClick(View v) {
165 deleteAlarm();
166 }
Patrick Scottc9c1acd2010-02-17 09:03:11 -0500167 });
168 }
Patrick Scotte46be902010-01-27 08:58:13 -0500169
170 // The last thing we do is pop the time picker if this is a new alarm.
Patrick Scott6064d3f2010-03-03 10:23:16 -0500171 if (mId == -1) {
Patrick Scott69b223a2010-02-26 08:18:46 -0500172 // Assume the user hit cancel
173 mTimePickerCancelled = true;
Patrick Scotte46be902010-01-27 08:58:13 -0500174 showTimePicker();
175 }
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800176 }
177
Patrick Scott6064d3f2010-03-03 10:23:16 -0500178 // Used to post runnables asynchronously.
179 private static final Handler sHandler = new Handler();
180
Patrick Scott585d4e42010-03-08 10:27:52 -0500181 public boolean onPreferenceChange(final Preference p, Object newValue) {
Patrick Scott6064d3f2010-03-03 10:23:16 -0500182 // Asynchronously save the alarm since this method is called _before_
183 // the value of the preference has changed.
184 sHandler.post(new Runnable() {
185 public void run() {
Patrick Scott585d4e42010-03-08 10:27:52 -0500186 // Editing any preference (except enable) enables the alarm.
187 if (p != mEnabledPref) {
188 mEnabledPref.setChecked(true);
189 }
Patrick Scott6064d3f2010-03-03 10:23:16 -0500190 saveAlarmAndEnableRevert();
191 }
192 });
193 return true;
194 }
195
196 private void updatePrefs(Alarm alarm) {
197 mId = alarm.id;
198 mEnabledPref.setChecked(alarm.enabled);
199 mLabel.setText(alarm.label);
200 mLabel.setSummary(alarm.label);
201 mHour = alarm.hour;
202 mMinutes = alarm.minutes;
203 mRepeatPref.setDaysOfWeek(alarm.daysOfWeek);
204 mVibratePref.setChecked(alarm.vibrate);
205 // Give the alert uri to the preference.
206 mAlarmPref.setAlert(alarm.alert);
207 updateTime();
208 }
209
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800210 @Override
Patrick Scottb83db522009-04-30 08:23:05 -0400211 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
212 Preference preference) {
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800213 if (preference == mTimePref) {
Patrick Scotte46be902010-01-27 08:58:13 -0500214 showTimePicker();
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800215 }
216
217 return super.onPreferenceTreeClick(preferenceScreen, preference);
218 }
219
Patrick Scott7495b002009-09-30 15:05:55 -0400220 @Override
221 public void onBackPressed() {
Patrick Scott69b223a2010-02-26 08:18:46 -0500222 // In the usual case of viewing an alarm, mTimePickerCancelled is
223 // initialized to false. When creating a new alarm, this value is
224 // assumed true until the user changes the time.
225 if (!mTimePickerCancelled) {
226 saveAlarm();
227 }
Patrick Scott7495b002009-09-30 15:05:55 -0400228 finish();
229 }
230
Patrick Scotte46be902010-01-27 08:58:13 -0500231 private void showTimePicker() {
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -0700232 mTimePicker = (TimePicker) findViewById(R.id.timePicker);
233 mTimePicker.setCurrentHour(mHour);
234 mTimePicker.setCurrentMinute(mMinutes);
235 mTimePicker.setIs24HourView(DateFormat.is24HourFormat(this));
236 mTimePicker.setVisibility(View.VISIBLE);
237 mTimePicker.setOnTimeChangedListener(this);
Patrick Scotte46be902010-01-27 08:58:13 -0500238 }
239
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -0700240
241 @Override
242 public void onTimeChanged(TimePicker timePicker, int hourOfDay, int minute) {
Patrick Scott69b223a2010-02-26 08:18:46 -0500243 // onTimeSet is called when the user clicks "Set"
244 mTimePickerCancelled = false;
Mindy Pereirad2ee3ef2011-08-30 10:52:31 -0700245 mHour = timePicker.getCurrentHour();
246 mMinutes = timePicker.getCurrentMinute();
Patrick Scottb83db522009-04-30 08:23:05 -0400247 updateTime();
Patrick Scott7495b002009-09-30 15:05:55 -0400248 // If the time has been changed, enable the alarm.
Patrick Scott90c48332009-11-23 14:46:44 -0500249 mEnabledPref.setChecked(true);
Patrick Scott6064d3f2010-03-03 10:23:16 -0500250 // Save the alarm and pop a toast.
251 popAlarmSetToast(this, saveAlarmAndEnableRevert());
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800252 }
253
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800254 private void updateTime() {
Patrick Scottb83db522009-04-30 08:23:05 -0400255 if (Log.LOGV) {
256 Log.v("updateTime " + mId);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800257 }
Patrick Scottb83db522009-04-30 08:23:05 -0400258 mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
259 mRepeatPref.getDaysOfWeek()));
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800260 }
261
Patrick Scott6064d3f2010-03-03 10:23:16 -0500262 private long saveAlarmAndEnableRevert() {
263 // Enable "Revert" to go back to the original Alarm.
264 final Button revert = (Button) findViewById(R.id.alarm_revert);
265 revert.setEnabled(true);
266 return saveAlarm();
267 }
268
269 private long saveAlarm() {
Patrick Scotte46be902010-01-27 08:58:13 -0500270 Alarm alarm = new Alarm();
271 alarm.id = mId;
272 alarm.enabled = mEnabledPref.isChecked();
273 alarm.hour = mHour;
274 alarm.minutes = mMinutes;
275 alarm.daysOfWeek = mRepeatPref.getDaysOfWeek();
276 alarm.vibrate = mVibratePref.isChecked();
277 alarm.label = mLabel.getText();
278 alarm.alert = mAlarmPref.getAlert();
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800279
Patrick Scotte46be902010-01-27 08:58:13 -0500280 long time;
Patrick Scott6064d3f2010-03-03 10:23:16 -0500281 if (alarm.id == -1) {
Patrick Scotte46be902010-01-27 08:58:13 -0500282 time = Alarms.addAlarm(this, alarm);
Patrick Scott6064d3f2010-03-03 10:23:16 -0500283 // addAlarm populates the alarm with the new id. Update mId so that
284 // changes to other preferences update the new alarm.
285 mId = alarm.id;
Patrick Scotte46be902010-01-27 08:58:13 -0500286 } else {
287 time = Alarms.setAlarm(this, alarm);
288 }
Patrick Scott6064d3f2010-03-03 10:23:16 -0500289 return time;
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800290 }
291
Patrick Scott90c48332009-11-23 14:46:44 -0500292 private void deleteAlarm() {
293 new AlertDialog.Builder(this)
294 .setTitle(getString(R.string.delete_alarm))
295 .setMessage(getString(R.string.delete_alarm_confirm))
296 .setPositiveButton(android.R.string.ok,
297 new DialogInterface.OnClickListener() {
298 public void onClick(DialogInterface d, int w) {
299 Alarms.deleteAlarm(SetAlarm.this, mId);
300 finish();
301 }
302 })
303 .setNegativeButton(android.R.string.cancel, null)
304 .show();
305 }
306
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800307 /**
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800308 * Display a toast that tells the user how long until the alarm
309 * goes off. This helps prevent "am/pm" mistakes.
310 */
311 static void popAlarmSetToast(Context context, int hour, int minute,
Patrick Scottd776e512009-06-26 14:52:56 -0400312 Alarm.DaysOfWeek daysOfWeek) {
Patrick Scottc7edd6e2009-11-09 14:59:05 -0500313 popAlarmSetToast(context,
314 Alarms.calculateAlarm(hour, minute, daysOfWeek)
315 .getTimeInMillis());
316 }
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800317
Patrick Scott5ad90262010-09-28 16:04:48 -0400318 static void popAlarmSetToast(Context context, long timeInMillis) {
Patrick Scottc7edd6e2009-11-09 14:59:05 -0500319 String toastText = formatToast(context, timeInMillis);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800320 Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
321 ToastMaster.setToast(toast);
322 toast.show();
323 }
324
325 /**
326 * format "Alarm set for 2 days 7 hours and 53 minutes from
327 * now"
328 */
Patrick Scottc7edd6e2009-11-09 14:59:05 -0500329 static String formatToast(Context context, long timeInMillis) {
330 long delta = timeInMillis - System.currentTimeMillis();
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800331 long hours = delta / (1000 * 60 * 60);
332 long minutes = delta / (1000 * 60) % 60;
333 long days = hours / 24;
334 hours = hours % 24;
335
336 String daySeq = (days == 0) ? "" :
337 (days == 1) ? context.getString(R.string.day) :
338 context.getString(R.string.days, Long.toString(days));
339
340 String minSeq = (minutes == 0) ? "" :
341 (minutes == 1) ? context.getString(R.string.minute) :
342 context.getString(R.string.minutes, Long.toString(minutes));
343
344 String hourSeq = (hours == 0) ? "" :
345 (hours == 1) ? context.getString(R.string.hour) :
346 context.getString(R.string.hours, Long.toString(hours));
347
348 boolean dispDays = days > 0;
349 boolean dispHour = hours > 0;
350 boolean dispMinute = minutes > 0;
351
Eric Fischer1bc128f2009-07-21 16:28:30 -0700352 int index = (dispDays ? 1 : 0) |
353 (dispHour ? 2 : 0) |
354 (dispMinute ? 4 : 0);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800355
Eric Fischer1bc128f2009-07-21 16:28:30 -0700356 String[] formats = context.getResources().getStringArray(R.array.alarm_set);
357 return String.format(formats[index], daySeq, hourSeq, minSeq);
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800358 }
The Android Open Source Project5fedae02009-03-03 19:32:15 -0800359}