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.graphics.Typeface;
28 import android.net.Uri;
29 import android.os.Bundle;
30 import android.os.Handler;
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.AdapterView;
40 import android.widget.AdapterView.AdapterContextMenuInfo;
41 import android.widget.AdapterView.OnItemClickListener;
42 import android.widget.Button;
43 import android.widget.CheckBox;
44 import android.widget.CursorAdapter;
45 import android.widget.ImageButton;
46 import android.widget.ImageView;
47 import android.widget.ListView;
48 import android.widget.TextView;
50 import java.util.Calendar;
53 * AlarmClock application.
55 public class AlarmClock extends Activity implements OnItemClickListener {
57 static final String PREFERENCES = "AlarmClock";
59 /** This must be false for production. If true, turns on logging,
61 static final boolean DEBUG = false;
63 private SharedPreferences mPrefs;
64 private LayoutInflater mFactory;
65 private ListView mAlarmsList;
66 private Cursor mCursor;
68 private void updateIndicatorAndAlarm(boolean enabled, ImageView bar,
70 bar.setImageResource(enabled ? R.drawable.ic_indicator_on
71 : R.drawable.ic_indicator_off);
72 Alarms.enableAlarm(this, alarm.id, enabled);
74 SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes,
79 private class AlarmTimeAdapter extends CursorAdapter {
80 public AlarmTimeAdapter(Context context, Cursor cursor) {
81 super(context, cursor);
84 public View newView(Context context, Cursor cursor, ViewGroup parent) {
85 View ret = mFactory.inflate(R.layout.alarm_time, parent, false);
87 DigitalClock digitalClock =
88 (DigitalClock) ret.findViewById(R.id.digitalClock);
89 digitalClock.setLive(false);
93 public void bindView(View view, Context context, Cursor cursor) {
94 final Alarm alarm = new Alarm(cursor);
96 View indicator = view.findViewById(R.id.indicator);
98 // Set the initial resource for the bar image.
99 final ImageView barOnOff =
100 (ImageView) indicator.findViewById(R.id.bar_onoff);
101 barOnOff.setImageResource(alarm.enabled ?
102 R.drawable.ic_indicator_on : R.drawable.ic_indicator_off);
104 // Set the initial state of the clock "checkbox"
105 final CheckBox clockOnOff =
106 (CheckBox) indicator.findViewById(R.id.clock_onoff);
107 clockOnOff.setChecked(alarm.enabled);
109 // Clicking outside the "checkbox" should also change the state.
110 indicator.setOnClickListener(new OnClickListener() {
111 public void onClick(View v) {
113 updateIndicatorAndAlarm(clockOnOff.isChecked(),
118 DigitalClock digitalClock =
119 (DigitalClock) view.findViewById(R.id.digitalClock);
121 // set the alarm text
122 final Calendar c = Calendar.getInstance();
123 c.set(Calendar.HOUR_OF_DAY, alarm.hour);
124 c.set(Calendar.MINUTE, alarm.minutes);
125 digitalClock.updateTime(c);
126 digitalClock.setTypeface(Typeface.DEFAULT);
128 // Set the repeat text or leave it blank if it does not repeat.
129 TextView daysOfWeekView =
130 (TextView) digitalClock.findViewById(R.id.daysOfWeek);
131 final String daysOfWeekStr =
132 alarm.daysOfWeek.toString(AlarmClock.this, false);
133 if (daysOfWeekStr != null && daysOfWeekStr.length() != 0) {
134 daysOfWeekView.setText(daysOfWeekStr);
135 daysOfWeekView.setVisibility(View.VISIBLE);
137 daysOfWeekView.setVisibility(View.GONE);
142 (TextView) view.findViewById(R.id.label);
143 if (alarm.label != null && alarm.label.length() != 0) {
144 labelView.setText(alarm.label);
145 labelView.setVisibility(View.VISIBLE);
147 labelView.setVisibility(View.GONE);
153 public boolean onContextItemSelected(final MenuItem item) {
154 final AdapterContextMenuInfo info =
155 (AdapterContextMenuInfo) item.getMenuInfo();
156 final int id = (int) info.id;
157 switch (item.getItemId()) {
158 case R.id.delete_alarm:
159 // Confirm that the alarm will be deleted.
160 new AlertDialog.Builder(this)
161 .setTitle(getString(R.string.delete_alarm))
162 .setMessage(getString(R.string.delete_alarm_confirm))
163 .setPositiveButton(android.R.string.ok,
164 new DialogInterface.OnClickListener() {
165 public void onClick(DialogInterface d,
167 Alarms.deleteAlarm(AlarmClock.this, id);
170 .setNegativeButton(android.R.string.cancel, null)
174 case R.id.enable_alarm:
175 final Cursor c = (Cursor) mAlarmsList.getAdapter()
176 .getItem(info.position);
177 final Alarm alarm = new Alarm(c);
178 Alarms.enableAlarm(this, alarm.id, !alarm.enabled);
179 if (!alarm.enabled) {
180 SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes,
185 case R.id.edit_alarm:
186 Intent intent = new Intent(this, SetAlarm.class);
187 intent.putExtra(Alarms.ALARM_ID, id);
188 startActivity(intent);
194 return super.onContextItemSelected(item);
198 protected void onCreate(Bundle icicle) {
199 super.onCreate(icicle);
201 mFactory = LayoutInflater.from(this);
202 mPrefs = getSharedPreferences(PREFERENCES, 0);
203 mCursor = Alarms.getAlarmsCursor(getContentResolver());
208 private void updateLayout() {
209 setContentView(R.layout.alarm_clock);
210 mAlarmsList = (ListView) findViewById(R.id.alarms_list);
211 AlarmTimeAdapter adapter = new AlarmTimeAdapter(this, mCursor);
212 mAlarmsList.setAdapter(adapter);
213 mAlarmsList.setVerticalScrollBarEnabled(true);
214 mAlarmsList.setOnItemClickListener(this);
215 mAlarmsList.setOnCreateContextMenuListener(this);
217 View addAlarm = findViewById(R.id.add_alarm);
218 addAlarm.setOnClickListener(new View.OnClickListener() {
219 public void onClick(View v) {
223 // Make the entire view selected when focused.
224 addAlarm.setOnFocusChangeListener(new View.OnFocusChangeListener() {
225 public void onFocusChange(View v, boolean hasFocus) {
226 v.setSelected(hasFocus);
230 ImageButton deskClock =
231 (ImageButton) findViewById(R.id.desk_clock_button);
232 deskClock.setOnClickListener(new View.OnClickListener() {
233 public void onClick(View v) {
234 startActivity(new Intent(AlarmClock.this, DeskClock.class));
239 // Version of addNewAlarm that can be called from any activity, e.g. DeskClock
240 protected static void addNewAlarm(Context context) {
241 final Uri uri = Alarms.addAlarm(context.getContentResolver());
242 final String segment = uri.getPathSegments().get(1);
243 int newId = Integer.parseInt(segment);
245 Log.v("In AlarmClock, new alarm id = " + newId);
247 final Intent intent = new Intent(context, SetAlarm.class);
248 intent.putExtra(Alarms.ALARM_ID, newId);
249 context.startActivity(intent);
252 private void addNewAlarm() {
257 protected void onDestroy() {
259 ToastMaster.cancelToast();
260 mCursor.deactivate();
264 public void onCreateContextMenu(ContextMenu menu, View view,
265 ContextMenuInfo menuInfo) {
266 // Inflate the menu from xml.
267 getMenuInflater().inflate(R.menu.context_menu, menu);
269 // Use the current item to create a custom view for the header.
270 final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
272 (Cursor) mAlarmsList.getAdapter().getItem((int) info.position);
273 final Alarm alarm = new Alarm(c);
275 // Construct the Calendar to compute the time.
276 final Calendar cal = Calendar.getInstance();
277 cal.set(Calendar.HOUR_OF_DAY, alarm.hour);
278 cal.set(Calendar.MINUTE, alarm.minutes);
279 final String time = Alarms.formatTime(this, cal);
281 // Inflate the custom view and set each TextView's text.
282 final View v = mFactory.inflate(R.layout.context_menu_header, null);
283 TextView textView = (TextView) v.findViewById(R.id.header_time);
284 textView.setText(time);
285 textView = (TextView) v.findViewById(R.id.header_label);
286 textView.setText(alarm.label);
288 // Set the custom view on the menu.
289 menu.setHeaderView(v);
290 // Change the text based on the state of the alarm.
292 menu.findItem(R.id.enable_alarm).setTitle(R.string.disable_alarm);
297 public boolean onOptionsItemSelected(MenuItem item) {
298 switch (item.getItemId()) {
299 case R.id.menu_item_settings:
300 startActivity(new Intent(this, SettingsActivity.class));
302 case R.id.menu_item_desk_clock:
303 startActivity(new Intent(this, DeskClock.class));
305 case R.id.menu_item_add_alarm:
311 return super.onOptionsItemSelected(item);
315 public boolean onCreateOptionsMenu(Menu menu) {
316 getMenuInflater().inflate(R.menu.alarm_list_menu, menu);
317 return super.onCreateOptionsMenu(menu);
320 public void onItemClick(AdapterView parent, View v, int pos, long id) {
321 Intent intent = new Intent(this, SetAlarm.class);
322 intent.putExtra(Alarms.ALARM_ID, (int) id);
323 startActivity(intent);