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.deskclock;
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;
48 public class SetAlarm extends PreferenceActivity
49 implements TimePickerDialog.OnTimeSetListener {
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;
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.
68 protected void onCreate(Bundle icicle) {
69 super.onCreate(icicle);
71 addPreferencesFromResource(R.xml.alarm_prefs);
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,
79 // Set the summary based on the new label.
80 p.setSummary((String) newValue);
84 mEnabledPref = (CheckBoxPreference) findPreference("enabled");
85 mTimePref = findPreference("time");
86 mAlarmPref = (AlarmPreference) findPreference("alarm");
87 mVibratePref = (CheckBoxPreference) findPreference("vibrate");
88 mRepeatPref = (RepeatPreference) findPreference("setRepeat");
90 Intent i = getIntent();
91 mId = i.getIntExtra(Alarms.ALARM_ID, -1);
93 Log.v("In SetAlarm, alarm id = " + mId);
96 /* load alarm details from database */
97 Alarm alarm = Alarms.getAlarm(getContentResolver(), mId);
98 // Bad alarm, bail to avoid a NPE.
103 mEnabledPref.setChecked(alarm.enabled);
104 mLabel.setText(alarm.label);
105 mLabel.setSummary(alarm.label);
107 mMinutes = alarm.minutes;
108 mRepeatPref.setDaysOfWeek(alarm.daysOfWeek);
109 mVibratePref.setChecked(alarm.vibrate);
110 // Give the alert uri to the preference.
111 mAlarmPref.setAlert(alarm.alert);
114 // We have to do this to get the save/cancel buttons to highlight on
116 getListView().setItemsCanFocus(true);
118 // Grab the content view so we can modify it.
119 FrameLayout content = (FrameLayout) getWindow().getDecorView()
120 .findViewById(com.android.internal.R.id.content);
122 // Get the main ListView and remove it from the content view.
123 ListView lv = getListView();
124 content.removeView(lv);
126 // Create the new LinearLayout that will become the content view and
128 LinearLayout ll = new LinearLayout(this);
129 ll.setOrientation(LinearLayout.VERTICAL);
131 // Have the ListView expand to fill the screen minus the save/cancel
133 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
134 LayoutParams.FILL_PARENT,
135 LayoutParams.WRAP_CONTENT);
139 // Inflate the buttons onto the LinearLayout.
140 View v = LayoutInflater.from(this).inflate(
141 R.layout.save_cancel_alarm, ll);
143 // Attach actions to each button.
144 Button b = (Button) v.findViewById(R.id.alarm_save);
145 b.setOnClickListener(new View.OnClickListener() {
146 public void onClick(View v) {
147 // Enable the alarm when clicking "Done"
148 mEnabledPref.setChecked(true);
153 b = (Button) v.findViewById(R.id.alarm_cancel);
154 b.setOnClickListener(new View.OnClickListener() {
155 public void onClick(View v) {
159 b = (Button) v.findViewById(R.id.alarm_delete);
160 b.setOnClickListener(new View.OnClickListener() {
161 public void onClick(View v) {
166 // Replace the old content view with our new one.
171 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
172 Preference preference) {
173 if (preference == mTimePref) {
174 new TimePickerDialog(this, this, mHour, mMinutes,
175 DateFormat.is24HourFormat(this)).show();
178 return super.onPreferenceTreeClick(preferenceScreen, preference);
182 public void onBackPressed() {
187 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
191 // If the time has been changed, enable the alarm.
192 mEnabledPref.setChecked(true);
195 private void updateTime() {
197 Log.v("updateTime " + mId);
199 mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
200 mRepeatPref.getDaysOfWeek()));
203 private void saveAlarm() {
204 final String alert = mAlarmPref.getAlertString();
205 long time = Alarms.setAlarm(this, mId, mEnabledPref.isChecked(), mHour,
206 mMinutes, mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
207 mLabel.getText(), alert);
209 if (mEnabledPref.isChecked()) {
210 popAlarmSetToast(this, time);
214 private void deleteAlarm() {
215 new AlertDialog.Builder(this)
216 .setTitle(getString(R.string.delete_alarm))
217 .setMessage(getString(R.string.delete_alarm_confirm))
218 .setPositiveButton(android.R.string.ok,
219 new DialogInterface.OnClickListener() {
220 public void onClick(DialogInterface d, int w) {
221 Alarms.deleteAlarm(SetAlarm.this, mId);
225 .setNegativeButton(android.R.string.cancel, null)
230 * Write alarm out to persistent store and pops toast if alarm
232 * Used only in test code.
234 private static void saveAlarm(
235 Context context, int id, boolean enabled, int hour, int minute,
236 Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label,
237 String alert, boolean popToast) {
238 if (Log.LOGV) Log.v("** saveAlarm " + id + " " + label + " " + enabled
239 + " " + hour + " " + minute + " vibe " + vibrate);
241 // Fix alert string first
242 long time = Alarms.setAlarm(context, id, enabled, hour, minute,
243 daysOfWeek, vibrate, label, alert);
245 if (enabled && popToast) {
246 popAlarmSetToast(context, time);
251 * Display a toast that tells the user how long until the alarm
252 * goes off. This helps prevent "am/pm" mistakes.
254 static void popAlarmSetToast(Context context, int hour, int minute,
255 Alarm.DaysOfWeek daysOfWeek) {
256 popAlarmSetToast(context,
257 Alarms.calculateAlarm(hour, minute, daysOfWeek)
261 private static void popAlarmSetToast(Context context, long timeInMillis) {
262 String toastText = formatToast(context, timeInMillis);
263 Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
264 ToastMaster.setToast(toast);
269 * format "Alarm set for 2 days 7 hours and 53 minutes from
272 static String formatToast(Context context, long timeInMillis) {
273 long delta = timeInMillis - System.currentTimeMillis();
274 long hours = delta / (1000 * 60 * 60);
275 long minutes = delta / (1000 * 60) % 60;
276 long days = hours / 24;
279 String daySeq = (days == 0) ? "" :
280 (days == 1) ? context.getString(R.string.day) :
281 context.getString(R.string.days, Long.toString(days));
283 String minSeq = (minutes == 0) ? "" :
284 (minutes == 1) ? context.getString(R.string.minute) :
285 context.getString(R.string.minutes, Long.toString(minutes));
287 String hourSeq = (hours == 0) ? "" :
288 (hours == 1) ? context.getString(R.string.hour) :
289 context.getString(R.string.hours, Long.toString(hours));
291 boolean dispDays = days > 0;
292 boolean dispHour = hours > 0;
293 boolean dispMinute = minutes > 0;
295 int index = (dispDays ? 1 : 0) |
297 (dispMinute ? 4 : 0);
299 String[] formats = context.getResources().getStringArray(R.array.alarm_set);
300 return String.format(formats[index], daySeq, hourSeq, minSeq);
303 public boolean onCreateOptionsMenu(Menu menu) {
304 super.onCreateOptionsMenu(menu);
306 if (AlarmClock.DEBUG) {
307 mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
313 public boolean onOptionsItemSelected(MenuItem item) {
314 if (AlarmClock.DEBUG) {
315 if (item == mTestAlarmItem) {
326 * Test code: this is disabled for production build. Sets
327 * this alarm to go off on the next minute
329 void setTestAlarm() {
332 java.util.Calendar c = java.util.Calendar.getInstance();
333 c.setTimeInMillis(System.currentTimeMillis());
335 int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
336 int nowMinute = c.get(java.util.Calendar.MINUTE);
338 int minutes = (nowMinute + 1) % 60;
339 int hour = nowHour + (nowMinute == 0 ? 1 : 0);
341 saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
342 true, mLabel.getText(), mAlarmPref.getAlertString(), true);