OSDN Git Service

Always enable the alarm when clicking done.
[android-x86/packages-apps-DeskClock.git] / src / com / android / alarmclock / SetAlarm.java
1 /*
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
17 package com.android.alarmclock;
18
19 import android.app.TimePickerDialog;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.media.RingtoneManager;
23 import android.net.Uri;
24 import android.os.Bundle;
25 import android.preference.CheckBoxPreference;
26 import android.preference.EditTextPreference;
27 import android.preference.Preference;
28 import android.preference.PreferenceActivity;
29 import android.preference.PreferenceScreen;
30 import android.text.format.DateFormat;
31 import android.view.LayoutInflater;
32 import android.view.Menu;
33 import android.view.MenuItem;
34 import android.view.View;
35 import android.view.ViewGroup.LayoutParams;
36 import android.widget.Button;
37 import android.widget.FrameLayout;
38 import android.widget.LinearLayout;
39 import android.widget.ListView;
40 import android.widget.TimePicker;
41 import android.widget.Toast;
42
43 /**
44  * Manages each alarm
45  */
46 public class SetAlarm extends PreferenceActivity
47         implements TimePickerDialog.OnTimeSetListener {
48
49     private EditTextPreference mLabel;
50     private Preference mTimePref;
51     private AlarmPreference mAlarmPref;
52     private CheckBoxPreference mVibratePref;
53     private RepeatPreference mRepeatPref;
54     private MenuItem mDeleteAlarmItem;
55     private MenuItem mTestAlarmItem;
56
57     private int     mId;
58     private boolean mEnabled;
59     private int     mHour;
60     private int     mMinutes;
61
62     /**
63      * Set an alarm.  Requires an Alarms.ALARM_ID to be passed in as an
64      * extra. FIXME: Pass an Alarm object like every other Activity.
65      */
66     @Override
67     protected void onCreate(Bundle icicle) {
68         super.onCreate(icicle);
69
70         addPreferencesFromResource(R.xml.alarm_prefs);
71
72         // Get each preference so we can retrieve the value later.
73         mLabel = (EditTextPreference) findPreference("label");
74         mLabel.setOnPreferenceChangeListener(
75                 new Preference.OnPreferenceChangeListener() {
76                     public boolean onPreferenceChange(Preference p,
77                             Object newValue) {
78                         // Set the summary based on the new label.
79                         p.setSummary((String) newValue);
80                         return true;
81                     }
82                 });
83         mTimePref = findPreference("time");
84         mAlarmPref = (AlarmPreference) findPreference("alarm");
85         mVibratePref = (CheckBoxPreference) findPreference("vibrate");
86         mRepeatPref = (RepeatPreference) findPreference("setRepeat");
87
88         Intent i = getIntent();
89         mId = i.getIntExtra(Alarms.ALARM_ID, -1);
90         if (Log.LOGV) {
91             Log.v("In SetAlarm, alarm id = " + mId);
92         }
93
94         /* load alarm details from database */
95         Alarm alarm = Alarms.getAlarm(getContentResolver(), mId);
96         mEnabled = alarm.enabled;
97         mLabel.setText(alarm.label);
98         mLabel.setSummary(alarm.label);
99         mHour = alarm.hour;
100         mMinutes = alarm.minutes;
101         mRepeatPref.setDaysOfWeek(alarm.daysOfWeek);
102         mVibratePref.setChecked(alarm.vibrate);
103         // Give the alert uri to the preference.
104         mAlarmPref.setAlert(alarm.alert);
105         updateTime();
106
107         // We have to do this to get the save/cancel buttons to highlight on
108         // their own.
109         getListView().setItemsCanFocus(true);
110
111         // Grab the content view so we can modify it.
112         FrameLayout content = (FrameLayout) getWindow().getDecorView()
113                 .findViewById(com.android.internal.R.id.content);
114
115         // Get the main ListView and remove it from the content view.
116         ListView lv = getListView();
117         content.removeView(lv);
118
119         // Create the new LinearLayout that will become the content view and
120         // make it vertical.
121         LinearLayout ll = new LinearLayout(this);
122         ll.setOrientation(LinearLayout.VERTICAL);
123
124         // Have the ListView expand to fill the screen minus the save/cancel
125         // buttons.
126         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
127                 LayoutParams.FILL_PARENT,
128                 LayoutParams.WRAP_CONTENT);
129         lp.weight = 1;
130         ll.addView(lv, lp);
131
132         // Inflate the buttons onto the LinearLayout.
133         View v = LayoutInflater.from(this).inflate(
134                 R.layout.save_cancel_alarm, ll);
135
136         // Attach actions to each button.
137         Button b = (Button) v.findViewById(R.id.alarm_save);
138         b.setOnClickListener(new View.OnClickListener() {
139                 public void onClick(View v) {
140                     // Enable the alarm when clicking "Done"
141                     mEnabled = true;
142                     saveAlarm();
143                     finish();
144                 }
145         });
146         b = (Button) v.findViewById(R.id.alarm_cancel);
147         b.setOnClickListener(new View.OnClickListener() {
148                 public void onClick(View v) {
149                     finish();
150                 }
151         });
152
153         // Replace the old content view with our new one.
154         setContentView(ll);
155     }
156
157     @Override
158     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
159             Preference preference) {
160         if (preference == mTimePref) {
161             new TimePickerDialog(this, this, mHour, mMinutes,
162                     DateFormat.is24HourFormat(this)).show();
163         }
164
165         return super.onPreferenceTreeClick(preferenceScreen, preference);
166     }
167
168     @Override
169     public void onBackPressed() {
170         saveAlarm();
171         finish();
172     }
173
174     public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
175         mHour = hourOfDay;
176         mMinutes = minute;
177         updateTime();
178         // If the time has been changed, enable the alarm.
179         mEnabled = true;
180     }
181
182     private void updateTime() {
183         if (Log.LOGV) {
184             Log.v("updateTime " + mId);
185         }
186         mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
187                 mRepeatPref.getDaysOfWeek()));
188     }
189
190     private void saveAlarm() {
191         final String alert = mAlarmPref.getAlertString();
192         Alarms.setAlarm(this, mId, mEnabled, mHour, mMinutes,
193                 mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
194                 mLabel.getText(), alert);
195
196         if (mEnabled) {
197             popAlarmSetToast(this, mHour, mMinutes,
198                     mRepeatPref.getDaysOfWeek());
199         }
200     }
201
202     /**
203      * Write alarm out to persistent store and pops toast if alarm
204      * enabled
205      */
206     private static void saveAlarm(
207             Context context, int id, boolean enabled, int hour, int minute,
208             Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label,
209             String alert, boolean popToast) {
210         if (Log.LOGV) Log.v("** saveAlarm " + id + " " + label + " " + enabled
211                 + " " + hour + " " + minute + " vibe " + vibrate);
212
213         // Fix alert string first
214         Alarms.setAlarm(context, id, enabled, hour, minute, daysOfWeek, vibrate,
215                 label, alert);
216
217         if (enabled && popToast) {
218             popAlarmSetToast(context, hour, minute, daysOfWeek);
219         }
220     }
221
222     /**
223      * Display a toast that tells the user how long until the alarm
224      * goes off.  This helps prevent "am/pm" mistakes.
225      */
226     static void popAlarmSetToast(Context context, int hour, int minute,
227                                  Alarm.DaysOfWeek daysOfWeek) {
228
229         String toastText = formatToast(context, hour, minute, daysOfWeek);
230         Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
231         ToastMaster.setToast(toast);
232         toast.show();
233     }
234
235     /**
236      * format "Alarm set for 2 days 7 hours and 53 minutes from
237      * now"
238      */
239     static String formatToast(Context context, int hour, int minute,
240                               Alarm.DaysOfWeek daysOfWeek) {
241         long alarm = Alarms.calculateAlarm(hour, minute,
242                                            daysOfWeek).getTimeInMillis();
243         long delta = alarm - System.currentTimeMillis();;
244         long hours = delta / (1000 * 60 * 60);
245         long minutes = delta / (1000 * 60) % 60;
246         long days = hours / 24;
247         hours = hours % 24;
248
249         String daySeq = (days == 0) ? "" :
250                 (days == 1) ? context.getString(R.string.day) :
251                 context.getString(R.string.days, Long.toString(days));
252
253         String minSeq = (minutes == 0) ? "" :
254                 (minutes == 1) ? context.getString(R.string.minute) :
255                 context.getString(R.string.minutes, Long.toString(minutes));
256
257         String hourSeq = (hours == 0) ? "" :
258                 (hours == 1) ? context.getString(R.string.hour) :
259                 context.getString(R.string.hours, Long.toString(hours));
260
261         boolean dispDays = days > 0;
262         boolean dispHour = hours > 0;
263         boolean dispMinute = minutes > 0;
264
265         int index = (dispDays ? 1 : 0) |
266                     (dispHour ? 2 : 0) |
267                     (dispMinute ? 4 : 0);
268
269         String[] formats = context.getResources().getStringArray(R.array.alarm_set);
270         return String.format(formats[index], daySeq, hourSeq, minSeq);
271     }
272
273     public boolean onCreateOptionsMenu(Menu menu) {
274         super.onCreateOptionsMenu(menu);
275
276         mDeleteAlarmItem = menu.add(0, 0, 0, R.string.delete_alarm);
277         mDeleteAlarmItem.setIcon(android.R.drawable.ic_menu_delete);
278
279         if (AlarmClock.DEBUG) {
280             mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
281         }
282
283         return true;
284     }
285
286     public boolean onOptionsItemSelected(MenuItem item) {
287         if (item == mDeleteAlarmItem) {
288             Alarms.deleteAlarm(this, mId);
289             finish();
290             return true;
291         }
292         if (AlarmClock.DEBUG) {
293             if (item == mTestAlarmItem) {
294                 setTestAlarm();
295                 return true;
296             }
297         }
298
299         return false;
300     }
301
302
303     /**
304      * Test code: this is disabled for production build.  Sets
305      * this alarm to go off on the next minute
306      */
307     void setTestAlarm() {
308
309         // start with now
310         java.util.Calendar c = java.util.Calendar.getInstance();
311         c.setTimeInMillis(System.currentTimeMillis());
312
313         int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
314         int nowMinute = c.get(java.util.Calendar.MINUTE);
315
316         int minutes = (nowMinute + 1) % 60;
317         int hour = nowHour + (nowMinute == 0 ? 1 : 0);
318
319         saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
320                 true, mLabel.getText(), mAlarmPref.getAlertString(), true);
321     }
322
323 }