• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
onCreate(Bundle icicle)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                     saveAlarm();
141                     finish();
142                 }
143         });
144         b = (Button) v.findViewById(R.id.alarm_cancel);
145         b.setOnClickListener(new View.OnClickListener() {
146                 public void onClick(View v) {
147                     finish();
148                 }
149         });
150 
151         // Replace the old content view with our new one.
152         setContentView(ll);
153     }
154 
155     @Override
onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)156     public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
157             Preference preference) {
158         if (preference == mTimePref) {
159             new TimePickerDialog(this, this, mHour, mMinutes,
160                     DateFormat.is24HourFormat(this)).show();
161         }
162 
163         return super.onPreferenceTreeClick(preferenceScreen, preference);
164     }
165 
166     @Override
onBackPressed()167     public void onBackPressed() {
168         saveAlarm();
169         finish();
170     }
171 
onTimeSet(TimePicker view, int hourOfDay, int minute)172     public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
173         mHour = hourOfDay;
174         mMinutes = minute;
175         updateTime();
176         // If the time has been changed, enable the alarm.
177         mEnabled = true;
178     }
179 
updateTime()180     private void updateTime() {
181         if (Log.LOGV) {
182             Log.v("updateTime " + mId);
183         }
184         mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
185                 mRepeatPref.getDaysOfWeek()));
186     }
187 
saveAlarm()188     private void saveAlarm() {
189         final String alert = mAlarmPref.getAlertString();
190         Alarms.setAlarm(this, mId, mEnabled, mHour, mMinutes,
191                 mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
192                 mLabel.getText(), alert);
193 
194         if (mEnabled) {
195             popAlarmSetToast(this, mHour, mMinutes,
196                     mRepeatPref.getDaysOfWeek());
197         }
198     }
199 
200     /**
201      * Write alarm out to persistent store and pops toast if alarm
202      * enabled
203      */
saveAlarm( Context context, int id, boolean enabled, int hour, int minute, Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label, String alert, boolean popToast)204     private static void saveAlarm(
205             Context context, int id, boolean enabled, int hour, int minute,
206             Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label,
207             String alert, boolean popToast) {
208         if (Log.LOGV) Log.v("** saveAlarm " + id + " " + label + " " + enabled
209                 + " " + hour + " " + minute + " vibe " + vibrate);
210 
211         // Fix alert string first
212         Alarms.setAlarm(context, id, enabled, hour, minute, daysOfWeek, vibrate,
213                 label, alert);
214 
215         if (enabled && popToast) {
216             popAlarmSetToast(context, hour, minute, daysOfWeek);
217         }
218     }
219 
220     /**
221      * Display a toast that tells the user how long until the alarm
222      * goes off.  This helps prevent "am/pm" mistakes.
223      */
popAlarmSetToast(Context context, int hour, int minute, Alarm.DaysOfWeek daysOfWeek)224     static void popAlarmSetToast(Context context, int hour, int minute,
225                                  Alarm.DaysOfWeek daysOfWeek) {
226 
227         String toastText = formatToast(context, hour, minute, daysOfWeek);
228         Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
229         ToastMaster.setToast(toast);
230         toast.show();
231     }
232 
233     /**
234      * format "Alarm set for 2 days 7 hours and 53 minutes from
235      * now"
236      */
formatToast(Context context, int hour, int minute, Alarm.DaysOfWeek daysOfWeek)237     static String formatToast(Context context, int hour, int minute,
238                               Alarm.DaysOfWeek daysOfWeek) {
239         long alarm = Alarms.calculateAlarm(hour, minute,
240                                            daysOfWeek).getTimeInMillis();
241         long delta = alarm - System.currentTimeMillis();;
242         long hours = delta / (1000 * 60 * 60);
243         long minutes = delta / (1000 * 60) % 60;
244         long days = hours / 24;
245         hours = hours % 24;
246 
247         String daySeq = (days == 0) ? "" :
248                 (days == 1) ? context.getString(R.string.day) :
249                 context.getString(R.string.days, Long.toString(days));
250 
251         String minSeq = (minutes == 0) ? "" :
252                 (minutes == 1) ? context.getString(R.string.minute) :
253                 context.getString(R.string.minutes, Long.toString(minutes));
254 
255         String hourSeq = (hours == 0) ? "" :
256                 (hours == 1) ? context.getString(R.string.hour) :
257                 context.getString(R.string.hours, Long.toString(hours));
258 
259         boolean dispDays = days > 0;
260         boolean dispHour = hours > 0;
261         boolean dispMinute = minutes > 0;
262 
263         int index = (dispDays ? 1 : 0) |
264                     (dispHour ? 2 : 0) |
265                     (dispMinute ? 4 : 0);
266 
267         String[] formats = context.getResources().getStringArray(R.array.alarm_set);
268         return String.format(formats[index], daySeq, hourSeq, minSeq);
269     }
270 
onCreateOptionsMenu(Menu menu)271     public boolean onCreateOptionsMenu(Menu menu) {
272         super.onCreateOptionsMenu(menu);
273 
274         mDeleteAlarmItem = menu.add(0, 0, 0, R.string.delete_alarm);
275         mDeleteAlarmItem.setIcon(android.R.drawable.ic_menu_delete);
276 
277         if (AlarmClock.DEBUG) {
278             mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
279         }
280 
281         return true;
282     }
283 
onOptionsItemSelected(MenuItem item)284     public boolean onOptionsItemSelected(MenuItem item) {
285         if (item == mDeleteAlarmItem) {
286             Alarms.deleteAlarm(this, mId);
287             finish();
288             return true;
289         }
290         if (AlarmClock.DEBUG) {
291             if (item == mTestAlarmItem) {
292                 setTestAlarm();
293                 return true;
294             }
295         }
296 
297         return false;
298     }
299 
300 
301     /**
302      * Test code: this is disabled for production build.  Sets
303      * this alarm to go off on the next minute
304      */
setTestAlarm()305     void setTestAlarm() {
306 
307         // start with now
308         java.util.Calendar c = java.util.Calendar.getInstance();
309         c.setTimeInMillis(System.currentTimeMillis());
310 
311         int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
312         int nowMinute = c.get(java.util.Calendar.MINUTE);
313 
314         int minutes = (nowMinute + 1) % 60;
315         int hour = nowHour + (nowMinute == 0 ? 1 : 0);
316 
317         saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
318                 true, mLabel.getText(), mAlarmPref.getAlertString(), true);
319     }
320 
321 }
322