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.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.content.res.Configuration;
26 import android.database.Cursor;
27 import android.database.DataSetObserver;
28 import android.net.Uri;
29 import android.os.Bundle;
30 import android.os.Handler;
31 import android.provider.Settings;
32 import android.view.ContextMenu;
33 import android.view.ContextMenu.ContextMenuInfo;
34 import android.view.LayoutInflater;
35 import android.view.Menu;
36 import android.view.MenuItem;
37 import android.view.View;
38 import android.view.View.OnClickListener;
39 import android.view.View.OnCreateContextMenuListener;
40 import android.view.ViewGroup;
41 import android.widget.AdapterView;
42 import android.widget.AdapterView.AdapterContextMenuInfo;
43 import android.widget.AdapterView.OnItemClickListener;
44 import android.widget.Button;
45 import android.widget.CheckBox;
46 import android.widget.CursorAdapter;
47 import android.widget.ListView;
48 import android.widget.TextView;
50 import java.util.Calendar;
51 import java.text.DateFormatSymbols;
54 * AlarmClock application.
56 public class AlarmClock extends Activity implements OnItemClickListener {
58 final static String PREFERENCES = "AlarmClock";
60 /** Cap alarm count at this number */
61 final static int MAX_ALARM_COUNT = 12;
63 /** This must be false for production. If true, turns on logging,
65 final static boolean DEBUG = false;
67 private SharedPreferences mPrefs;
68 private LayoutInflater mFactory;
69 private ListView mAlarmsList;
70 private Cursor mCursor;
72 private String mAm, mPm;
74 private class AlarmTimeAdapter extends CursorAdapter {
75 public AlarmTimeAdapter(Context context, Cursor cursor) {
76 super(context, cursor);
79 public View newView(Context context, Cursor cursor, ViewGroup parent) {
80 View ret = mFactory.inflate(R.layout.alarm_time, parent, false);
82 ((TextView) ret.findViewById(R.id.am)).setText(mAm);
83 ((TextView) ret.findViewById(R.id.pm)).setText(mPm);
85 DigitalClock digitalClock = (DigitalClock)ret.findViewById(R.id.digitalClock);
86 digitalClock.setLive(false);
87 if (Log.LOGV) Log.v("newView " + cursor.getPosition());
91 public void bindView(View view, Context context, Cursor cursor) {
92 final Alarm alarm = new Alarm(cursor);
94 CheckBox onButton = (CheckBox)view.findViewById(R.id.alarmButton);
95 onButton.setChecked(alarm.enabled);
96 onButton.setOnClickListener(new OnClickListener() {
97 public void onClick(View v) {
98 boolean isChecked = ((CheckBox) v).isChecked();
99 Alarms.enableAlarm(AlarmClock.this, alarm.id,
102 SetAlarm.popAlarmSetToast(AlarmClock.this,
103 alarm.hour, alarm.minutes, alarm.daysOfWeek);
108 DigitalClock digitalClock =
109 (DigitalClock) view.findViewById(R.id.digitalClock);
111 // set the alarm text
112 final Calendar c = Calendar.getInstance();
113 c.set(Calendar.HOUR_OF_DAY, alarm.hour);
114 c.set(Calendar.MINUTE, alarm.minutes);
115 digitalClock.updateTime(c);
117 // Set the repeat text or leave it blank if it does not repeat.
118 TextView daysOfWeekView =
119 (TextView) digitalClock.findViewById(R.id.daysOfWeek);
120 final String daysOfWeekStr =
121 alarm.daysOfWeek.toString(AlarmClock.this, false);
122 if (daysOfWeekStr != null && daysOfWeekStr.length() != 0) {
123 daysOfWeekView.setText(daysOfWeekStr);
124 daysOfWeekView.setVisibility(View.VISIBLE);
126 daysOfWeekView.setVisibility(View.GONE);
131 (TextView) digitalClock.findViewById(R.id.label);
132 if (alarm.label != null && alarm.label.length() != 0) {
133 labelView.setText(alarm.label);
134 labelView.setVisibility(View.VISIBLE);
136 labelView.setVisibility(View.GONE);
142 public boolean onContextItemSelected(final MenuItem item) {
143 final AdapterContextMenuInfo info =
144 (AdapterContextMenuInfo) item.getMenuInfo();
145 final int id = (int) info.id;
146 switch (item.getItemId()) {
147 case R.id.delete_alarm:
148 // Confirm that the alarm will be deleted.
149 new AlertDialog.Builder(this)
150 .setTitle(getString(R.string.delete_alarm))
151 .setMessage(getString(R.string.delete_alarm_confirm))
152 .setPositiveButton(android.R.string.ok,
153 new DialogInterface.OnClickListener() {
154 public void onClick(DialogInterface d,
156 Alarms.deleteAlarm(AlarmClock.this, id);
159 .setNegativeButton(android.R.string.cancel, null)
163 case R.id.enable_alarm:
164 final Cursor c = (Cursor) mAlarmsList.getAdapter()
165 .getItem(info.position);
166 final Alarm alarm = new Alarm(c);
167 Alarms.enableAlarm(this, alarm.id, !alarm.enabled);
168 if (!alarm.enabled) {
169 SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes,
177 return super.onContextItemSelected(item);
181 protected void onCreate(Bundle icicle) {
182 super.onCreate(icicle);
184 String[] ampm = new DateFormatSymbols().getAmPmStrings();
188 mFactory = LayoutInflater.from(this);
189 mPrefs = getSharedPreferences(PREFERENCES, 0);
190 mCursor = Alarms.getAlarmsCursor(getContentResolver());
195 private void updateLayout() {
196 setContentView(R.layout.alarm_clock);
197 mAlarmsList = (ListView) findViewById(R.id.alarms_list);
198 AlarmTimeAdapter adapter = new AlarmTimeAdapter(this, mCursor);
199 mAlarmsList.setAdapter(adapter);
200 mAlarmsList.setVerticalScrollBarEnabled(true);
201 mAlarmsList.setOnItemClickListener(this);
202 mAlarmsList.setOnCreateContextMenuListener(this);
204 final Button addAlarm = (Button) findViewById(R.id.add_alarm);
205 addAlarm.setOnClickListener(new View.OnClickListener() {
206 public void onClick(View v) {
207 Uri uri = Alarms.addAlarm(getContentResolver());
208 // FIXME: scroll to new item?
209 String segment = uri.getPathSegments().get(1);
210 int newId = Integer.parseInt(segment);
212 Log.v("In AlarmClock, new alarm id = " + newId);
215 new Intent(AlarmClock.this, SetAlarm.class);
216 intent.putExtra(Alarms.ALARM_ID, newId);
217 startActivity(intent);
220 // Update the enabled state of the "Add alarm" menu item depending on
221 // how many alarms are set.
222 adapter.registerDataSetObserver(new DataSetObserver() {
223 public void onChanged() {
224 updateAddAlarmButton(addAlarm);
226 public void onInvalidate() {
227 updateAddAlarmButton(addAlarm);
231 Button settings = (Button) findViewById(R.id.settings);
232 settings.setOnClickListener(new View.OnClickListener() {
233 public void onClick(View v) {
235 new Intent(AlarmClock.this, SettingsActivity.class));
240 private void updateAddAlarmButton(Button b) {
241 b.setEnabled(mAlarmsList.getAdapter().getCount() < MAX_ALARM_COUNT);
245 protected void onDestroy() {
247 ToastMaster.cancelToast();
248 mCursor.deactivate();
252 public void onCreateContextMenu(ContextMenu menu, View view,
253 ContextMenuInfo menuInfo) {
254 // Inflate the menu from xml.
255 getMenuInflater().inflate(R.menu.context_menu, menu);
257 // Use the current item to create a custom view for the header.
258 final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
260 (Cursor) mAlarmsList.getAdapter().getItem((int) info.position);
261 final Alarm alarm = new Alarm(c);
263 // Construct the Calendar to compute the time.
264 final Calendar cal = Calendar.getInstance();
265 cal.set(Calendar.HOUR_OF_DAY, alarm.hour);
266 cal.set(Calendar.MINUTE, alarm.minutes);
267 final String time = Alarms.formatTime(this, cal);
269 // Inflate the custom view and set each TextView's text.
270 final View v = mFactory.inflate(R.layout.context_menu_header, null);
271 TextView textView = (TextView) v.findViewById(R.id.header_time);
272 textView.setText(time);
273 textView = (TextView) v.findViewById(R.id.header_label);
274 textView.setText(alarm.label);
276 // Set the custom view on the menu.
277 menu.setHeaderView(v);
278 // Change the text to "disable" if the alarm is already enabled.
280 menu.findItem(R.id.enable_alarm).setTitle(R.string.disable_alarm);
284 public void onItemClick(AdapterView parent, View v, int pos, long id) {
285 Intent intent = new Intent(this, SetAlarm.class);
286 intent.putExtra(Alarms.ALARM_ID, (int) id);
287 startActivity(intent);