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.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) {
144 b = (Button) v.findViewById(R.id.alarm_cancel);
145 b.setOnClickListener(new View.OnClickListener() {
146 public void onClick(View v) {
151 // Replace the old content view with our new one.
156 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
157 Preference preference) {
158 if (preference == mTimePref) {
159 new TimePickerDialog(this, this, mHour, mMinutes,
160 DateFormat.is24HourFormat(this)).show();
163 return super.onPreferenceTreeClick(preferenceScreen, preference);
167 public void onBackPressed() {
172 public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
176 // If the time has been changed, enable the alarm.
180 private void updateTime() {
182 Log.v("updateTime " + mId);
184 mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
185 mRepeatPref.getDaysOfWeek()));
188 private void saveAlarm() {
189 final String alert = mAlarmPref.getAlertString();
190 Alarms.setAlarm(this, mId, mEnabled, mHour, mMinutes,
191 mRepeatPref.getDaysOfWeek(), mVibratePref.isChecked(),
192 mLabel.getText(), alert);
195 popAlarmSetToast(this, mHour, mMinutes,
196 mRepeatPref.getDaysOfWeek());
201 * Write alarm out to persistent store and pops toast if alarm
204 private static void saveAlarm(
205 Context context, int id, boolean enabled, int hour, int minute,
206 Alarm.DaysOfWeek daysOfWeek, boolean vibrate, String label,
207 String alert, boolean popToast) {
208 if (Log.LOGV) Log.v("** saveAlarm " + id + " " + label + " " + enabled
209 + " " + hour + " " + minute + " vibe " + vibrate);
211 // Fix alert string first
212 Alarms.setAlarm(context, id, enabled, hour, minute, daysOfWeek, vibrate,
215 if (enabled && popToast) {
216 popAlarmSetToast(context, hour, minute, daysOfWeek);
221 * Display a toast that tells the user how long until the alarm
222 * goes off. This helps prevent "am/pm" mistakes.
224 static void popAlarmSetToast(Context context, int hour, int minute,
225 Alarm.DaysOfWeek daysOfWeek) {
227 String toastText = formatToast(context, hour, minute, daysOfWeek);
228 Toast toast = Toast.makeText(context, toastText, Toast.LENGTH_LONG);
229 ToastMaster.setToast(toast);
234 * format "Alarm set for 2 days 7 hours and 53 minutes from
237 static String formatToast(Context context, int hour, int minute,
238 Alarm.DaysOfWeek daysOfWeek) {
239 long alarm = Alarms.calculateAlarm(hour, minute,
240 daysOfWeek).getTimeInMillis();
241 long delta = alarm - System.currentTimeMillis();;
242 long hours = delta / (1000 * 60 * 60);
243 long minutes = delta / (1000 * 60) % 60;
244 long days = hours / 24;
247 String daySeq = (days == 0) ? "" :
248 (days == 1) ? context.getString(R.string.day) :
249 context.getString(R.string.days, Long.toString(days));
251 String minSeq = (minutes == 0) ? "" :
252 (minutes == 1) ? context.getString(R.string.minute) :
253 context.getString(R.string.minutes, Long.toString(minutes));
255 String hourSeq = (hours == 0) ? "" :
256 (hours == 1) ? context.getString(R.string.hour) :
257 context.getString(R.string.hours, Long.toString(hours));
259 boolean dispDays = days > 0;
260 boolean dispHour = hours > 0;
261 boolean dispMinute = minutes > 0;
263 int index = (dispDays ? 1 : 0) |
265 (dispMinute ? 4 : 0);
267 String[] formats = context.getResources().getStringArray(R.array.alarm_set);
268 return String.format(formats[index], daySeq, hourSeq, minSeq);
271 public boolean onCreateOptionsMenu(Menu menu) {
272 super.onCreateOptionsMenu(menu);
274 mDeleteAlarmItem = menu.add(0, 0, 0, R.string.delete_alarm);
275 mDeleteAlarmItem.setIcon(android.R.drawable.ic_menu_delete);
277 if (AlarmClock.DEBUG) {
278 mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
284 public boolean onOptionsItemSelected(MenuItem item) {
285 if (item == mDeleteAlarmItem) {
286 Alarms.deleteAlarm(this, mId);
290 if (AlarmClock.DEBUG) {
291 if (item == mTestAlarmItem) {
302 * Test code: this is disabled for production build. Sets
303 * this alarm to go off on the next minute
305 void setTestAlarm() {
308 java.util.Calendar c = java.util.Calendar.getInstance();
309 c.setTimeInMillis(System.currentTimeMillis());
311 int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
312 int nowMinute = c.get(java.util.Calendar.MINUTE);
314 int minutes = (nowMinute + 1) % 60;
315 int hour = nowHour + (nowMinute == 0 ? 1 : 0);
317 saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
318 true, mLabel.getText(), mAlarmPref.getAlertString(), true);