• 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.deskclock;
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         long time = Alarms.setAlarm(this, mId, mEnabled, mHour, mMinutes,
191                 mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
192                 mLabel.getText(), alert);
193 
194         if (mEnabled) {
195             popAlarmSetToast(this, time);
196         }
197     }
198 
199     /**
200      * Write alarm out to persistent store and pops toast if alarm
201      * enabled.
202      * Used only in test code.
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         long time = Alarms.setAlarm(context, id, enabled, hour, minute,
213                 daysOfWeek, vibrate, label, alert);
214 
215         if (enabled && popToast) {
216             popAlarmSetToast(context, time);
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         popAlarmSetToast(context,
227                 Alarms.calculateAlarm(hour, minute, daysOfWeek)
228                 .getTimeInMillis());
229     }
230 
popAlarmSetToast(Context context, long timeInMillis)231     private static void popAlarmSetToast(Context context, long timeInMillis) {
232         String toastText = formatToast(context, timeInMillis);
233         Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
234         ToastMaster.setToast(toast);
235         toast.show();
236     }
237 
238     /**
239      * format "Alarm set for 2 days 7 hours and 53 minutes from
240      * now"
241      */
formatToast(Context context, long timeInMillis)242     static String formatToast(Context context, long timeInMillis) {
243         long delta = timeInMillis - 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 
onCreateOptionsMenu(Menu menu)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 
onOptionsItemSelected(MenuItem item)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      */
setTestAlarm()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 }
324