Alarm.java revision 1c604c48ef4dd01e789e1fffb0dec8f815e0cd30
14bbc2931263b232fba61807fca00e127573eff42Doris Liu/*
24bbc2931263b232fba61807fca00e127573eff42Doris Liu * Copyright (C) 2013 The Android Open Source Project
34bbc2931263b232fba61807fca00e127573eff42Doris Liu *
44bbc2931263b232fba61807fca00e127573eff42Doris Liu * Licensed under the Apache License, Version 2.0 (the "License");
54bbc2931263b232fba61807fca00e127573eff42Doris Liu * you may not use this file except in compliance with the License.
64bbc2931263b232fba61807fca00e127573eff42Doris Liu * You may obtain a copy of the License at
74bbc2931263b232fba61807fca00e127573eff42Doris Liu *
84bbc2931263b232fba61807fca00e127573eff42Doris Liu *      http://www.apache.org/licenses/LICENSE-2.0
94bbc2931263b232fba61807fca00e127573eff42Doris Liu *
104bbc2931263b232fba61807fca00e127573eff42Doris Liu * Unless required by applicable law or agreed to in writing, software
114bbc2931263b232fba61807fca00e127573eff42Doris Liu * distributed under the License is distributed on an "AS IS" BASIS,
124bbc2931263b232fba61807fca00e127573eff42Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134bbc2931263b232fba61807fca00e127573eff42Doris Liu * See the License for the specific language governing permissions and
144bbc2931263b232fba61807fca00e127573eff42Doris Liu * limitations under the License.
154bbc2931263b232fba61807fca00e127573eff42Doris Liu */
164bbc2931263b232fba61807fca00e127573eff42Doris Liu
174bbc2931263b232fba61807fca00e127573eff42Doris Liupackage com.android.deskclock.provider;
181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
194bbc2931263b232fba61807fca00e127573eff42Doris Liuimport android.content.ContentResolver;
204bbc2931263b232fba61807fca00e127573eff42Doris Liuimport android.content.ContentUris;
211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liuimport android.content.ContentValues;
224bbc2931263b232fba61807fca00e127573eff42Doris Liuimport android.content.Context;
234bbc2931263b232fba61807fca00e127573eff42Doris Liuimport android.content.CursorLoader;
24dccca44ffda4836b56a21da95a046c9708ffd49csergeyvimport android.database.Cursor;
25dccca44ffda4836b56a21da95a046c9708ffd49csergeyvimport android.media.RingtoneManager;
264bbc2931263b232fba61807fca00e127573eff42Doris Liuimport android.net.Uri;
274bbc2931263b232fba61807fca00e127573eff42Doris Liuimport android.os.Parcel;
284bbc2931263b232fba61807fca00e127573eff42Doris Liuimport android.os.Parcelable;
294bbc2931263b232fba61807fca00e127573eff42Doris Liu
301d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liuimport com.android.deskclock.Log;
311d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liuimport com.android.deskclock.R;
321d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
334bbc2931263b232fba61807fca00e127573eff42Doris Liuimport java.util.Calendar;
344bbc2931263b232fba61807fca00e127573eff42Doris Liuimport java.util.LinkedList;
354bbc2931263b232fba61807fca00e127573eff42Doris Liuimport java.util.List;
364bbc2931263b232fba61807fca00e127573eff42Doris Liu
374bbc2931263b232fba61807fca00e127573eff42Doris Liupublic final class Alarm implements Parcelable, ClockContract.AlarmsColumns {
384bbc2931263b232fba61807fca00e127573eff42Doris Liu    /**
39335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu     * Alarms start with an invalid id when it hasn't been saved to the database.
40335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu     */
41335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu    public static final long INVALID_ID = -1;
42335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu
43335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu    /**
44335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu     * This string is used to indicate a silent alarm in the db.
45335d7d174464ea3fc2d058dcff6e436df1cf0fd9Doris Liu     */
461d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public static final String ALARM_ALERT_SILENT = "silent";
471d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
481d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    /**
494bbc2931263b232fba61807fca00e127573eff42Doris Liu     * The default sort order for this table
504bbc2931263b232fba61807fca00e127573eff42Doris Liu     */
511d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final String DEFAULT_SORT_ORDER =
521d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            HOUR + ", " +
531d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            MINUTES + " ASC" + ", " +
541d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            _ID + " DESC";
551d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
564bbc2931263b232fba61807fca00e127573eff42Doris Liu    private static final String[] QUERY_COLUMNS = {
574bbc2931263b232fba61807fca00e127573eff42Doris Liu            _ID,
581d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            HOUR,
591d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            MINUTES,
601d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            DAYS_OF_WEEK,
611d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            ALARM_TIME,
621d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            ENABLED,
631d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            VIBRATE,
641d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            MESSAGE,
651d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            ALERT,
661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            DELETE_AFTER_USE
671d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    };
681d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    /**
701d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * These save calls to cursor.getColumnIndexOrThrow()
711d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * THEY MUST BE KEPT IN SYNC WITH ABOVE QUERY COLUMNS
721d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     */
731d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int ID_INDEX = 0;
741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int HOUR_INDEX = 1;
751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int MINUTES_INDEX = 2;
761d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int DAYS_OF_WEEK_INDEX = 3;
771d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    @Deprecated //ALARM_TIME is not used anymore
781d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int ALARM_TIME_INDEX = 4;
791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int ENABLED_INDEX = 5;
801d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int VIBRATE_INDEX = 6;
811d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int MESSAGE_INDEX = 7;
821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int ALERT_INDEX = 8;
831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int DELETE_AFTER_USE_INDEX = 9;
841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
851d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    private static final int COLUMN_COUNT = DELETE_AFTER_USE_INDEX + 1;
861d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
871d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public static ContentValues createContentValues(Alarm alarm) {
881d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        ContentValues values = new ContentValues(COLUMN_COUNT);
891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        if (alarm.id != INVALID_ID) {
901d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            values.put(ClockContract.AlarmsColumns._ID, alarm.id);
911d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        }
924bbc2931263b232fba61807fca00e127573eff42Doris Liu
934bbc2931263b232fba61807fca00e127573eff42Doris Liu        values.put(ENABLED, alarm.enabled ? 1 : 0);
944bbc2931263b232fba61807fca00e127573eff42Doris Liu        values.put(HOUR, alarm.hour);
954bbc2931263b232fba61807fca00e127573eff42Doris Liu        values.put(MINUTES, alarm.minutes);
964bbc2931263b232fba61807fca00e127573eff42Doris Liu        values.put(ALARM_TIME, 0);
974bbc2931263b232fba61807fca00e127573eff42Doris Liu        values.put(DAYS_OF_WEEK, alarm.daysOfWeek.getBitSet());
984bbc2931263b232fba61807fca00e127573eff42Doris Liu        values.put(VIBRATE, alarm.vibrate);
991d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        values.put(MESSAGE, alarm.label);
1001d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        values.put(DELETE_AFTER_USE, alarm.deleteAfterUse);
1011d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
102f8d131cc8dc4ef675b8f8fc57dcc26062d575d32Doris Liu        // A null alert Uri indicates a silent alarm.
1034bbc2931263b232fba61807fca00e127573eff42Doris Liu        values.put(ALERT, alarm.alert == null ? ALARM_ALERT_SILENT : alarm.alert.toString());
1044bbc2931263b232fba61807fca00e127573eff42Doris Liu
1054bbc2931263b232fba61807fca00e127573eff42Doris Liu        return values;
1064bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
1074bbc2931263b232fba61807fca00e127573eff42Doris Liu
1084bbc2931263b232fba61807fca00e127573eff42Doris Liu    public static long getId(Uri contentUri) {
109f8d131cc8dc4ef675b8f8fc57dcc26062d575d32Doris Liu        return ContentUris.parseId(contentUri);
1104bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
1114bbc2931263b232fba61807fca00e127573eff42Doris Liu
1121d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    /**
1131d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * Get alarm cursor loader for all alarms.
1141d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     *
1151d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * @param context to query the database.
1161d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * @return cursor loader with all the alarms.
1171d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     */
1181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public static CursorLoader getAlarmsCursorLoader(Context context) {
1194bbc2931263b232fba61807fca00e127573eff42Doris Liu        return new CursorLoader(context, ClockContract.AlarmsColumns.CONTENT_URI,
1204bbc2931263b232fba61807fca00e127573eff42Doris Liu                QUERY_COLUMNS, null, null, DEFAULT_SORT_ORDER);
1211d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    }
1221d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
1231d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    /**
1241d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * Get alarm by id.
1251d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     *
1261d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * @param contentResolver to perform the query on.
1271d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * @param alarmId for the desired alarm.
1281d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * @return alarm if found, null otherwise
1294bbc2931263b232fba61807fca00e127573eff42Doris Liu     */
1304bbc2931263b232fba61807fca00e127573eff42Doris Liu    public static Alarm getAlarm(ContentResolver contentResolver, long alarmId) {
1314bbc2931263b232fba61807fca00e127573eff42Doris Liu        Cursor cursor = contentResolver.query(ContentUris.withAppendedId(CONTENT_URI, alarmId),
1324bbc2931263b232fba61807fca00e127573eff42Doris Liu                QUERY_COLUMNS, null, null, null);
1334bbc2931263b232fba61807fca00e127573eff42Doris Liu        Alarm result = null;
13446591f4a2dbd785bcae2b82bb490e78208605ec8Teng-Hui Zhu        if (cursor == null) {
1354bbc2931263b232fba61807fca00e127573eff42Doris Liu            return result;
1361d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        }
1371d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
1381d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        try {
1394bbc2931263b232fba61807fca00e127573eff42Doris Liu            if (cursor.moveToFirst()) {
1404bbc2931263b232fba61807fca00e127573eff42Doris Liu                result = new Alarm(cursor);
141dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            }
142dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        } finally {
143dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu            cursor.close();
1441d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        }
145dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
146dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu        return result;
147dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    }
148dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu
149dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu    /**
1501d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     * Get all alarms given conditions.
151dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     *
152dbee9bb342cdfaa5155b1918f90262c05e2464cbTeng-Hui Zhu     * @param contentResolver to perform the query on.
1534bbc2931263b232fba61807fca00e127573eff42Doris Liu     * @param selection A filter declaring which rows to return, formatted as an
1544bbc2931263b232fba61807fca00e127573eff42Doris Liu     *         SQL WHERE clause (excluding the WHERE itself). Passing null will
1554bbc2931263b232fba61807fca00e127573eff42Doris Liu     *         return all rows for the given URI.
1564bbc2931263b232fba61807fca00e127573eff42Doris Liu     * @param selectionArgs You may include ?s in selection, which will be
1571d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu     *         replaced by the values from selectionArgs, in the order that they
1584bbc2931263b232fba61807fca00e127573eff42Doris Liu     *         appear in the selection. The values will be bound as Strings.
1594bbc2931263b232fba61807fca00e127573eff42Doris Liu     * @return list of alarms matching where clause or empty list if none found.
1604bbc2931263b232fba61807fca00e127573eff42Doris Liu     */
1614bbc2931263b232fba61807fca00e127573eff42Doris Liu    public static List<Alarm> getAlarms(ContentResolver contentResolver,
1624bbc2931263b232fba61807fca00e127573eff42Doris Liu            String selection, String ... selectionArgs) {
1634bbc2931263b232fba61807fca00e127573eff42Doris Liu        Cursor cursor  = contentResolver.query(CONTENT_URI, QUERY_COLUMNS,
1644bbc2931263b232fba61807fca00e127573eff42Doris Liu                selection, selectionArgs, null);
1654bbc2931263b232fba61807fca00e127573eff42Doris Liu        List<Alarm> result = new LinkedList<Alarm>();
1661d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        if (cursor == null) {
1674bbc2931263b232fba61807fca00e127573eff42Doris Liu            return result;
1684bbc2931263b232fba61807fca00e127573eff42Doris Liu        }
1694bbc2931263b232fba61807fca00e127573eff42Doris Liu
1704bbc2931263b232fba61807fca00e127573eff42Doris Liu        try {
1714bbc2931263b232fba61807fca00e127573eff42Doris Liu            if (cursor.moveToFirst()) {
1724bbc2931263b232fba61807fca00e127573eff42Doris Liu                do {
1734bbc2931263b232fba61807fca00e127573eff42Doris Liu                    result.add(new Alarm(cursor));
1741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu                } while (cursor.moveToNext());
1751d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            }
1764bbc2931263b232fba61807fca00e127573eff42Doris Liu        } finally {
1774bbc2931263b232fba61807fca00e127573eff42Doris Liu            cursor.close();
1784bbc2931263b232fba61807fca00e127573eff42Doris Liu        }
1794bbc2931263b232fba61807fca00e127573eff42Doris Liu
1804bbc2931263b232fba61807fca00e127573eff42Doris Liu        return result;
1814bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
1821d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
1831d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public static final Parcelable.Creator<Alarm> CREATOR
1841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            = new Parcelable.Creator<Alarm>() {
185b35da390601e3c24e777d72daacd8dbeb4d1d9c4Doris Liu        public Alarm createFromParcel(Parcel p) {
1860a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liu            return new Alarm(p);
1870a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liu        }
1880a1a5167be26d363d4e27bdc7b816f425b7b4e66Doris Liu
1891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        public Alarm[] newArray(int size) {
1904bbc2931263b232fba61807fca00e127573eff42Doris Liu            return new Alarm[size];
1914bbc2931263b232fba61807fca00e127573eff42Doris Liu        }
1924bbc2931263b232fba61807fca00e127573eff42Doris Liu    };
1931d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
1941d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    // Public fields
1951d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public long id;
1964bbc2931263b232fba61807fca00e127573eff42Doris Liu    public boolean enabled;
1974bbc2931263b232fba61807fca00e127573eff42Doris Liu    public int hour;
1981d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public int minutes;
1994bbc2931263b232fba61807fca00e127573eff42Doris Liu    public DaysOfWeek daysOfWeek;
2004bbc2931263b232fba61807fca00e127573eff42Doris Liu    public boolean vibrate;
2014bbc2931263b232fba61807fca00e127573eff42Doris Liu    public String label;
2024bbc2931263b232fba61807fca00e127573eff42Doris Liu    public Uri alert;
2031d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public boolean silent;
2044bbc2931263b232fba61807fca00e127573eff42Doris Liu    public boolean deleteAfterUse;
2054bbc2931263b232fba61807fca00e127573eff42Doris Liu
2064bbc2931263b232fba61807fca00e127573eff42Doris Liu    // Creates a default alarm at the current time.
2074bbc2931263b232fba61807fca00e127573eff42Doris Liu    public Alarm() {
2081d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        this(0, 0);
2094bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
2104bbc2931263b232fba61807fca00e127573eff42Doris Liu
2114bbc2931263b232fba61807fca00e127573eff42Doris Liu    public Alarm(int hour, int minutes) {
2124bbc2931263b232fba61807fca00e127573eff42Doris Liu        this.id = INVALID_ID;
2131d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        this.hour = hour;
2144bbc2931263b232fba61807fca00e127573eff42Doris Liu        this.minutes = minutes;
2154bbc2931263b232fba61807fca00e127573eff42Doris Liu        this.vibrate = true;
2164bbc2931263b232fba61807fca00e127573eff42Doris Liu        this.daysOfWeek = new DaysOfWeek(0);
2174bbc2931263b232fba61807fca00e127573eff42Doris Liu        this.label = "";
2181d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        this.alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
2194bbc2931263b232fba61807fca00e127573eff42Doris Liu        this.deleteAfterUse = false;
2204bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
2214bbc2931263b232fba61807fca00e127573eff42Doris Liu
2224bbc2931263b232fba61807fca00e127573eff42Doris Liu    public Alarm(Cursor c) {
2231d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        id = c.getLong(ID_INDEX);
2244bbc2931263b232fba61807fca00e127573eff42Doris Liu        enabled = c.getInt(ENABLED_INDEX) == 1;
2254bbc2931263b232fba61807fca00e127573eff42Doris Liu        hour = c.getInt(HOUR_INDEX);
2264bbc2931263b232fba61807fca00e127573eff42Doris Liu        minutes = c.getInt(MINUTES_INDEX);
2274bbc2931263b232fba61807fca00e127573eff42Doris Liu        daysOfWeek = new DaysOfWeek(c.getInt(DAYS_OF_WEEK_INDEX));
2281d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        vibrate = c.getInt(VIBRATE_INDEX) == 1;
2294bbc2931263b232fba61807fca00e127573eff42Doris Liu        label = c.getString(MESSAGE_INDEX);
2304bbc2931263b232fba61807fca00e127573eff42Doris Liu        deleteAfterUse = c.getInt(DELETE_AFTER_USE_INDEX) == 1;
2314bbc2931263b232fba61807fca00e127573eff42Doris Liu
2324bbc2931263b232fba61807fca00e127573eff42Doris Liu        setAlert(c.getString(ALERT_INDEX));
2331d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    }
2344bbc2931263b232fba61807fca00e127573eff42Doris Liu
2354bbc2931263b232fba61807fca00e127573eff42Doris Liu    public void setAlert(String alertString) {
2364bbc2931263b232fba61807fca00e127573eff42Doris Liu        if (ALARM_ALERT_SILENT.equals(alertString)) {
2374bbc2931263b232fba61807fca00e127573eff42Doris Liu            if (Log.LOGV) {
2381d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu                Log.v("Alarm is marked as silent");
2394bbc2931263b232fba61807fca00e127573eff42Doris Liu            }
2404bbc2931263b232fba61807fca00e127573eff42Doris Liu            silent = true;
2414bbc2931263b232fba61807fca00e127573eff42Doris Liu        } else {
2424bbc2931263b232fba61807fca00e127573eff42Doris Liu            if (alertString != null && alertString.length() != 0) {
2431d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu                alert = Uri.parse(alertString);
2444bbc2931263b232fba61807fca00e127573eff42Doris Liu            }
2454bbc2931263b232fba61807fca00e127573eff42Doris Liu
2464bbc2931263b232fba61807fca00e127573eff42Doris Liu            // If the database alert is null or it failed to parse, use the
2474bbc2931263b232fba61807fca00e127573eff42Doris Liu            // default alert.
2481d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu            if (alert == null) {
2494bbc2931263b232fba61807fca00e127573eff42Doris Liu                alert = RingtoneManager.getDefaultUri(
2504bbc2931263b232fba61807fca00e127573eff42Doris Liu                        RingtoneManager.TYPE_ALARM);
2514bbc2931263b232fba61807fca00e127573eff42Doris Liu            }
2524bbc2931263b232fba61807fca00e127573eff42Doris Liu        }
2531d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    }
2544bbc2931263b232fba61807fca00e127573eff42Doris Liu
2554bbc2931263b232fba61807fca00e127573eff42Doris Liu    Alarm(Parcel p) {
2564bbc2931263b232fba61807fca00e127573eff42Doris Liu        id = p.readLong();
2574bbc2931263b232fba61807fca00e127573eff42Doris Liu        enabled = p.readInt() == 1;
2581d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        hour = p.readInt();
2594bbc2931263b232fba61807fca00e127573eff42Doris Liu        minutes = p.readInt();
2604bbc2931263b232fba61807fca00e127573eff42Doris Liu        daysOfWeek = new DaysOfWeek(p.readInt());
2614bbc2931263b232fba61807fca00e127573eff42Doris Liu        vibrate = p.readInt() == 1;
2624bbc2931263b232fba61807fca00e127573eff42Doris Liu        label = p.readString();
2631d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        alert = (Uri) p.readParcelable(null);
2644bbc2931263b232fba61807fca00e127573eff42Doris Liu        silent = p.readInt() == 1;
2654bbc2931263b232fba61807fca00e127573eff42Doris Liu        deleteAfterUse = p.readInt() == 1;
2664bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
2674bbc2931263b232fba61807fca00e127573eff42Doris Liu
2684bbc2931263b232fba61807fca00e127573eff42Doris Liu    public String getLabelOrDefault(Context context) {
2691d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        if (label == null || label.length() == 0) {
2704bbc2931263b232fba61807fca00e127573eff42Doris Liu            return context.getString(R.string.default_label);
2714bbc2931263b232fba61807fca00e127573eff42Doris Liu        }
2724bbc2931263b232fba61807fca00e127573eff42Doris Liu        return label;
2734bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
2741d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
2754bbc2931263b232fba61807fca00e127573eff42Doris Liu    public void writeToParcel(Parcel p, int flags) {
2764bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeLong(id);
2774bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeInt(enabled ? 1 : 0);
2784bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeInt(hour);
2791d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        p.writeInt(minutes);
2804bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeInt(daysOfWeek.getBitSet());
2814bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeInt(vibrate ? 1 : 0);
2824bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeString(label);
2834bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeParcelable(alert, flags);
2841d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        p.writeInt(silent ? 1 : 0);
2854bbc2931263b232fba61807fca00e127573eff42Doris Liu        p.writeInt(deleteAfterUse ? 1 : 0);
2864bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
2874bbc2931263b232fba61807fca00e127573eff42Doris Liu
2884bbc2931263b232fba61807fca00e127573eff42Doris Liu    public int describeContents() {
2891d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        return 0;
2904bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
2914bbc2931263b232fba61807fca00e127573eff42Doris Liu
2924bbc2931263b232fba61807fca00e127573eff42Doris Liu    public long calculateAlarmTime() {
2934bbc2931263b232fba61807fca00e127573eff42Doris Liu        // start with now
2941d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        Calendar c = Calendar.getInstance();
2954bbc2931263b232fba61807fca00e127573eff42Doris Liu        c.setTimeInMillis(System.currentTimeMillis());
2964bbc2931263b232fba61807fca00e127573eff42Doris Liu
2974bbc2931263b232fba61807fca00e127573eff42Doris Liu        int nowHour = c.get(Calendar.HOUR_OF_DAY);
2984bbc2931263b232fba61807fca00e127573eff42Doris Liu        int nowMinute = c.get(Calendar.MINUTE);
2991d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu
3004bbc2931263b232fba61807fca00e127573eff42Doris Liu        // if alarm is behind current time, advance one day
3014bbc2931263b232fba61807fca00e127573eff42Doris Liu        if ((hour < nowHour  || (hour == nowHour && minutes <= nowMinute))) {
3024bbc2931263b232fba61807fca00e127573eff42Doris Liu            c.add(Calendar.DAY_OF_YEAR, 1);
3034bbc2931263b232fba61807fca00e127573eff42Doris Liu        }
3041d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        c.set(Calendar.HOUR_OF_DAY, hour);
3054bbc2931263b232fba61807fca00e127573eff42Doris Liu        c.set(Calendar.MINUTE, minutes);
3064bbc2931263b232fba61807fca00e127573eff42Doris Liu        c.set(Calendar.SECOND, 0);
3074bbc2931263b232fba61807fca00e127573eff42Doris Liu        c.set(Calendar.MILLISECOND, 0);
3084bbc2931263b232fba61807fca00e127573eff42Doris Liu
3091d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        int addDays = daysOfWeek.calculateDaysToNextAlarm(c);
3104bbc2931263b232fba61807fca00e127573eff42Doris Liu        if (addDays > 0) {
3114bbc2931263b232fba61807fca00e127573eff42Doris Liu            c.add(Calendar.DAY_OF_WEEK, addDays);
3124bbc2931263b232fba61807fca00e127573eff42Doris Liu        }
3134bbc2931263b232fba61807fca00e127573eff42Doris Liu        return c.getTimeInMillis();
3141d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    }
3154bbc2931263b232fba61807fca00e127573eff42Doris Liu
3164bbc2931263b232fba61807fca00e127573eff42Doris Liu    @Override
3174bbc2931263b232fba61807fca00e127573eff42Doris Liu    public boolean equals(Object o) {
3184bbc2931263b232fba61807fca00e127573eff42Doris Liu        if (!(o instanceof Alarm)) return false;
3191d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu        final Alarm other = (Alarm) o;
3204bbc2931263b232fba61807fca00e127573eff42Doris Liu        return id == other.id;
3214bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
3224bbc2931263b232fba61807fca00e127573eff42Doris Liu
3234bbc2931263b232fba61807fca00e127573eff42Doris Liu    @Override
3241d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public int hashCode() {
3254bbc2931263b232fba61807fca00e127573eff42Doris Liu        return Long.valueOf(id).hashCode();
3264bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
3274bbc2931263b232fba61807fca00e127573eff42Doris Liu
3284bbc2931263b232fba61807fca00e127573eff42Doris Liu    @Override
3291d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu    public String toString() {
3304bbc2931263b232fba61807fca00e127573eff42Doris Liu        return "Alarm{" +
3314bbc2931263b232fba61807fca00e127573eff42Doris Liu                "alert=" + alert +
3324bbc2931263b232fba61807fca00e127573eff42Doris Liu                ", id=" + id +
3334bbc2931263b232fba61807fca00e127573eff42Doris Liu                ", enabled=" + enabled +
3341d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu                ", hour=" + hour +
3354bbc2931263b232fba61807fca00e127573eff42Doris Liu                ", minutes=" + minutes +
3364bbc2931263b232fba61807fca00e127573eff42Doris Liu                ", daysOfWeek=" + daysOfWeek +
3374bbc2931263b232fba61807fca00e127573eff42Doris Liu                ", vibrate=" + vibrate +
3384bbc2931263b232fba61807fca00e127573eff42Doris Liu                ", label='" + label + '\'' +
3391d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu                ", silent=" + silent +
3404bbc2931263b232fba61807fca00e127573eff42Doris Liu                ", deleteAfterUse=" + deleteAfterUse +
3414bbc2931263b232fba61807fca00e127573eff42Doris Liu                '}';
3424bbc2931263b232fba61807fca00e127573eff42Doris Liu    }
3434bbc2931263b232fba61807fca00e127573eff42Doris Liu}
3441d8e194661085f9a18ab1b3cd12f9e19d3a86be5Doris Liu