1d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott/* 28188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Copyright (C) 2013 The Android Open Source Project 3d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * 4d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * Licensed under the Apache License, Version 2.0 (the "License"); 5d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * you may not use this file except in compliance with the License. 6d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * You may obtain a copy of the License at 7d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * 8d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * http://www.apache.org/licenses/LICENSE-2.0 9d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * 10d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * Unless required by applicable law or agreed to in writing, software 11d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * distributed under the License is distributed on an "AS IS" BASIS, 12d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * See the License for the specific language governing permissions and 14d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott * limitations under the License. 15d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott */ 16d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 17b839a7d1f42a1f3d58887f5a3c7978791d508cdbPaul Sliwowskipackage com.android.deskclock.provider; 18d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 198188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.content.ContentResolver; 208188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.content.ContentUris; 218188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.content.ContentValues; 22d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scottimport android.content.Context; 238188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport android.content.CursorLoader; 24ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowskiimport android.content.Intent; 25d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scottimport android.database.Cursor; 26d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scottimport android.media.RingtoneManager; 27d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scottimport android.net.Uri; 28d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scottimport android.os.Parcel; 29d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scottimport android.os.Parcelable; 30d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 31e10d62be00a99c19f2a111801d7f80ecb7baf336Annie Chinimport com.android.deskclock.R; 326a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieuximport com.android.deskclock.data.DataModel; 336a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux 34d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scottimport java.util.Calendar; 358188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport java.util.LinkedList; 368188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskiimport java.util.List; 37d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 388188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowskipublic final class Alarm implements Parcelable, ClockContract.AlarmsColumns { 398188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski /** 408188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Alarms start with an invalid id when it hasn't been saved to the database. 418188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski */ 428188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public static final long INVALID_ID = -1; 43d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 448188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski /** 458188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * The default sort order for this table 468188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski */ 478188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski private static final String DEFAULT_SORT_ORDER = 48381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + HOUR + ", " + 49381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + MINUTES + " ASC" + ", " + 50381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + ClockContract.AlarmsColumns._ID + " DESC"; 518188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 528188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski private static final String[] QUERY_COLUMNS = { 538188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski _ID, 548188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski HOUR, 558188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski MINUTES, 568188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski DAYS_OF_WEEK, 578188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ENABLED, 588188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski VIBRATE, 59ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski LABEL, 60ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski RINGTONE, 612f2584bdcabbf2f114f48efcab7ceb0a34067761Annie Chin DELETE_AFTER_USE 628188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski }; 638188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 64381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin private static final String[] QUERY_ALARMS_WITH_INSTANCES_COLUMNS = { 65381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + _ID, 66381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + HOUR, 67381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + MINUTES, 68381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + DAYS_OF_WEEK, 69381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + ENABLED, 70381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + VIBRATE, 71381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + LABEL, 72381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + RINGTONE, 73381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.ALARMS_TABLE_NAME + "." + DELETE_AFTER_USE, 74381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." 75381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin + ClockContract.InstancesColumns.ALARM_STATE, 76381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns._ID, 77381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns.YEAR, 78381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns.MONTH, 79381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns.DAY, 80381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns.HOUR, 81381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns.MINUTES, 82381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns.LABEL, 83381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin ClockDatabaseHelper.INSTANCES_TABLE_NAME + "." + ClockContract.InstancesColumns.VIBRATE 84381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin }; 85381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin 868188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski /** 878188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * These save calls to cursor.getColumnIndexOrThrow() 888188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * THEY MUST BE KEPT IN SYNC WITH ABOVE QUERY COLUMNS 898188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski */ 908188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski private static final int ID_INDEX = 0; 918188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski private static final int HOUR_INDEX = 1; 928188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski private static final int MINUTES_INDEX = 2; 938188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski private static final int DAYS_OF_WEEK_INDEX = 3; 94ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski private static final int ENABLED_INDEX = 4; 95ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski private static final int VIBRATE_INDEX = 5; 96ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski private static final int LABEL_INDEX = 6; 97ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski private static final int RINGTONE_INDEX = 7; 98ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski private static final int DELETE_AFTER_USE_INDEX = 8; 99381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin private static final int INSTANCE_STATE_INDEX = 9; 100381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_ID_INDEX = 10; 101381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_YEAR_INDEX = 11; 102381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_MONTH_INDEX = 12; 103381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_DAY_INDEX = 13; 104381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_HOUR_INDEX = 14; 105381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_MINUTE_INDEX = 15; 106381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_LABEL_INDEX = 16; 107381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public static final int INSTANCE_VIBRATE_INDEX = 17; 1088188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1092f2584bdcabbf2f114f48efcab7ceb0a34067761Annie Chin private static final int COLUMN_COUNT = DELETE_AFTER_USE_INDEX + 1; 110381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin private static final int ALARM_JOIN_INSTANCE_COLUMN_COUNT = INSTANCE_VIBRATE_INDEX + 1; 1118188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1128188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public static ContentValues createContentValues(Alarm alarm) { 1138188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ContentValues values = new ContentValues(COLUMN_COUNT); 1148188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski if (alarm.id != INVALID_ID) { 1158188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski values.put(ClockContract.AlarmsColumns._ID, alarm.id); 1168188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 1178188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1188188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski values.put(ENABLED, alarm.enabled ? 1 : 0); 1198188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski values.put(HOUR, alarm.hour); 1208188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski values.put(MINUTES, alarm.minutes); 1218188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski values.put(DAYS_OF_WEEK, alarm.daysOfWeek.getBitSet()); 12220dccf1991285ab46670521cea5adbc795b5be5ePaul Sliwowski values.put(VIBRATE, alarm.vibrate ? 1 : 0); 123ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski values.put(LABEL, alarm.label); 1248188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski values.put(DELETE_AFTER_USE, alarm.deleteAfterUse); 125ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski if (alarm.alert == null) { 126ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski // We want to put null, so default alarm changes 127ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski values.putNull(RINGTONE); 128ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski } else { 129ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski values.put(RINGTONE, alarm.alert.toString()); 130ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski } 1318188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1328188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return values; 133d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } 134d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 135ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski public static Intent createIntent(Context context, Class<?> cls, long alarmId) { 136ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski return new Intent(context, cls).setData(getUri(alarmId)); 137ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski } 138ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski 139ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski public static Uri getUri(long alarmId) { 140ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski return ContentUris.withAppendedId(CONTENT_URI, alarmId); 141ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski } 142ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski 1438188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public static long getId(Uri contentUri) { 1448188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return ContentUris.parseId(contentUri); 145d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } 1469fc42f9af42b408e85655c55e6c7825bc1ce8665Paul Sliwowski 1478188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski /** 1488188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Get alarm cursor loader for all alarms. 1498188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * 1508188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * @param context to query the database. 1518188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * @return cursor loader with all the alarms. 1528188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski */ 1538188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public static CursorLoader getAlarmsCursorLoader(Context context) { 154381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin return new CursorLoader(context, ALARMS_WITH_INSTANCES_URI, 155381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin QUERY_ALARMS_WITH_INSTANCES_COLUMNS, null, null, DEFAULT_SORT_ORDER); 156d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } 1578188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1588188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski /** 1598188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Get alarm by id. 1608188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * 1619c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux * @param cr to perform the query on. 1628188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * @param alarmId for the desired alarm. 1638188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * @return alarm if found, null otherwise 1648188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski */ 1659c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux public static Alarm getAlarm(ContentResolver cr, long alarmId) { 1669c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux try (Cursor cursor = cr.query(getUri(alarmId), QUERY_COLUMNS, null, null, null)) { 1678188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski if (cursor.moveToFirst()) { 1689c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux return new Alarm(cursor); 1698188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 1708188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 1718188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1729c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux return null; 1738188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 1748188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1758188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski /** 1768188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * Get all alarms given conditions. 1778188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * 1789c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux * @param cr to perform the query on. 1798188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * @param selection A filter declaring which rows to return, formatted as an 1808188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * SQL WHERE clause (excluding the WHERE itself). Passing null will 1818188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * return all rows for the given URI. 1828188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * @param selectionArgs You may include ?s in selection, which will be 1838188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * replaced by the values from selectionArgs, in the order that they 1848188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * appear in the selection. The values will be bound as Strings. 1858188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski * @return list of alarms matching where clause or empty list if none found. 1868188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski */ 1879c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux public static List<Alarm> getAlarms(ContentResolver cr, String selection, 1889c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux String... selectionArgs) { 1899c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux final List<Alarm> result = new LinkedList<>(); 1909c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux try (Cursor cursor = cr.query(CONTENT_URI, QUERY_COLUMNS, selection, selectionArgs, null)) { 1919c1f508c1f68bbbcb8fc42f8fc7748d63833fe89James Lemieux if (cursor != null && cursor.moveToFirst()) { 1928188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski do { 1938188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski result.add(new Alarm(cursor)); 1948188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } while (cursor.moveToNext()); 1958188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 1968188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 1978188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 1988188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return result; 1998188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 2008188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 201e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin public static boolean isTomorrow(Alarm alarm, Calendar now) { 202e6f73547d9fed9f9e0a44e6baf2894d317e6ef78Daria Evdokimova final int alarmHour = alarm.hour; 203e6f73547d9fed9f9e0a44e6baf2894d317e6ef78Daria Evdokimova final int currHour = now.get(Calendar.HOUR_OF_DAY); 204e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin // If the alarm is not snoozed and the time is less than the current time, it must be 205e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin // firing tomorrow. 206e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin // If the alarm is snoozed, return "false" to indicate that this alarm is firing today. 207e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin // (The alarm must have already rung today in order to be snoozed, and this function is only 208e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin // called on non-repeating alarms.) 209e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin return alarm.instanceState != AlarmInstance.SNOOZE_STATE 210e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin && (alarmHour < currHour 211e28d63671ccf81607dc47fa87b7abcf66ef22b86Annie Chin || (alarmHour == currHour && alarm.minutes <= now.get(Calendar.MINUTE))); 212e6f73547d9fed9f9e0a44e6baf2894d317e6ef78Daria Evdokimova } 213e6f73547d9fed9f9e0a44e6baf2894d317e6ef78Daria Evdokimova 214ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski public static Alarm addAlarm(ContentResolver contentResolver, Alarm alarm) { 215ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski ContentValues values = createContentValues(alarm); 216ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski Uri uri = contentResolver.insert(CONTENT_URI, values); 217ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski alarm.id = getId(uri); 218ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski return alarm; 219ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski } 220ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski 221ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski public static boolean updateAlarm(ContentResolver contentResolver, Alarm alarm) { 2222f2584bdcabbf2f114f48efcab7ceb0a34067761Annie Chin if (alarm.id == Alarm.INVALID_ID) return false; 223ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski ContentValues values = createContentValues(alarm); 224ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski long rowsUpdated = contentResolver.update(getUri(alarm.id), values, null, null); 225ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski return rowsUpdated == 1; 226ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski } 227ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski 228ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski public static boolean deleteAlarm(ContentResolver contentResolver, long alarmId) { 229ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski if (alarmId == INVALID_ID) return false; 230ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski int deletedRows = contentResolver.delete(getUri(alarmId), "", null); 231ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski return deletedRows == 1; 232ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski } 233ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski 234ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski public static final Parcelable.Creator<Alarm> CREATOR = new Parcelable.Creator<Alarm>() { 2358188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public Alarm createFromParcel(Parcel p) { 2368188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return new Alarm(p); 2378188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 2388188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 2398188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public Alarm[] newArray(int size) { 2408188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return new Alarm[size]; 2418188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 2428188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski }; 243d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 244d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott // Public fields 245ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski // TODO: Refactor instance names 2468188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public long id; 2478188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public boolean enabled; 2488188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public int hour; 2498188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public int minutes; 250d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott public DaysOfWeek daysOfWeek; 2518188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public boolean vibrate; 2528188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public String label; 2538188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public Uri alert; 2548188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public boolean deleteAfterUse; 255381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public int instanceState; 256381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin public int instanceId; 257d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 2588188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski // Creates a default alarm at the current time. 2598188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public Alarm() { 2608188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this(0, 0); 2618188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 2628188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 2638188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public Alarm(int hour, int minutes) { 2648188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this.id = INVALID_ID; 2658188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this.hour = hour; 2668188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this.minutes = minutes; 2678188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this.vibrate = true; 2688188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this.daysOfWeek = new DaysOfWeek(0); 2698188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this.label = ""; 2706a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux this.alert = DataModel.getDataModel().getDefaultAlarmRingtoneUri(); 2718188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski this.deleteAfterUse = false; 272dfbd6b43fc22d82b5ba576cb686496bfd8ddc016Chiao Cheng } 273dfbd6b43fc22d82b5ba576cb686496bfd8ddc016Chiao Cheng 274d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott public Alarm(Cursor c) { 2758188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski id = c.getLong(ID_INDEX); 2768188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski enabled = c.getInt(ENABLED_INDEX) == 1; 2778188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski hour = c.getInt(HOUR_INDEX); 2788188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski minutes = c.getInt(MINUTES_INDEX); 2798188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski daysOfWeek = new DaysOfWeek(c.getInt(DAYS_OF_WEEK_INDEX)); 2808188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski vibrate = c.getInt(VIBRATE_INDEX) == 1; 281ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski label = c.getString(LABEL_INDEX); 2828188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski deleteAfterUse = c.getInt(DELETE_AFTER_USE_INDEX) == 1; 2838188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski 284381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin if (c.getColumnCount() == ALARM_JOIN_INSTANCE_COLUMN_COUNT) { 285381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin instanceState = c.getInt(INSTANCE_STATE_INDEX); 286381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin instanceId = c.getInt(INSTANCE_ID_INDEX); 287381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin } 288381f4f17c8b2d4f0aac35eca56a315d129c5fb1eAnnie Chin 289ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski if (c.isNull(RINGTONE_INDEX)) { 290ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski // Should we be saving this with the current ringtone or leave it null 291ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski // so it changes when user changes default ringtone? 292ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM); 293d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } else { 294ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski alert = Uri.parse(c.getString(RINGTONE_INDEX)); 295d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } 296d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } 297d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 2988188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski Alarm(Parcel p) { 2998188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski id = p.readLong(); 300d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott enabled = p.readInt() == 1; 301d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott hour = p.readInt(); 302d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott minutes = p.readInt(); 303d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott daysOfWeek = new DaysOfWeek(p.readInt()); 304d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott vibrate = p.readInt() == 1; 305d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott label = p.readString(); 3066a59a7b2c034557bc8bc7481544db5cd1105a891James Lemieux alert = p.readParcelable(null); 3078188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski deleteAfterUse = p.readInt() == 1; 3089fc42f9af42b408e85655c55e6c7825bc1ce8665Paul Sliwowski } 3099fc42f9af42b408e85655c55e6c7825bc1ce8665Paul Sliwowski 310e10d62be00a99c19f2a111801d7f80ecb7baf336Annie Chin public String getLabelOrDefault(Context context) { 311e10d62be00a99c19f2a111801d7f80ecb7baf336Annie Chin return label.isEmpty() ? context.getString(R.string.default_label) : label; 312e10d62be00a99c19f2a111801d7f80ecb7baf336Annie Chin } 313e10d62be00a99c19f2a111801d7f80ecb7baf336Annie Chin 314effc01ce01f15cae466235d3a736389c84c7ebefFan Zhang /** 315effc01ce01f15cae466235d3a736389c84c7ebefFan Zhang * Whether the alarm is in a state to show preemptive dismiss. Valid states are SNOOZE_STATE 3164c9234c459245f39a6d991a030027c383dfbf560Annie Chin * HIGH_NOTIFICATION, LOW_NOTIFICATION, and HIDE_NOTIFICATION. 317effc01ce01f15cae466235d3a736389c84c7ebefFan Zhang */ 318effc01ce01f15cae466235d3a736389c84c7ebefFan Zhang public boolean canPreemptivelyDismiss() { 319effc01ce01f15cae466235d3a736389c84c7ebefFan Zhang return instanceState == AlarmInstance.SNOOZE_STATE 320effc01ce01f15cae466235d3a736389c84c7ebefFan Zhang || instanceState == AlarmInstance.HIGH_NOTIFICATION_STATE 3214c9234c459245f39a6d991a030027c383dfbf560Annie Chin || instanceState == AlarmInstance.LOW_NOTIFICATION_STATE 3224c9234c459245f39a6d991a030027c383dfbf560Annie Chin || instanceState == AlarmInstance.HIDE_NOTIFICATION_STATE; 323d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } 324d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott 3258188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public void writeToParcel(Parcel p, int flags) { 3268188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeLong(id); 3278188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeInt(enabled ? 1 : 0); 3288188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeInt(hour); 3298188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeInt(minutes); 3308188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeInt(daysOfWeek.getBitSet()); 3318188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeInt(vibrate ? 1 : 0); 3328188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeString(label); 3338188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeParcelable(alert, flags); 3348188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski p.writeInt(deleteAfterUse ? 1 : 0); 3358304c6e63ee1ff86208bac6f79285905027e95e8Paul Westbrook } 3368304c6e63ee1ff86208bac6f79285905027e95e8Paul Westbrook 3378188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public int describeContents() { 3388188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return 0; 3398304c6e63ee1ff86208bac6f79285905027e95e8Paul Westbrook } 3408304c6e63ee1ff86208bac6f79285905027e95e8Paul Westbrook 341ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski public AlarmInstance createInstanceAfter(Calendar time) { 342c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin Calendar nextInstanceTime = getNextAlarmTime(time); 343c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin AlarmInstance result = new AlarmInstance(nextInstanceTime, id); 344c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin result.mVibrate = vibrate; 345c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin result.mLabel = label; 346c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin result.mRingtone = alert; 347c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin return result; 348c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin } 349c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin 350d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin /** 351d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin * 352d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin * @param currentTime 353d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin * @return Previous firing time, or null if this is a one-time alarm. 354d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin */ 355d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin public Calendar getPreviousAlarmTime(Calendar currentTime) { 356d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin Calendar previousInstanceTime = Calendar.getInstance(); 357d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.set(Calendar.YEAR, currentTime.get(Calendar.YEAR)); 358d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.set(Calendar.MONTH, currentTime.get(Calendar.MONTH)); 359d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.set(Calendar.DAY_OF_MONTH, currentTime.get(Calendar.DAY_OF_MONTH)); 360d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.set(Calendar.HOUR_OF_DAY, hour); 361d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.set(Calendar.MINUTE, minutes); 362d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.set(Calendar.SECOND, 0); 363d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.set(Calendar.MILLISECOND, 0); 364d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin 365d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin int subtractDays = daysOfWeek.calculateDaysToPreviousAlarm(previousInstanceTime); 366d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin if (subtractDays > 0) { 367d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin previousInstanceTime.add(Calendar.DAY_OF_WEEK, -subtractDays); 368d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin return previousInstanceTime; 369d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin } else { 370d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin return null; 371d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin } 372d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin } 373d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin 374c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin public Calendar getNextAlarmTime(Calendar currentTime) { 375d68d58de285756f5094a33b12385f4989c76d9c4Annie Chin final Calendar nextInstanceTime = Calendar.getInstance(); 376c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin nextInstanceTime.set(Calendar.YEAR, currentTime.get(Calendar.YEAR)); 377c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin nextInstanceTime.set(Calendar.MONTH, currentTime.get(Calendar.MONTH)); 378c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin nextInstanceTime.set(Calendar.DAY_OF_MONTH, currentTime.get(Calendar.DAY_OF_MONTH)); 379ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski nextInstanceTime.set(Calendar.HOUR_OF_DAY, hour); 380ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski nextInstanceTime.set(Calendar.MINUTE, minutes); 381ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski nextInstanceTime.set(Calendar.SECOND, 0); 382ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski nextInstanceTime.set(Calendar.MILLISECOND, 0); 383ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski 384c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin // If we are still behind the passed in currentTime, then add a day 385c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin if (nextInstanceTime.getTimeInMillis() <= currentTime.getTimeInMillis()) { 386ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski nextInstanceTime.add(Calendar.DAY_OF_YEAR, 1); 38795b88d9453d7d47026b4a2e3bcc4e7bbb4dd7ccfPaul Sliwowski } 38895b88d9453d7d47026b4a2e3bcc4e7bbb4dd7ccfPaul Sliwowski 389ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski // The day of the week might be invalid, so find next valid one 390ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski int addDays = daysOfWeek.calculateDaysToNextAlarm(nextInstanceTime); 39195b88d9453d7d47026b4a2e3bcc4e7bbb4dd7ccfPaul Sliwowski if (addDays > 0) { 392ab0d28c68a77bea2a4a2ee50378da3670a1dd939Paul Sliwowski nextInstanceTime.add(Calendar.DAY_OF_WEEK, addDays); 39395b88d9453d7d47026b4a2e3bcc4e7bbb4dd7ccfPaul Sliwowski } 3949699c4ab5817c103f804633ebef2d3c0d5db1f9cJames Lemieux 3959699c4ab5817c103f804633ebef2d3c0d5db1f9cJames Lemieux // Daylight Savings Time can alter the hours and minutes when adjusting the day above. 3969699c4ab5817c103f804633ebef2d3c0d5db1f9cJames Lemieux // Reset the desired hour and minute now that the correct day has been chosen. 3979699c4ab5817c103f804633ebef2d3c0d5db1f9cJames Lemieux nextInstanceTime.set(Calendar.HOUR_OF_DAY, hour); 3989699c4ab5817c103f804633ebef2d3c0d5db1f9cJames Lemieux nextInstanceTime.set(Calendar.MINUTE, minutes); 3999699c4ab5817c103f804633ebef2d3c0d5db1f9cJames Lemieux 400c34e4a02bf9a8ef294891281fd46dcf8f6dd8d85Annie Chin return nextInstanceTime; 40195b88d9453d7d47026b4a2e3bcc4e7bbb4dd7ccfPaul Sliwowski } 40295b88d9453d7d47026b4a2e3bcc4e7bbb4dd7ccfPaul Sliwowski 4038188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski @Override 4048188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public boolean equals(Object o) { 4058188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski if (!(o instanceof Alarm)) return false; 4068188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski final Alarm other = (Alarm) o; 4078188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return id == other.id; 4088188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 409dfbd6b43fc22d82b5ba576cb686496bfd8ddc016Chiao Cheng 4108188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski @Override 4118188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public int hashCode() { 4128188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return Long.valueOf(id).hashCode(); 4138188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski } 41495b88d9453d7d47026b4a2e3bcc4e7bbb4dd7ccfPaul Sliwowski 4158188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski @Override 4168188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski public String toString() { 4178188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski return "Alarm{" + 4188188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski "alert=" + alert + 4198188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", id=" + id + 4208188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", enabled=" + enabled + 4218188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", hour=" + hour + 4228188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", minutes=" + minutes + 4238188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", daysOfWeek=" + daysOfWeek + 4248188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", vibrate=" + vibrate + 4258188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", label='" + label + '\'' + 4268188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski ", deleteAfterUse=" + deleteAfterUse + 4278188813bc869d3df4885f9c2972f9cc85745b59bPaul Sliwowski '}'; 428d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott } 429d776e51cec79901a0d656bba7b1f3780cceac57dPatrick Scott} 430