OSDN Git Service

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