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 mEnabledPref.setChecked(alarm.enabled);
99 mLabel.setText(alarm.label);
100 mLabel.setSummary(alarm.label);
102 mMinutes = alarm.minutes;
103 mRepeatPref.setDaysOfWeek(alarm.daysOfWeek);
104 mVibratePref.setChecked(alarm.vibrate);
105 // Give the alert uri to the preference.
106 mAlarmPref.setAlert(alarm.alert);
109 // We have to do this to get the save/cancel buttons to highlight on
111 getListView().setItemsCanFocus(true);
113 // Grab the content view so we can modify it.
114 FrameLayout content = (FrameLayout) getWindow().getDecorView()
115 .findViewById(com.android.internal.R.id.content);
117 // Get the main ListView and remove it from the content view.
118 ListView lv = getListView();
119 content.removeView(lv);
121 // Create the new LinearLayout that will become the content view and
123 LinearLayout ll = new LinearLayout(this);
124 ll.setOrientation(LinearLayout.VERTICAL);
126 // Have the ListView expand to fill the screen minus the save/cancel
128 LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
129 LayoutParams.FILL_PARENT,
130 LayoutParams.WRAP_CONTENT);
134 // Inflate the buttons onto the LinearLayout.
135 View v = LayoutInflater.from(this).inflate(
136 R.layout.save_cancel_alarm, ll);
138 // Attach actions to each button.
139 Button b = (Button) v.findViewById(R.id.alarm_save);
140 b.setOnClickListener(new View.OnClickListener() {
141 public void onClick(View v) {
146 b = (Button) v.findViewById(R.id.alarm_cancel);
147 b.setOnClickListener(new View.OnClickListener() {
148 public void onClick(View v) {
152 b = (Button) v.findViewById(R.id.alarm_delete);
153 b.setOnClickListener(new View.OnClickListener() {
154 public void onClick(View v) {
159 // Replace the old content view with our new one.
164 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
165 Preference preference) {
166 if (preference == mTimePref) {
167 new TimePickerDialog(this, this, mHour, mMinutes,
168 DateFormat.is24HourFormat(this)).show();
171 return super.onPreferenceTreeClick(preferenceScreen, preference);
175 public void onBackPressed() {
180 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
184 // If the time has been changed, enable the alarm.
185 mEnabledPref.setChecked(true);
188 private void updateTime() {
190 Log.v("updateTime " + mId);
192 mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
193 mRepeatPref.getDaysOfWeek()));
196 private void saveAlarm() {
197 final String alert = mAlarmPref.getAlertString();
198 long time = Alarms.setAlarm(this, mId, mEnabledPref.isChecked(), mHour,
199 mMinutes, mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
200 mLabel.getText(), alert);
202 if (mEnabledPref.isChecked()) {
203 popAlarmSetToast(this, time);
207 private void deleteAlarm() {
208 new AlertDialog.Builder(this)
209 .setTitle(getString(R.string.delete_alarm))
210 .setMessage(getString(R.string.delete_alarm_confirm))
211 .setPositiveButton(android.R.string.ok,
212 new DialogInterface.OnClickListener() {
213 public void onClick(DialogInterface d, int w) {
214 Alarms.deleteAlarm(SetAlarm.this, mId);
218 .setNegativeButton(android.R.string.cancel, null)
223 * Write alarm out to persistent store and pops toast if alarm
225 * Used only in test code.
227 private static void saveAlarm(
228 Context context, int id, boolean enabled, int hour, int minute,
229 Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label,
230 String alert, boolean popToast) {
231 if (Log.LOGV) Log.v("** saveAlarm " + id + " " + label + " " + enabled
232 + " " + hour + " " + minute + " vibe " + vibrate);
234 // Fix alert string first
235 long time = Alarms.setAlarm(context, id, enabled, hour, minute,
236 daysOfWeek, vibrate, label, alert);
238 if (enabled && popToast) {
239 popAlarmSetToast(context, time);
244 * Display a toast that tells the user how long until the alarm
245 * goes off. This helps prevent "am/pm" mistakes.
247 static void popAlarmSetToast(Context context, int hour, int minute,
248 Alarm.DaysOfWeek daysOfWeek) {
249 popAlarmSetToast(context,
250 Alarms.calculateAlarm(hour, minute, daysOfWeek)
254 private static void popAlarmSetToast(Context context, long timeInMillis) {
255 String toastText = formatToast(context, timeInMillis);
256 Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
257 ToastMaster.setToast(toast);
262 * format "Alarm set for 2 days 7 hours and 53 minutes from
265 static String formatToast(Context context, long timeInMillis) {
266 long delta = timeInMillis - System.currentTimeMillis();
267 long hours = delta / (1000 * 60 * 60);
268 long minutes = delta / (1000 * 60) % 60;
269 long days = hours / 24;
272 String daySeq = (days == 0) ? "" :
273 (days == 1) ? context.getString(R.string.day) :
274 context.getString(R.string.days, Long.toString(days));
276 String minSeq = (minutes == 0) ? "" :
277 (minutes == 1) ? context.getString(R.string.minute) :
278 context.getString(R.string.minutes, Long.toString(minutes));
280 String hourSeq = (hours == 0) ? "" :
281 (hours == 1) ? context.getString(R.string.hour) :
282 context.getString(R.string.hours, Long.toString(hours));
284 boolean dispDays = days > 0;
285 boolean dispHour = hours > 0;
286 boolean dispMinute = minutes > 0;
288 int index = (dispDays ? 1 : 0) |
290 (dispMinute ? 4 : 0);
292 String[] formats = context.getResources().getStringArray(R.array.alarm_set);
293 return String.format(formats[index], daySeq, hourSeq, minSeq);
296 public boolean onCreateOptionsMenu(Menu menu) {
297 super.onCreateOptionsMenu(menu);
299 if (AlarmClock.DEBUG) {
300 mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
306 public boolean onOptionsItemSelected(MenuItem item) {
307 if (AlarmClock.DEBUG) {
308 if (item == mTestAlarmItem) {
319 * Test code: this is disabled for production build. Sets
320 * this alarm to go off on the next minute
322 void setTestAlarm() {
325 java.util.Calendar c = java.util.Calendar.getInstance();
326 c.setTimeInMillis(System.currentTimeMillis());
328 int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
329 int nowMinute = c.get(java.util.Calendar.MINUTE);
331 int minutes = (nowMinute + 1) % 60;
332 int hour = nowHour + (nowMinute == 0 ? 1 : 0);
334 saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
335 true, mLabel.getText(), mAlarmPref.getAlertString(), true);