2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.alarmclock;
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;
46 public class SetAlarm extends PreferenceActivity
47 implements TimePickerDialog.OnTimeSetListener {
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;
58 private boolean mEnabled;
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.
67 protected void onCreate(Bundle icicle) {
68 super.onCreate(icicle);
70 addPreferencesFromResource(R.xml.alarm_prefs);
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,
78 // Set the summary based on the new label.
79 p.setSummary((String) newValue);
83 mTimePref = findPreference("time");
84 mAlarmPref = (AlarmPreference) findPreference("alarm");
85 mVibratePref = (CheckBoxPreference) findPreference("vibrate");
86 mRepeatPref = (RepeatPreference) findPreference("setRepeat");
88 Intent i = getIntent();
89 mId = i.getIntExtra(Alarms.ALARM_ID, -1);
91 Log.v("In SetAlarm, alarm id = " + mId);
94 /* load alarm details from database */
95 Alarm alarm = Alarms.getAlarm(getContentResolver(), mId);
96 // Bad alarm, bail to avoid a NPE.
101 mEnabled = alarm.enabled;
102 mLabel.setText(alarm.label);
103 mLabel.setSummary(alarm.label);
105 mMinutes = alarm.minutes;
106 mRepeatPref.setDaysOfWeek(alarm.daysOfWeek);
107 mVibratePref.setChecked(alarm.vibrate);
108 // Give the alert uri to the preference.
109 mAlarmPref.setAlert(alarm.alert);
112 // We have to do this to get the save/cancel buttons to highlight on
114 getListView().setItemsCanFocus(true);
116 // Grab the content view so we can modify it.
117 FrameLayout content = (FrameLayout) getWindow().getDecorView()
118 .findViewById(com.android.internal.R.id.content);
120 // Get the main ListView and remove it from the content view.
121 ListView lv = getListView();
122 content.removeView(lv);
124 // Create the new LinearLayout that will become the content view and
126 LinearLayout ll = new LinearLayout(this);
127 ll.setOrientation(LinearLayout.VERTICAL);
129 // Have the ListView expand to fill the screen minus the save/cancel
131 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
132 LayoutParams.FILL_PARENT,
133 LayoutParams.WRAP_CONTENT);
137 // Inflate the buttons onto the LinearLayout.
138 View v = LayoutInflater.from(this).inflate(
139 R.layout.save_cancel_alarm, ll);
141 // Attach actions to each button.
142 Button b = (Button) v.findViewById(R.id.alarm_save);
143 b.setOnClickListener(new View.OnClickListener() {
144 public void onClick(View v) {
145 // Enable the alarm when clicking "Done"
151 b = (Button) v.findViewById(R.id.alarm_cancel);
152 b.setOnClickListener(new View.OnClickListener() {
153 public void onClick(View v) {
158 // Replace the old content view with our new one.
163 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
164 Preference preference) {
165 if (preference == mTimePref) {
166 new TimePickerDialog(this, this, mHour, mMinutes,
167 DateFormat.is24HourFormat(this)).show();
170 return super.onPreferenceTreeClick(preferenceScreen, preference);
174 public void onBackPressed() {
179 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
183 // If the time has been changed, enable the alarm.
187 private void updateTime() {
189 Log.v("updateTime " + mId);
191 mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
192 mRepeatPref.getDaysOfWeek()));
195 private void saveAlarm() {
196 final String alert = mAlarmPref.getAlertString();
197 Alarms.setAlarm(this, mId, mEnabled, mHour, mMinutes,
198 mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
199 mLabel.getText(), alert);
202 popAlarmSetToast(this, mHour, mMinutes,
203 mRepeatPref.getDaysOfWeek());
208 * Write alarm out to persistent store and pops toast if alarm
211 private static void saveAlarm(
212 Context context, int id, boolean enabled, int hour, int minute,
213 Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label,
214 String alert, boolean popToast) {
215 if (Log.LOGV) Log.v("** saveAlarm " + id + " " + label + " " + enabled
216 + " " + hour + " " + minute + " vibe " + vibrate);
218 // Fix alert string first
219 Alarms.setAlarm(context, id, enabled, hour, minute, daysOfWeek, vibrate,
222 if (enabled && popToast) {
223 popAlarmSetToast(context, hour, minute, daysOfWeek);
228 * Display a toast that tells the user how long until the alarm
229 * goes off. This helps prevent "am/pm" mistakes.
231 static void popAlarmSetToast(Context context, int hour, int minute,
232 Alarm.DaysOfWeek daysOfWeek) {
234 String toastText = formatToast(context, hour, minute, daysOfWeek);
235 Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
236 ToastMaster.setToast(toast);
241 * format "Alarm set for 2 days 7 hours and 53 minutes from
244 static String formatToast(Context context, int hour, int minute,
245 Alarm.DaysOfWeek daysOfWeek) {
246 long alarm = Alarms.calculateAlarm(hour, minute,
247 daysOfWeek).getTimeInMillis();
248 long delta = alarm - System.currentTimeMillis();;
249 long hours = delta / (1000 * 60 * 60);
250 long minutes = delta / (1000 * 60) % 60;
251 long days = hours / 24;
254 String daySeq = (days == 0) ? "" :
255 (days == 1) ? context.getString(R.string.day) :
256 context.getString(R.string.days, Long.toString(days));
258 String minSeq = (minutes == 0) ? "" :
259 (minutes == 1) ? context.getString(R.string.minute) :
260 context.getString(R.string.minutes, Long.toString(minutes));
262 String hourSeq = (hours == 0) ? "" :
263 (hours == 1) ? context.getString(R.string.hour) :
264 context.getString(R.string.hours, Long.toString(hours));
266 boolean dispDays = days > 0;
267 boolean dispHour = hours > 0;
268 boolean dispMinute = minutes > 0;
270 int index = (dispDays ? 1 : 0) |
272 (dispMinute ? 4 : 0);
274 String[] formats = context.getResources().getStringArray(R.array.alarm_set);
275 return String.format(formats[index], daySeq, hourSeq, minSeq);
278 public boolean onCreateOptionsMenu(Menu menu) {
279 super.onCreateOptionsMenu(menu);
281 mDeleteAlarmItem = menu.add(0, 0, 0, R.string.delete_alarm);
282 mDeleteAlarmItem.setIcon(android.R.drawable.ic_menu_delete);
284 if (AlarmClock.DEBUG) {
285 mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
291 public boolean onOptionsItemSelected(MenuItem item) {
292 if (item == mDeleteAlarmItem) {
293 Alarms.deleteAlarm(this, mId);
297 if (AlarmClock.DEBUG) {
298 if (item == mTestAlarmItem) {
309 * Test code: this is disabled for production build. Sets
310 * this alarm to go off on the next minute
312 void setTestAlarm() {
315 java.util.Calendar c = java.util.Calendar.getInstance();
316 c.setTimeInMillis(System.currentTimeMillis());
318 int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
319 int nowMinute = c.get(java.util.Calendar.MINUTE);
321 int minutes = (nowMinute + 1) % 60;
322 int hour = nowHour + (nowMinute == 0 ? 1 : 0);
324 saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
325 true, mLabel.getText(), mAlarmPref.getAlertString(), true);