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);
70 AlarmClock.setVolumeControlForPlatform(this);
72 addPreferencesFromResource(R.xml.alarm_prefs);
74 // Get each preference so we can retrieve the value later.
75 mLabel = (EditTextPreference) findPreference("label");
76 mLabel.setOnPreferenceChangeListener(
77 new Preference.OnPreferenceChangeListener() {
78 public boolean onPreferenceChange(Preference p,
80 // Set the summary based on the new label.
81 p.setSummary((String) newValue);
85 mEnabledPref = (CheckBoxPreference) findPreference("enabled");
86 mTimePref = findPreference("time");
87 mAlarmPref = (AlarmPreference) findPreference("alarm");
88 mVibratePref = (CheckBoxPreference) findPreference("vibrate");
89 mVibratePref.setEnabled(!AlarmClock.isVolumeAdjustable());
90 mRepeatPref = (RepeatPreference) findPreference("setRepeat");
92 Intent i = getIntent();
93 mId = i.getIntExtra(Alarms.ALARM_ID, -1);
95 Log.v("In SetAlarm, alarm id = " + mId);
98 /* load alarm details from database */
99 Alarm alarm = Alarms.getAlarm(getContentResolver(), mId);
100 mEnabledPref.setChecked(alarm.enabled);
101 mLabel.setText(alarm.label);
102 mLabel.setSummary(alarm.label);
104 mMinutes = alarm.minutes;
105 mRepeatPref.setDaysOfWeek(alarm.daysOfWeek);
106 mVibratePref.setChecked(alarm.vibrate && !AlarmClock.isVolumeAdjustable());
107 // Give the alert uri to the preference.
108 mAlarmPref.setAlert(alarm.alert);
111 // We have to do this to get the save/cancel buttons to highlight on
113 getListView().setItemsCanFocus(true);
115 // Grab the content view so we can modify it.
116 FrameLayout content = (FrameLayout) getWindow().getDecorView()
117 .findViewById(com.android.internal.R.id.content);
119 // Get the main ListView and remove it from the content view.
120 ListView lv = getListView();
121 content.removeView(lv);
123 // Create the new LinearLayout that will become the content view and
125 LinearLayout ll = new LinearLayout(this);
126 ll.setOrientation(LinearLayout.VERTICAL);
128 // Have the ListView expand to fill the screen minus the save/cancel
130 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
131 LayoutParams.FILL_PARENT,
132 LayoutParams.WRAP_CONTENT);
136 // Inflate the buttons onto the LinearLayout.
137 View v = LayoutInflater.from(this).inflate(
138 R.layout.save_cancel_alarm, ll);
140 // Attach actions to each button.
141 Button b = (Button) v.findViewById(R.id.alarm_save);
142 b.setOnClickListener(new View.OnClickListener() {
143 public void onClick(View v) {
148 b = (Button) v.findViewById(R.id.alarm_cancel);
149 b.setOnClickListener(new View.OnClickListener() {
150 public void onClick(View v) {
154 b = (Button) v.findViewById(R.id.alarm_delete);
155 b.setOnClickListener(new View.OnClickListener() {
156 public void onClick(View v) {
161 // Replace the old content view with our new one.
166 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
167 Preference preference) {
168 if (preference == mTimePref) {
169 new TimePickerDialog(this, this, mHour, mMinutes,
170 DateFormat.is24HourFormat(this)).show();
173 return super.onPreferenceTreeClick(preferenceScreen, preference);
177 public void onBackPressed() {
182 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
186 // If the time has been changed, enable the alarm.
187 mEnabledPref.setChecked(true);
190 private void updateTime() {
192 Log.v("updateTime " + mId);
194 mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
195 mRepeatPref.getDaysOfWeek()));
198 private void saveAlarm() {
199 final String alert = mAlarmPref.getAlertString();
200 long time = Alarms.setAlarm(this, mId, mEnabledPref.isChecked(), mHour,
201 mMinutes, mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
202 mLabel.getText(), alert);
204 if (mEnabledPref.isChecked()) {
205 popAlarmSetToast(this, time);
209 private void deleteAlarm() {
210 new AlertDialog.Builder(this)
211 .setTitle(getString(R.string.delete_alarm))
212 .setMessage(getString(R.string.delete_alarm_confirm))
213 .setPositiveButton(android.R.string.ok,
214 new DialogInterface.OnClickListener() {
215 public void onClick(DialogInterface d, int w) {
216 Alarms.deleteAlarm(SetAlarm.this, mId);
220 .setNegativeButton(android.R.string.cancel, null)
225 * Write alarm out to persistent store and pops toast if alarm
227 * Used only in test code.
229 private static void saveAlarm(
230 Context context, int id, boolean enabled, int hour, int minute,
231 Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label,
232 String alert, boolean popToast) {
233 if (Log.LOGV) Log.v("** saveAlarm " + id + " " + label + " " + enabled
234 + " " + hour + " " + minute + " vibe " + vibrate);
236 // Fix alert string first
237 long time = Alarms.setAlarm(context, id, enabled, hour, minute,
238 daysOfWeek, vibrate, label, alert);
240 if (enabled && popToast) {
241 popAlarmSetToast(context, time);
246 * Display a toast that tells the user how long until the alarm
247 * goes off. This helps prevent "am/pm" mistakes.
249 static void popAlarmSetToast(Context context, int hour, int minute,
250 Alarm.DaysOfWeek daysOfWeek) {
251 popAlarmSetToast(context,
252 Alarms.calculateAlarm(hour, minute, daysOfWeek)
256 private static void popAlarmSetToast(Context context, long timeInMillis) {
257 String toastText = formatToast(context, timeInMillis);
258 Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
259 ToastMaster.setToast(toast);
264 * format "Alarm set for 2 days 7 hours and 53 minutes from
267 static String formatToast(Context context, long timeInMillis) {
268 long delta = timeInMillis - System.currentTimeMillis();
269 long hours = delta / (1000 * 60 * 60);
270 long minutes = delta / (1000 * 60) % 60;
271 long days = hours / 24;
274 String daySeq = (days == 0) ? "" :
275 (days == 1) ? context.getString(R.string.day) :
276 context.getString(R.string.days, Long.toString(days));
278 String minSeq = (minutes == 0) ? "" :
279 (minutes == 1) ? context.getString(R.string.minute) :
280 context.getString(R.string.minutes, Long.toString(minutes));
282 String hourSeq = (hours == 0) ? "" :
283 (hours == 1) ? context.getString(R.string.hour) :
284 context.getString(R.string.hours, Long.toString(hours));
286 boolean dispDays = days > 0;
287 boolean dispHour = hours > 0;
288 boolean dispMinute = minutes > 0;
290 int index = (dispDays ? 1 : 0) |
292 (dispMinute ? 4 : 0);
294 String[] formats = context.getResources().getStringArray(R.array.alarm_set);
295 return String.format(formats[index], daySeq, hourSeq, minSeq);
298 public boolean onCreateOptionsMenu(Menu menu) {
299 super.onCreateOptionsMenu(menu);
301 if (AlarmClock.DEBUG) {
302 mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
308 public boolean onOptionsItemSelected(MenuItem item) {
309 if (AlarmClock.DEBUG) {
310 if (item == mTestAlarmItem) {
321 * Test code: this is disabled for production build. Sets
322 * this alarm to go off on the next minute
324 void setTestAlarm() {
327 java.util.Calendar c = java.util.Calendar.getInstance();
328 c.setTimeInMillis(System.currentTimeMillis());
330 int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
331 int nowMinute = c.get(java.util.Calendar.MINUTE);
333 int minutes = (nowMinute + 1) % 60;
334 int hour = nowHour + (nowMinute == 0 ? 1 : 0);
336 saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
337 true, mLabel.getText(), mAlarmPref.getAlertString(), true);