15fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project/*
25fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
35fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project *
45fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
55fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * you may not use this file except in compliance with the License.
65fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * You may obtain a copy of the License at
75fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project *
85fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
95fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project *
105fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
115fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
125fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * See the License for the specific language governing permissions and
145fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * limitations under the License.
155fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project */
165fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
175fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectpackage com.android.alarmclock;
185fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
195fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.app.Activity;
205fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.app.AlertDialog;
215fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.content.Context;
225fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.content.DialogInterface;
235fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.content.Intent;
245fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.content.SharedPreferences;
25cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scottimport android.content.res.Configuration;
265fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.database.Cursor;
275fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.net.Uri;
285fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.os.Bundle;
295fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.os.Handler;
305fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.ContextMenu;
315fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
325fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.LayoutInflater;
335fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.Menu;
345fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.MenuItem;
355fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.View;
365fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.View.OnClickListener;
375fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.view.ViewGroup;
380dffdefe54299ee01b45574244c92d3a06507b87Patrick Scottimport android.widget.AdapterView;
390dffdefe54299ee01b45574244c92d3a06507b87Patrick Scottimport android.widget.AdapterView.AdapterContextMenuInfo;
400dffdefe54299ee01b45574244c92d3a06507b87Patrick Scottimport android.widget.AdapterView.OnItemClickListener;
41bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scottimport android.widget.CheckBox;
425fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.widget.CursorAdapter;
435fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.widget.ListView;
445fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Projectimport android.widget.TextView;
455fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
46eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischerimport java.text.DateFormatSymbols;
47bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scottimport java.util.Calendar;
485fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
495fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project/**
505fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project * AlarmClock application.
515fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project */
520dffdefe54299ee01b45574244c92d3a06507b87Patrick Scottpublic class AlarmClock extends Activity implements OnItemClickListener {
535fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
54bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott    static final String PREFERENCES = "AlarmClock";
55bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott    static final String PREF_CLOCK_FACE = "face";
56bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott    static final String PREF_SHOW_CLOCK = "show_clock";
575fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
585fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    /** Cap alarm count at this number */
59bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott    static final int MAX_ALARM_COUNT = 12;
605fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
615fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    /** This must be false for production.  If true, turns on logging,
625fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        test code, etc. */
63bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott    static final boolean DEBUG = false;
645fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
655fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private SharedPreferences mPrefs;
665fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private LayoutInflater mFactory;
675fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private ViewGroup mClockLayout;
685fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private View mClock = null;
695fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private ListView mAlarmsList;
705fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private Cursor mCursor;
715fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
72eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer    private String mAm, mPm;
73eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer
745fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    /**
755fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project     * Which clock face to show
765fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project     */
775fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private int mFace = -1;
785fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
795fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    /*
80bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott     * TODO: it would be nice for this to live in an xml config file.
815fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project     */
82bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott    static final int[] CLOCKS = {
835fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        R.layout.clock_basic_bw,
845fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        R.layout.clock_googly,
855fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        R.layout.clock_droid2,
865fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        R.layout.clock_droids,
875fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        R.layout.digital_clock
885fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    };
895fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
905fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private class AlarmTimeAdapter extends CursorAdapter {
915fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        public AlarmTimeAdapter(Context context, Cursor cursor) {
925fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            super(context, cursor);
935fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        }
945fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
955fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        public View newView(Context context, Cursor cursor, ViewGroup parent) {
965fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            View ret = mFactory.inflate(R.layout.alarm_time, parent, false);
97eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer
98eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer            ((TextView) ret.findViewById(R.id.am)).setText(mAm);
99eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer            ((TextView) ret.findViewById(R.id.pm)).setText(mPm);
100eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer
101bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott            DigitalClock digitalClock =
102bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott                    (DigitalClock) ret.findViewById(R.id.digitalClock);
1035fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            digitalClock.setLive(false);
1045fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            return ret;
1055fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        }
1065fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
1075fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        public void bindView(View view, Context context, Cursor cursor) {
108d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott            final Alarm alarm = new Alarm(cursor);
1095fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
110bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott            CheckBox onButton = (CheckBox) view.findViewById(R.id.alarmButton);
111d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott            onButton.setChecked(alarm.enabled);
1125fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            onButton.setOnClickListener(new OnClickListener() {
1135fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                    public void onClick(View v) {
1145fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                        boolean isChecked = ((CheckBox) v).isChecked();
115d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                        Alarms.enableAlarm(AlarmClock.this, alarm.id,
116d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                            isChecked);
1175fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                        if (isChecked) {
118d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                            SetAlarm.popAlarmSetToast(AlarmClock.this,
119d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                                alarm.hour, alarm.minutes, alarm.daysOfWeek);
1205fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                        }
1215fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                    }
1225fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            });
1235fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
124d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott            DigitalClock digitalClock =
125d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                    (DigitalClock) view.findViewById(R.id.digitalClock);
1265fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
1275fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            // set the alarm text
1285fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            final Calendar c = Calendar.getInstance();
129d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott            c.set(Calendar.HOUR_OF_DAY, alarm.hour);
130d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott            c.set(Calendar.MINUTE, alarm.minutes);
1315fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            digitalClock.updateTime(c);
132185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project
133185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            // Set the repeat text or leave it blank if it does not repeat.
134d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott            TextView daysOfWeekView =
135d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                    (TextView) digitalClock.findViewById(R.id.daysOfWeek);
136185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            final String daysOfWeekStr =
137d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                    alarm.daysOfWeek.toString(AlarmClock.this, false);
138185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            if (daysOfWeekStr != null && daysOfWeekStr.length() != 0) {
139185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project                daysOfWeekView.setText(daysOfWeekStr);
140185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project                daysOfWeekView.setVisibility(View.VISIBLE);
141185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            } else {
142185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project                daysOfWeekView.setVisibility(View.GONE);
143185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            }
144185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project
145185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            // Display the label
146185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            TextView labelView =
147185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project                    (TextView) digitalClock.findViewById(R.id.label);
148d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott            if (alarm.label != null && alarm.label.length() != 0) {
149d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                labelView.setText(alarm.label);
1505d6f5fa51fa7fd13784a73199161deabec5bc898Patrick Scott                labelView.setVisibility(View.VISIBLE);
151185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            } else {
1525d6f5fa51fa7fd13784a73199161deabec5bc898Patrick Scott                labelView.setVisibility(View.GONE);
153185d17974729a98cf48a71ab9f16adaab9d1e1e0The Android Open Source Project            }
1545fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        }
1555fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    };
1565fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
1575fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    @Override
1585fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    public boolean onContextItemSelected(final MenuItem item) {
1590dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        final AdapterContextMenuInfo info =
1600dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                (AdapterContextMenuInfo) item.getMenuInfo();
1610dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        final int id = (int) info.id;
1620dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        switch (item.getItemId()) {
1630dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott            case R.id.delete_alarm:
1640dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                // Confirm that the alarm will be deleted.
1650dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                new AlertDialog.Builder(this)
1660dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                        .setTitle(getString(R.string.delete_alarm))
1670dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                        .setMessage(getString(R.string.delete_alarm_confirm))
1680dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                        .setPositiveButton(android.R.string.ok,
1690dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                                new DialogInterface.OnClickListener() {
1700dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                                    public void onClick(DialogInterface d,
1710dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                                            int w) {
1720dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                                        Alarms.deleteAlarm(AlarmClock.this, id);
1730dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                                    }
1740dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                                })
1750dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                        .setNegativeButton(android.R.string.cancel, null)
1760dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                        .show();
1770dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                return true;
1780dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
1790dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott            case R.id.enable_alarm:
1800dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                final Cursor c = (Cursor) mAlarmsList.getAdapter()
1810dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                        .getItem(info.position);
182d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                final Alarm alarm = new Alarm(c);
183d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                Alarms.enableAlarm(this, alarm.id, !alarm.enabled);
184d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                if (!alarm.enabled) {
185d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                    SetAlarm.popAlarmSetToast(this, alarm.hour, alarm.minutes,
186d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                            alarm.daysOfWeek);
1870dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                }
1880dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                return true;
1890dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
1900dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott            default:
1910dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                break;
1920dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        }
1930dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        return super.onContextItemSelected(item);
1945fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
1955fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
1965fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    @Override
1975fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    protected void onCreate(Bundle icicle) {
1985fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        super.onCreate(icicle);
1995fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
200eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer        String[] ampm = new DateFormatSymbols().getAmPmStrings();
201eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer        mAm = ampm[0];
202eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer        mPm = ampm[1];
203eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer
2045fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mFactory = LayoutInflater.from(this);
2055fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mPrefs = getSharedPreferences(PREFERENCES, 0);
2065fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mCursor = Alarms.getAlarmsCursor(getContentResolver());
207cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott
208cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott        updateLayout();
209cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott        setClockVisibility(mPrefs.getBoolean(PREF_SHOW_CLOCK, true));
210cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott    }
211cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott
212bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott    private final Handler mHandler = new Handler();
213bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott
214cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott    @Override
215cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott    public void onConfigurationChanged(Configuration newConfig) {
216cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott        super.onConfigurationChanged(newConfig);
217bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott        // Send a message to avoid a possible ANR.
218bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott        mHandler.post(new Runnable() {
219bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott            public void run() {
220bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott                updateLayout();
221bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott                inflateClock();
222203b5aa2c07516cc64d722072edfd9e093e4988aPatrick Scott                setClockVisibility(mPrefs.getBoolean(PREF_SHOW_CLOCK, true));
223bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott            }
224bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott        });
225cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott    }
226cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott
227cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott    private void updateLayout() {
228cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott        setContentView(R.layout.alarm_clock);
2295fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mAlarmsList = (ListView) findViewById(R.id.alarms_list);
2305fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mAlarmsList.setAdapter(new AlarmTimeAdapter(this, mCursor));
2315fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mAlarmsList.setVerticalScrollBarEnabled(true);
2320dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        mAlarmsList.setOnItemClickListener(this);
2330dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        mAlarmsList.setOnCreateContextMenuListener(this);
2345fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
2355fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mClockLayout = (ViewGroup) findViewById(R.id.clock_layout);
2365fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mClockLayout.setOnClickListener(new View.OnClickListener() {
2375fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                public void onClick(View v) {
238cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott                    final Intent intent =
239cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott                            new Intent(AlarmClock.this, ClockPicker.class);
2405fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2415fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                    startActivity(intent);
2425fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                }
2435fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            });
2445fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
2455fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
2465fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    @Override
2475fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    protected void onResume() {
2485fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        super.onResume();
2495fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
2505fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        int face = mPrefs.getInt(PREF_CLOCK_FACE, 0);
2515fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        if (mFace != face) {
252cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott            if (face < 0 || face >= AlarmClock.CLOCKS.length) {
2535fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                mFace = 0;
254cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott            } else {
2555fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project                mFace = face;
256cf7307401797b159ca32f85e7cf38d18cececd0dPatrick Scott            }
2575fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            inflateClock();
2585fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        }
2595fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
2605fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
2615fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    @Override
2625fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    protected void onDestroy() {
2635fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        super.onDestroy();
2645fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        ToastMaster.cancelToast();
2655fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mCursor.deactivate();
2665fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
2675fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
2685fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    protected void inflateClock() {
2695fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        if (mClock != null) {
2705fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project            mClockLayout.removeView(mClock);
2715fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        }
272eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer
273f47699dd4704917713004099b5e3609be48653c4Patrick Scott        LayoutInflater.from(this).inflate(CLOCKS[mFace], mClockLayout);
274f47699dd4704917713004099b5e3609be48653c4Patrick Scott        mClock = findViewById(R.id.clock);
275f47699dd4704917713004099b5e3609be48653c4Patrick Scott
276f47699dd4704917713004099b5e3609be48653c4Patrick Scott        TextView am = (TextView) findViewById(R.id.am);
277f47699dd4704917713004099b5e3609be48653c4Patrick Scott        TextView pm = (TextView) findViewById(R.id.pm);
278eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer
279eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer        if (am != null) {
280eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer            am.setText(mAm);
281eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer        }
282eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer        if (pm != null) {
283eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer            pm.setText(mPm);
284eb142ac59aa8039c409b5fe4f50a130f16960d41Eric Fischer        }
2855fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
2865fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
2875fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    @Override
2885fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    public boolean onCreateOptionsMenu(Menu menu) {
28906522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        // Inflate our menu.
29006522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        getMenuInflater().inflate(R.menu.main_menu, menu);
2915fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
29206522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        return super.onCreateOptionsMenu(menu);
2935fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
2945fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
2950dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott    @Override
2960dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott    public void onCreateContextMenu(ContextMenu menu, View view,
2970dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott            ContextMenuInfo menuInfo) {
2980dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        // Inflate the menu from xml.
2990dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        getMenuInflater().inflate(R.menu.context_menu, menu);
3000dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
3010dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        // Use the current item to create a custom view for the header.
3020dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
3030dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        final Cursor c =
3040dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott                (Cursor) mAlarmsList.getAdapter().getItem((int) info.position);
305d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott        final Alarm alarm = new Alarm(c);
3060dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
3070dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        // Construct the Calendar to compute the time.
3080dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        final Calendar cal = Calendar.getInstance();
309d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott        cal.set(Calendar.HOUR_OF_DAY, alarm.hour);
310d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott        cal.set(Calendar.MINUTE, alarm.minutes);
3110dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        final String time = Alarms.formatTime(this, cal);
3120dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
3130dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        // Inflate the custom view and set each TextView's text.
3140dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        final View v = mFactory.inflate(R.layout.context_menu_header, null);
3150dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        TextView textView = (TextView) v.findViewById(R.id.header_time);
3160dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        textView.setText(time);
3170dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        textView = (TextView) v.findViewById(R.id.header_label);
318d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott        textView.setText(alarm.label);
3190dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
3200dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        // Set the custom view on the menu.
3210dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        menu.setHeaderView(v);
3220dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        // Change the text to "disable" if the alarm is already enabled.
323d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott        if (alarm.enabled) {
3240dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott            menu.findItem(R.id.enable_alarm).setTitle(R.string.disable_alarm);
3250dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        }
3260dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott    }
3270dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
3280dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott    public void onItemClick(AdapterView parent, View v, int pos, long id) {
3290dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        Intent intent = new Intent(this, SetAlarm.class);
330d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott        intent.putExtra(Alarms.ALARM_ID, (int) id);
3310dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott        startActivity(intent);
3320dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott    }
3330dffdefe54299ee01b45574244c92d3a06507b87Patrick Scott
3345fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    /**
3355fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project     * Only allow user to add a new alarm if there are fewer than
3365fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project     * MAX_ALARM_COUNT
3375fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project     */
3385fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    @Override
3395fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    public boolean onPrepareOptionsMenu(Menu menu) {
34006522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        menu.findItem(R.id.menu_add_alarm).setVisible(
34106522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                mAlarmsList.getAdapter().getCount() < MAX_ALARM_COUNT);
34206522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        menu.findItem(R.id.menu_toggle_clock).setTitle(
34306522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                getClockVisibility() ? R.string.hide_clock
34406522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                    : R.string.show_clock);
34506522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        return super.onPrepareOptionsMenu(menu);
3465fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
3475fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
3485fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    @Override
3495fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
35006522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        switch (item.getItemId()) {
35106522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott            case R.id.menu_add_alarm:
35206522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                Uri uri = Alarms.addAlarm(getContentResolver());
353bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott                // TODO: Create new alarm _after_ SetAlarm so the user has the
354bcfaaa6b567b95df64499c2a2e3c15780438a2dcPatrick Scott                // chance to cancel alarm creation.
35506522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                String segment = uri.getPathSegments().get(1);
35606522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                int newId = Integer.parseInt(segment);
35706522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                if (Log.LOGV) {
35806522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                    Log.v("In AlarmClock, new alarm id = " + newId);
35906522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                }
36006522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                Intent intent = new Intent(this, SetAlarm.class);
361d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott                intent.putExtra(Alarms.ALARM_ID, newId);
36206522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                startActivity(intent);
36306522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                return true;
36406522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott
36506522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott            case R.id.menu_toggle_clock:
36606522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                setClockVisibility(!getClockVisibility());
36706522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                saveClockVisibility();
36806522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                return true;
36906522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott
37006522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott            case R.id.menu_settings:
37106522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                startActivity(new Intent(this, SettingsActivity.class));
37206522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott                return true;
3735fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        }
3745fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
37506522bf515aa117255e1e1d7ad0d6ae56a55ebfcPatrick Scott        return super.onOptionsItemSelected(item);
3765fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
3775fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
3785fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
3795fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private boolean getClockVisibility() {
3805fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        return mClockLayout.getVisibility() == View.VISIBLE;
3815fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
3825fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
3835fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private void setClockVisibility(boolean visible) {
3845fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mClockLayout.setVisibility(visible ? View.VISIBLE : View.GONE);
3855fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
3865fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project
3875fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    private void saveClockVisibility() {
3885fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project        mPrefs.edit().putBoolean(PREF_SHOW_CLOCK, getClockVisibility()).commit();
3895fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project    }
3905fedae0fb8cc29db88719329d52bdd62aad14277The Android Open Source Project}
391