OSDN Git Service

a25cd20e9156a9c5e833a0009d407efa76531db2
[android-x86/packages-apps-AlarmClock.git] / src / com / android / alarmclock / AlarmClock.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.alarmclock;
18
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.content.SharedPreferences;
25 import android.database.Cursor;
26 import android.net.Uri;
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.SystemProperties;
30 import android.provider.Settings;
31 import android.view.ContextMenu;
32 import android.view.ContextMenu.ContextMenuInfo;
33 import android.view.LayoutInflater;
34 import android.view.Menu;
35 import android.view.MenuItem;
36 import android.view.View;
37 import android.view.View.OnClickListener;
38 import android.view.ViewGroup;
39 import android.widget.CursorAdapter;
40 import android.widget.ListView;
41 import android.widget.TextView;
42 import android.widget.CheckBox;
43 import android.media.AudioManager;
44 import java.util.Calendar;
45 import java.text.DateFormatSymbols;
46
47 /**
48  * AlarmClock application.
49  */
50 public class AlarmClock extends Activity {
51
52     final static String PREFERENCES = "AlarmClock";
53     final static String PREF_CLOCK_FACE = "face";
54     final static String PREF_SHOW_CLOCK = "show_clock";
55
56     /** Cap alarm count at this number */
57     final static int MAX_ALARM_COUNT = 12;
58
59     /** This must be false for production.  If true, turns on logging,
60         test code, etc. */
61     final static boolean DEBUG = false;
62
63     private SharedPreferences mPrefs;
64     private LayoutInflater mFactory;
65     private ViewGroup mClockLayout;
66     private View mClock = null;
67     private MenuItem mAddAlarmItem;
68     private MenuItem mToggleClockItem;
69     private ListView mAlarmsList;
70     private Cursor mCursor;
71     private static boolean volumeAdjustable;
72     private String mAm, mPm;
73
74     /**
75      * Which clock face to show
76      */
77     private int mFace = -1;
78
79     /*
80      * FIXME: it would be nice for this to live in an xml config file.
81      */
82     final static int[] CLOCKS = {
83         R.layout.clock_basic_bw,
84         R.layout.clock_googly,
85         R.layout.clock_droid2,
86         R.layout.clock_droids,
87         R.layout.digital_clock
88     };
89
90     private class AlarmTimeAdapter extends CursorAdapter {
91         public AlarmTimeAdapter(Context context, Cursor cursor) {
92             super(context, cursor);
93         }
94
95         public View newView(Context context, Cursor cursor, ViewGroup parent) {
96             View ret = mFactory.inflate(R.layout.alarm_time, parent, false);
97
98             ((TextView) ret.findViewById(R.id.am)).setText(mAm);
99             ((TextView) ret.findViewById(R.id.pm)).setText(mPm);
100
101             DigitalClock digitalClock = (DigitalClock)ret.findViewById(R.id.digitalClock);
102             digitalClock.setLive(false);
103             if (Log.LOGV) Log.v("newView " + cursor.getPosition());
104             return ret;
105         }
106
107         public void bindView(View view, Context context, Cursor cursor) {
108             final int id = cursor.getInt(Alarms.AlarmColumns.ALARM_ID_INDEX);
109             final int hour = cursor.getInt(Alarms.AlarmColumns.ALARM_HOUR_INDEX);
110             final int minutes = cursor.getInt(Alarms.AlarmColumns.ALARM_MINUTES_INDEX);
111             final Alarms.DaysOfWeek daysOfWeek = new Alarms.DaysOfWeek(
112                     cursor.getInt(Alarms.AlarmColumns.ALARM_DAYS_OF_WEEK_INDEX));
113             final boolean enabled = cursor.getInt(Alarms.AlarmColumns.ALARM_ENABLED_INDEX) == 1;
114             final String label =
115                     cursor.getString(Alarms.AlarmColumns.ALARM_MESSAGE_INDEX);
116
117             CheckBox onButton = (CheckBox)view.findViewById(R.id.alarmButton);
118             onButton.setChecked(enabled);
119             onButton.setOnClickListener(new OnClickListener() {
120                     public void onClick(View v) {
121                         boolean isChecked = ((CheckBox) v).isChecked();
122                         Alarms.enableAlarm(AlarmClock.this, id, isChecked);
123                         if (isChecked) {
124                             SetAlarm.popAlarmSetToast(
125                                     AlarmClock.this, hour, minutes, daysOfWeek);
126                         }
127                     }
128             });
129
130             DigitalClock digitalClock = (DigitalClock)view.findViewById(R.id.digitalClock);
131             if (Log.LOGV) Log.v("bindView " + cursor.getPosition() + " " + id + " " + hour +
132                                 ":" + minutes + " " + daysOfWeek.toString(context, true) + " dc " + digitalClock);
133
134             digitalClock.setOnClickListener(new OnClickListener() {
135                     public void onClick(View v) {
136                         if (true) {
137                             Intent intent = new Intent(AlarmClock.this, SetAlarm.class);
138                             intent.putExtra(Alarms.ID, id);
139                             startActivity(intent);
140                         } else {
141                             // TESTING: immediately pop alarm
142                             Intent fireAlarm = new Intent(AlarmClock.this, AlarmAlert.class);
143                             fireAlarm.putExtra(Alarms.ID, id);
144                             fireAlarm.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
145                             startActivity(fireAlarm);
146                         }
147                     }
148                 });
149
150             // set the alarm text
151             final Calendar c = Calendar.getInstance();
152             c.set(Calendar.HOUR_OF_DAY, hour);
153             c.set(Calendar.MINUTE, minutes);
154             digitalClock.updateTime(c);
155
156             // Set the repeat text or leave it blank if it does not repeat.
157             TextView daysOfWeekView = (TextView) digitalClock.findViewById(R.id.daysOfWeek);
158             final String daysOfWeekStr =
159                     daysOfWeek.toString(AlarmClock.this, false);
160             if (daysOfWeekStr != null && daysOfWeekStr.length() != 0) {
161                 daysOfWeekView.setText(daysOfWeekStr);
162                 daysOfWeekView.setVisibility(View.VISIBLE);
163             } else {
164                 daysOfWeekView.setVisibility(View.GONE);
165             }
166
167             // Display the label
168             TextView labelView =
169                     (TextView) digitalClock.findViewById(R.id.label);
170             if (label != null && label.length() != 0) {
171                 labelView.setText(label);
172             } else {
173                 labelView.setText(R.string.default_label);
174             }
175
176             // Build context menu
177             digitalClock.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
178                     public void onCreateContextMenu(ContextMenu menu, View view,
179                                                     ContextMenuInfo menuInfo) {
180                         menu.setHeaderTitle(Alarms.formatTime(AlarmClock.this, c));
181                         MenuItem deleteAlarmItem = menu.add(0, id, 0, R.string.delete_alarm);
182                     }
183                 });
184         }
185     };
186
187     @Override
188     public boolean onContextItemSelected(final MenuItem item) {
189         // Confirm that the alarm will be deleted.
190         new AlertDialog.Builder(this)
191                 .setTitle(getString(R.string.delete_alarm))
192                 .setMessage(getString(R.string.delete_alarm_confirm))
193                 .setPositiveButton(android.R.string.ok,
194                         new DialogInterface.OnClickListener() {
195                             public void onClick(DialogInterface d, int w) {
196                                 Alarms.deleteAlarm(AlarmClock.this,
197                                         item.getItemId());
198                             }
199                         })
200                 .setNegativeButton(android.R.string.cancel, null)
201                 .show();
202         return true;
203     }
204
205     @Override
206     protected void onCreate(Bundle icicle) {
207         super.onCreate(icicle);
208         volumeAdjustable=SystemProperties.getBoolean("ro.alarm.volume.adjustable",false);       
209         AlarmClock.setVolumeControlForPlatform(this);
210         
211         String[] ampm = new DateFormatSymbols().getAmPmStrings();
212         mAm = ampm[0];
213         mPm = ampm[1];
214
215         // sanity check -- no database, no clock
216         if (getContentResolver() == null) {
217             new AlertDialog.Builder(this)
218                     .setTitle(getString(R.string.error))
219                     .setMessage(getString(R.string.dberror))
220                     .setPositiveButton(
221                             android.R.string.ok,
222                             new DialogInterface.OnClickListener() {
223                                 public void onClick(DialogInterface dialog, int which) {
224                                     finish();
225                                 }
226                             })
227                     .setOnCancelListener(
228                             new DialogInterface.OnCancelListener() {
229                                 public void onCancel(DialogInterface dialog) {
230                                     finish();
231                                 }})
232                     .setIcon(android.R.drawable.ic_dialog_alert)
233                     .create().show();
234             return;
235         }
236
237         setContentView(R.layout.alarm_clock);
238         mFactory = LayoutInflater.from(this);
239         mPrefs = getSharedPreferences(PREFERENCES, 0);
240
241         mCursor = Alarms.getAlarmsCursor(getContentResolver());
242         mAlarmsList = (ListView) findViewById(R.id.alarms_list);
243         mAlarmsList.setAdapter(new AlarmTimeAdapter(this, mCursor));
244         mAlarmsList.setVerticalScrollBarEnabled(true);
245         mAlarmsList.setItemsCanFocus(true);
246
247         mClockLayout = (ViewGroup) findViewById(R.id.clock_layout);
248         mClockLayout.setOnClickListener(new View.OnClickListener() {
249                 public void onClick(View v) {
250                     final Intent intent = new Intent(AlarmClock.this, ClockPicker.class);
251                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
252                     startActivity(intent);
253                 }
254             });
255
256         setClockVisibility(mPrefs.getBoolean(PREF_SHOW_CLOCK, true));
257     }
258
259     @Override
260     protected void onResume() {
261         super.onResume();
262
263         int face = mPrefs.getInt(PREF_CLOCK_FACE, 0);
264         if (mFace != face) {
265             if (face < 0 || face >= AlarmClock.CLOCKS.length)
266                 mFace = 0;
267             else
268                 mFace = face;
269             inflateClock();
270         }
271     }
272
273     @Override
274     protected void onDestroy() {
275         super.onDestroy();
276         ToastMaster.cancelToast();
277         mCursor.deactivate();
278     }
279
280     protected void inflateClock() {
281         if (mClock != null) {
282             mClockLayout.removeView(mClock);
283         }
284
285         LayoutInflater.from(this).inflate(CLOCKS[mFace], mClockLayout);
286         mClock = findViewById(R.id.clock);
287
288         TextView am = (TextView) findViewById(R.id.am);
289         TextView pm = (TextView) findViewById(R.id.pm);
290
291         if (am != null) {
292             am.setText(mAm);
293         }
294         if (pm != null) {
295             pm.setText(mPm);
296         }
297     }
298
299     @Override
300     public boolean onCreateOptionsMenu(Menu menu) {
301         // Inflate our menu.
302         getMenuInflater().inflate(R.menu.main_menu, menu);
303
304         return super.onCreateOptionsMenu(menu);
305     }
306
307     /**
308      * Only allow user to add a new alarm if there are fewer than
309      * MAX_ALARM_COUNT
310      */
311     @Override
312     public boolean onPrepareOptionsMenu(Menu menu) {
313         menu.findItem(R.id.menu_add_alarm).setVisible(
314                 mAlarmsList.getAdapter().getCount() < MAX_ALARM_COUNT);
315         menu.findItem(R.id.menu_toggle_clock).setTitle(
316                 getClockVisibility() ? R.string.hide_clock
317                     : R.string.show_clock);
318         return super.onPrepareOptionsMenu(menu);
319     }
320
321     @Override
322     public boolean onOptionsItemSelected(MenuItem item) {
323         switch (item.getItemId()) {
324             case R.id.menu_add_alarm:
325                 Uri uri = Alarms.addAlarm(getContentResolver());
326                 // FIXME: scroll to new item?
327                 String segment = uri.getPathSegments().get(1);
328                 int newId = Integer.parseInt(segment);
329                 if (Log.LOGV) {
330                     Log.v("In AlarmClock, new alarm id = " + newId);
331                 }
332                 Intent intent = new Intent(this, SetAlarm.class);
333                 intent.putExtra(Alarms.ID, newId);
334                 startActivity(intent);
335                 return true;
336
337             case R.id.menu_toggle_clock:
338                 setClockVisibility(!getClockVisibility());
339                 saveClockVisibility();
340                 return true;
341
342             case R.id.menu_settings:
343                 startActivity(new Intent(this, SettingsActivity.class));
344                 return true;
345         }
346
347         return super.onOptionsItemSelected(item);
348     }
349
350
351     private boolean getClockVisibility() {
352         return mClockLayout.getVisibility() == View.VISIBLE;
353     }
354
355     private void setClockVisibility(boolean visible) {
356         mClockLayout.setVisibility(visible ? View.VISIBLE : View.GONE);
357     }
358
359     private void saveClockVisibility() {
360         mPrefs.edit().putBoolean(PREF_SHOW_CLOCK, getClockVisibility()).commit();
361     }
362     public static void setVolumeControlForPlatform(Activity context){
363             if (isVolumeAdjustable()){
364                 context.setVolumeControlStream(AudioManager.STREAM_ALARM);
365             }else{
366                 //Use default stream type,the default type use a fixed volume
367                 context.setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
368             }
369     }
370     public static boolean isVolumeAdjustable(){
371         return  volumeAdjustable;
372     }
373 }