OSDN Git Service

set alarm volume adjustable and disable vibrate for platform
[android-x86/packages-apps-DeskClock.git] / src / com / android / deskclock / SetAlarm.java
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package com.android.deskclock;
18
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;
44
45 /**
46  * Manages each alarm
47  */
48 public class SetAlarm extends PreferenceActivity
49         implements TimePickerDialog.OnTimeSetListener {
50
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;
58
59     private int     mId;
60     private int     mHour;
61     private int     mMinutes;
62
63     /**
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.
66      */
67     @Override
68     protected void onCreate(Bundle icicle) {
69         super.onCreate(icicle);
70         AlarmClock.setVolumeControlForPlatform(this);
71
72         addPreferencesFromResource(R.xml.alarm_prefs);
73
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,
79                             Object newValue) {
80                         // Set the summary based on the new label.
81                         p.setSummary((String) newValue);
82                         return true;
83                     }
84                 });
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");
91
92         Intent i = getIntent();
93         mId = i.getIntExtra(Alarms.ALARM_ID, -1);
94         if (Log.LOGV) {
95             Log.v("In SetAlarm, alarm id = " + mId);
96         }
97
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);
103         mHour = alarm.hour;
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);
109         updateTime();
110
111         // We have to do this to get the save/cancel buttons to highlight on
112         // their own.
113         getListView().setItemsCanFocus(true);
114
115         // Grab the content view so we can modify it.
116         FrameLayout content = (FrameLayout) getWindow().getDecorView()
117                 .findViewById(com.android.internal.R.id.content);
118
119         // Get the main ListView and remove it from the content view.
120         ListView lv = getListView();
121         content.removeView(lv);
122
123         // Create the new LinearLayout that will become the content view and
124         // make it vertical.
125         LinearLayout ll = new LinearLayout(this);
126         ll.setOrientation(LinearLayout.VERTICAL);
127
128         // Have the ListView expand to fill the screen minus the save/cancel
129         // buttons.
130         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
131                 LayoutParams.FILL_PARENT,
132                 LayoutParams.WRAP_CONTENT);
133         lp.weight = 1;
134         ll.addView(lv, lp);
135
136         // Inflate the buttons onto the LinearLayout.
137         View v = LayoutInflater.from(this).inflate(
138                 R.layout.save_cancel_alarm, ll);
139
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) {
144                     saveAlarm();
145                     finish();
146                 }
147         });
148         b = (Button) v.findViewById(R.id.alarm_cancel);
149         b.setOnClickListener(new View.OnClickListener() {
150                 public void onClick(View v) {
151                     finish();
152                 }
153         });
154         b = (Button) v.findViewById(R.id.alarm_delete);
155         b.setOnClickListener(new View.OnClickListener() {
156                 public void onClick(View v) {
157                     deleteAlarm();
158                 }
159         });
160
161         // Replace the old content view with our new one.
162         setContentView(ll);
163     }
164
165     @Override
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();
171         }
172
173         return super.onPreferenceTreeClick(preferenceScreen, preference);
174     }
175
176     @Override
177     public void onBackPressed() {
178         saveAlarm();
179         finish();
180     }
181
182     public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
183         mHour = hourOfDay;
184         mMinutes = minute;
185         updateTime();
186         // If the time has been changed, enable the alarm.
187         mEnabledPref.setChecked(true);
188     }
189
190     private void updateTime() {
191         if (Log.LOGV) {
192             Log.v("updateTime " + mId);
193         }
194         mTimePref.setSummary(Alarms.formatTime(this, mHour, mMinutes,
195                 mRepeatPref.getDaysOfWeek()));
196     }
197
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);
203
204         if (mEnabledPref.isChecked()) {
205             popAlarmSetToast(this, time);
206         }
207     }
208
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);
217                                 finish();
218                             }
219                         })
220                 .setNegativeButton(android.R.string.cancel, null)
221                 .show();
222     }
223
224     /**
225      * Write alarm out to persistent store and pops toast if alarm
226      * enabled.
227      * Used only in test code.
228      */
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);
235
236         // Fix alert string first
237         long time = Alarms.setAlarm(context, id, enabled, hour, minute,
238                 daysOfWeek, vibrate, label, alert);
239
240         if (enabled && popToast) {
241             popAlarmSetToast(context, time);
242         }
243     }
244
245     /**
246      * Display a toast that tells the user how long until the alarm
247      * goes off.  This helps prevent "am/pm" mistakes.
248      */
249     static void popAlarmSetToast(Context context, int hour, int minute,
250                                  Alarm.DaysOfWeek daysOfWeek) {
251         popAlarmSetToast(context,
252                 Alarms.calculateAlarm(hour, minute, daysOfWeek)
253                 .getTimeInMillis());
254     }
255
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);
260         toast.show();
261     }
262
263     /**
264      * format "Alarm set for 2 days 7 hours and 53 minutes from
265      * now"
266      */
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;
272         hours = hours % 24;
273
274         String daySeq = (days == 0) ? "" :
275                 (days == 1) ? context.getString(R.string.day) :
276                 context.getString(R.string.days, Long.toString(days));
277
278         String minSeq = (minutes == 0) ? "" :
279                 (minutes == 1) ? context.getString(R.string.minute) :
280                 context.getString(R.string.minutes, Long.toString(minutes));
281
282         String hourSeq = (hours == 0) ? "" :
283                 (hours == 1) ? context.getString(R.string.hour) :
284                 context.getString(R.string.hours, Long.toString(hours));
285
286         boolean dispDays = days > 0;
287         boolean dispHour = hours > 0;
288         boolean dispMinute = minutes > 0;
289
290         int index = (dispDays ? 1 : 0) |
291                     (dispHour ? 2 : 0) |
292                     (dispMinute ? 4 : 0);
293
294         String[] formats = context.getResources().getStringArray(R.array.alarm_set);
295         return String.format(formats[index], daySeq, hourSeq, minSeq);
296     }
297
298     public boolean onCreateOptionsMenu(Menu menu) {
299         super.onCreateOptionsMenu(menu);
300
301         if (AlarmClock.DEBUG) {
302             mTestAlarmItem = menu.add(0, 0, 0, "test alarm");
303         }
304
305         return true;
306     }
307
308     public boolean onOptionsItemSelected(MenuItem item) {
309         if (AlarmClock.DEBUG) {
310             if (item == mTestAlarmItem) {
311                 setTestAlarm();
312                 return true;
313             }
314         }
315
316         return false;
317     }
318
319
320     /**
321      * Test code: this is disabled for production build.  Sets
322      * this alarm to go off on the next minute
323      */
324     void setTestAlarm() {
325
326         // start with now
327         java.util.Calendar c = java.util.Calendar.getInstance();
328         c.setTimeInMillis(System.currentTimeMillis());
329
330         int nowHour = c.get(java.util.Calendar.HOUR_OF_DAY);
331         int nowMinute = c.get(java.util.Calendar.MINUTE);
332
333         int minutes = (nowMinute + 1) % 60;
334         int hour = nowHour + (nowMinute == 0 ? 1 : 0);
335
336         saveAlarm(this, mId, true, hour, minutes, mRepeatPref.getDaysOfWeek(),
337                 true, mLabel.getText(), mAlarmPref.getAlertString(), true);
338     }
339
340 }