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 mEnabled = alarm.enabled;
97 mLabel.setText(alarm.label);
98 mLabel.setSummary(alarm.label);
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);
107 // We have to do this to get the save/cancel buttons to highlight on
109 getListView().setItemsCanFocus(true);
111 // Grab the content view so we can modify it.
112 FrameLayout content = (FrameLayout) getWindow().getDecorView()
113 .findViewById(com.android.internal.R.id.content);
115 // Get the main ListView and remove it from the content view.
116 ListView lv = getListView();
117 content.removeView(lv);
119 // Create the new LinearLayout that will become the content view and
121 LinearLayout ll = new LinearLayout(this);
122 ll.setOrientation(LinearLayout.VERTICAL);
124 // Have the ListView expand to fill the screen minus the save/cancel
126 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
127 LayoutParams.FILL_PARENT,
128 LayoutParams.WRAP_CONTENT);
132 // Inflate the buttons onto the LinearLayout.
133 View v = LayoutInflater.from(this).inflate(
134 R.layout.save_cancel_alarm, ll);
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"
146 b = (Button) v.findViewById(R.id.alarm_cancel);
147 b.setOnClickListener(new View.OnClickListener() {
148 public void onClick(View v) {
153 // Replace the old content view with our new one.
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();
165 return super.onPreferenceTreeClick(preferenceScreen, preference);
169 public void onBackPressed() {
174 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
178 // If the time has been changed, enable the alarm.
182 private void updateTime() {
184 Log.v("updateTime " + mId);
186 mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
187 mRepeatPref.getDaysOfWeek()));
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);
197 popAlarmSetToast(this, mHour, mMinutes,
198 mRepeatPref.getDaysOfWeek());
203 * Write alarm out to persistent store and pops toast if alarm
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);
213 // Fix alert string first
214 Alarms.setAlarm(context, id, enabled, hour, minute, daysOfWeek, vibrate,
217 if (enabled && popToast) {
218 popAlarmSetToast(context, hour, minute, daysOfWeek);
223 * Display a toast that tells the user how long until the alarm
224 * goes off. This helps prevent "am/pm" mistakes.
226 static void popAlarmSetToast(Context context, int hour, int minute,
227 Alarm.DaysOfWeek daysOfWeek) {
229 String toastText = formatToast(context, hour, minute, daysOfWeek);
230 Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
231 ToastMaster.setToast(toast);
236 * format "Alarm set for 2 days 7 hours and 53 minutes from
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;
249 String daySeq = (days == 0) ? "" :
250 (days == 1) ? context.getString(R.string.day) :
251 context.getString(R.string.days, Long.toString(days));
253 String minSeq = (minutes == 0) ? "" :
254 (minutes == 1) ? context.getString(R.string.minute) :
255 context.getString(R.string.minutes, Long.toString(minutes));
257 String hourSeq = (hours == 0) ? "" :
258 (hours == 1) ? context.getString(R.string.hour) :
259 context.getString(R.string.hours, Long.toString(hours));
261 boolean dispDays = days > 0;
262 boolean dispHour = hours > 0;
263 boolean dispMinute = minutes > 0;
265 int index = (dispDays ? 1 : 0) |
267 (dispMinute ? 4 : 0);
269 String[] formats = context.getResources().getStringArray(R.array.alarm_set);
270 return String.format(formats[index], daySeq, hourSeq, minSeq);
273 public boolean onCreateOptionsMenu(Menu menu) {
274 super.onCreateOptionsMenu(menu);
276 mDeleteAlarmItem = menu.add(0, 0, 0, R.string.delete_alarm);
277 mDeleteAlarmItem.setIcon(android.R.drawable.ic_menu_delete);
279 if (AlarmClock.DEBUG) {
280 mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
286 public boolean onOptionsItemSelected(MenuItem item) {
287 if (item == mDeleteAlarmItem) {
288 Alarms.deleteAlarm(this, mId);
292 if (AlarmClock.DEBUG) {
293 if (item == mTestAlarmItem) {
304 * Test code: this is disabled for production build. Sets
305 * this alarm to go off on the next minute
307 void setTestAlarm() {
310 java.util.Calendar c = java.util.Calendar.getInstance();
311 c.setTimeInMillis(System.currentTimeMillis());
313 int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
314 int nowMinute = c.get(java.util.Calendar.MINUTE);
316 int minutes = (nowMinute + 1) % 60;
317 int hour = nowHour + (nowMinute == 0 ? 1 : 0);
319 saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
320 true, mLabel.getText(), mAlarmPref.getAlertString(), true);