1146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/* 2146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 4146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * you may not use this file except in compliance with the License. 6146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * You may obtain a copy of the License at 7146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 8146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * 10146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * See the License for the specific language governing permissions and 14146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * limitations under the License. 15146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 16146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 1723e7da3eacee7bceb105cdfc7b5329c7a43846d5Mason Tangpackage com.android.calendar.alerts; 18146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 1907d9fee87bc02849c0dd7b66326a320d53cf5479Michael Chanimport com.android.calendar.AllInOneActivity; 2023e7da3eacee7bceb105cdfc7b5329c7a43846d5Mason Tangimport com.android.calendar.AsyncQueryService; 2123e7da3eacee7bceb105cdfc7b5329c7a43846d5Mason Tangimport com.android.calendar.R; 2223e7da3eacee7bceb105cdfc7b5329c7a43846d5Mason Tangimport com.android.calendar.Utils; 23146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 24146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.app.Activity; 25146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.app.AlarmManager; 26146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.app.NotificationManager; 27fa292a0db2a6f04255c75a57908b17ba48a96183RoboErikimport android.app.PendingIntent; 28fa292a0db2a6f04255c75a57908b17ba48a96183RoboErikimport android.content.ContentUris; 295c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chanimport android.content.ContentValues; 30146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.content.Context; 31db4ce4a81063b7f5f6068f4144f8a3e3bca1e064Erikimport android.content.Intent; 32146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.database.Cursor; 33146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.net.Uri; 34db4ce4a81063b7f5f6068f4144f8a3e3bca1e064Erikimport android.net.Uri.Builder; 35146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.os.Bundle; 36a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract; 37a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErikimport android.provider.CalendarContract.CalendarAlerts; 381a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawaimport android.util.Log; 39146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.view.View; 401a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawaimport android.view.View.OnClickListener; 41146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.AdapterView; 421a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawaimport android.widget.AdapterView.OnItemClickListener; 43146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.Button; 44146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Projectimport android.widget.ListView; 45146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 46146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project/** 47146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * The alert panel that pops up when there is a calendar event alarm. 48146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project * This activity is started by an intent that specifies an event id. 49146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project */ 501a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawapublic class AlertActivity extends Activity implements OnClickListener { 511a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa private static final String TAG = "AlertActivity"; 525c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 53146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // The default snooze delay: 5 minutes 54146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final long SNOOZE_DELAY = 5 * 60 * 1000L; 555c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 565c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan private static final String[] PROJECTION = new String[] { 57146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts._ID, // 0 58146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.TITLE, // 1 59146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.EVENT_LOCATION, // 2 60146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.ALL_DAY, // 3 61146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.BEGIN, // 4 62146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.END, // 5 63146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.EVENT_ID, // 6 640e1e62408b96e1532eb6f6a609ae4c817751aaf3RoboErik CalendarAlerts.CALENDAR_COLOR, // 7 65146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.RRULE, // 8 66146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.HAS_ALARM, // 9 67146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.STATE, // 10 68146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project CalendarAlerts.ALARM_TIME, // 11 69146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 705c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 715c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan public static final int INDEX_ROW_ID = 0; 72146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_TITLE = 1; 73146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_EVENT_LOCATION = 2; 74146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_ALL_DAY = 3; 75146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_BEGIN = 4; 76146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_END = 5; 77146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_EVENT_ID = 6; 78146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_COLOR = 7; 79146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_RRULE = 8; 80146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_HAS_ALARM = 9; 81146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_STATE = 10; 82146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int INDEX_ALARM_TIME = 11; 835c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 84e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan private static final String SELECTION = CalendarAlerts.STATE + "=?"; 85e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan private static final String[] SELECTIONARG = new String[] { 86fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik Integer.toString(CalendarAlerts.STATE_FIRED) 87e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan }; 88e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan 89146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // We use one notification id for all events so that we don't clutter 90146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // the notification screen. It doesn't matter what the id is, as long 91146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // as it is used consistently everywhere. 92146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public static final int NOTIFICATION_ID = 0; 935c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 94146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private AlertAdapter mAdapter; 95146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private QueryHandler mQueryHandler; 96146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private Cursor mCursor; 97146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private ListView mListView; 98146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private Button mSnoozeAllButton; 99146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private Button mDismissAllButton; 1005c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 1015c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 1025c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan private void dismissFiredAlarms() { 1035c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan ContentValues values = new ContentValues(1 /* size */); 104fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik values.put(PROJECTION[INDEX_STATE], CalendarAlerts.STATE_DISMISSED); 105fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik String selection = CalendarAlerts.STATE + "=" + CalendarAlerts.STATE_FIRED; 1065c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan mQueryHandler.startUpdate(0, null, CalendarAlerts.CONTENT_URI, values, 107bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan selection, null /* selectionArgs */, Utils.UNDO_DELAY); 1085c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan } 1095c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 1105c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan private void dismissAlarm(long id) { 1115c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan ContentValues values = new ContentValues(1 /* size */); 112fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik values.put(PROJECTION[INDEX_STATE], CalendarAlerts.STATE_DISMISSED); 1135c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan String selection = CalendarAlerts._ID + "=" + id; 1145c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan mQueryHandler.startUpdate(0, null, CalendarAlerts.CONTENT_URI, values, 115bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan selection, null /* selectionArgs */, Utils.UNDO_DELAY); 1165c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan } 1175c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 118bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan private class QueryHandler extends AsyncQueryService { 119bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan public QueryHandler(Context context) { 120bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan super(context); 121146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 122146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 123146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 124146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 125146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Only set mCursor if the Activity is not finishing. Otherwise close the cursor. 126146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (!isFinishing()) { 127146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mCursor = cursor; 128146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mAdapter.changeCursor(cursor); 12910d9f11fec9cb578185e4455eeaef289c0dff8b9Michael Chan mListView.setSelection(cursor.getCount() - 1); 1305c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 131146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // The results are in, enable the buttons 132146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mSnoozeAllButton.setEnabled(true); 133146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mDismissAllButton.setEnabled(true); 134146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 135146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project cursor.close(); 136146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 137146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 1385c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 1395c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan @Override 1405c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan protected void onInsertComplete(int token, Object cookie, Uri uri) { 1415c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan if (uri != null) { 142e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan Long alarmTime = (Long) cookie; 143e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan 144e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan if (alarmTime != 0) { 145e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan // Set a new alarm to go off after the snooze delay. 146fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik // TODO make provider schedule this automatically when 147fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik // inserting an alarm 148e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan AlarmManager alarmManager = 149e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan (AlarmManager) getSystemService(Context.ALARM_SERVICE); 150fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik scheduleAlarm(AlertActivity.this, alarmManager, alarmTime); 151e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan } 1525c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan } 1535c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan } 1545c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 1555c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan @Override 1565c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan protected void onUpdateComplete(int token, Object cookie, int result) { 1575c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan // Ignore 1585c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan } 1595c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan } 1605c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 161fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik /** 162fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * Schedules an alarm intent with the system AlarmManager that will notify 163fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * listeners when a reminder should be fired. The provider will keep 164fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * scheduled reminders up to date but apps may use this to implement snooze 165fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * functionality without modifying the reminders table. Scheduled alarms 166fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * will generate an intent using {@link #ACTION_EVENT_REMINDER}. 167fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * 168fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * @param context A context for referencing system resources 169fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * @param manager The AlarmManager to use or null 170fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik * @param alarmTime The time to fire the intent in UTC millis since epoch 171fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik */ 172fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik public static void scheduleAlarm(Context context, AlarmManager manager, long alarmTime) { 173fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik 174fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik if (manager == null) { 175fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 176fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik } 177fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik 178fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik Intent intent = new Intent(CalendarContract.ACTION_EVENT_REMINDER); 179fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik intent.setData(ContentUris.withAppendedId(CalendarContract.CONTENT_URI, alarmTime)); 180fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik intent.putExtra(CalendarContract.CalendarAlerts.ALARM_TIME, alarmTime); 181fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); 182fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik manager.set(AlarmManager.RTC_WAKEUP, alarmTime, pi); 183fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik } 184fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik 1855c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan private static ContentValues makeContentValues(long eventId, long begin, long end, 1865c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan long alarmTime, int minutes) { 1875c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan ContentValues values = new ContentValues(); 1885c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.EVENT_ID, eventId); 1895c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.BEGIN, begin); 1905c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.END, end); 1915c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.ALARM_TIME, alarmTime); 1925c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan long currentTime = System.currentTimeMillis(); 1935c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.CREATION_TIME, currentTime); 1945c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.RECEIVED_TIME, 0); 1955c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.NOTIFY_TIME, 0); 196fa292a0db2a6f04255c75a57908b17ba48a96183RoboErik values.put(CalendarAlerts.STATE, CalendarAlerts.STATE_SCHEDULED); 1975c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan values.put(CalendarAlerts.MINUTES, minutes); 1985c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan return values; 199146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 2005c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 201146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project private OnItemClickListener mViewListener = new OnItemClickListener() { 202146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 2034ce500bd7d08eac3f05dfd50bce51e620fa9f08eChristian Mehlmauer public void onItemClick(AdapterView<?> parent, View view, int position, 204146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long i) { 205146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project AlertActivity alertActivity = AlertActivity.this; 206146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Cursor cursor = alertActivity.getItemForView(view); 2075c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 2089e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan // Mark this alarm as DISMISSED 2099e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan dismissAlarm(cursor.getLong(INDEX_ROW_ID)); 2109e89dca0902d13fe27fd2680cc15cbb470e40288Michael Chan 211146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long id = cursor.getInt(AlertActivity.INDEX_EVENT_ID); 212146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long startMillis = cursor.getLong(AlertActivity.INDEX_BEGIN); 213146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project long endMillis = cursor.getLong(AlertActivity.INDEX_END); 214db4ce4a81063b7f5f6068f4144f8a3e3bca1e064Erik Intent eventIntent = new Intent(Intent.ACTION_VIEW); 215a7c0390d9c5dd4ff730de505682687fae5f5ced0RoboErik Builder builder = CalendarContract.CONTENT_URI.buildUpon(); 216d050fc8acd93f59ecff1536572b85d84a08335acRoboErik builder.appendEncodedPath("events/" + id); 217db4ce4a81063b7f5f6068f4144f8a3e3bca1e064Erik eventIntent.setData(builder.build()); 21807d9fee87bc02849c0dd7b66326a320d53cf5479Michael Chan eventIntent.setClass(AlertActivity.this, AllInOneActivity.class); 219a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik eventIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis); 220a27a886892fe3ec5edbc63c0b58e0a988623011aRoboErik eventIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis); 221db4ce4a81063b7f5f6068f4144f8a3e3bca1e064Erik alertActivity.startActivity(eventIntent); 2225c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 223146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project alertActivity.finish(); 224146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 225146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project }; 2265c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 227146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 228146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project protected void onCreate(Bundle icicle) { 229146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project super.onCreate(icicle); 2305c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 231146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project setContentView(R.layout.alert_activity); 2327abd8566e5718c43d610e046495bcb412e87847fThe Android Open Source Project setTitle(R.string.alert_title); 2335c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 234bed0275111ecc6c4a3a638f90a9bac13bee594f4Michael Chan mQueryHandler = new QueryHandler(this); 235146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mAdapter = new AlertAdapter(this, R.layout.alert_item); 2365c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 237146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mListView = (ListView) findViewById(R.id.alert_container); 238146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mListView.setItemsCanFocus(true); 239146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mListView.setAdapter(mAdapter); 240146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mListView.setOnItemClickListener(mViewListener); 2415c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 242146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mSnoozeAllButton = (Button) findViewById(R.id.snooze_all); 2431a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa mSnoozeAllButton.setOnClickListener(this); 244146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mDismissAllButton = (Button) findViewById(R.id.dismiss_all); 2451a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa mDismissAllButton.setOnClickListener(this); 246146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project 247146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // Disable the buttons, since they need mCursor, which is created asynchronously 248146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mSnoozeAllButton.setEnabled(false); 249146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mDismissAllButton.setEnabled(false); 250146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 2515c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 252146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 253146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project protected void onResume() { 254146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project super.onResume(); 2555c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 256146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project // If the cursor is null, start the async handler. If it is not null just requery. 257146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mCursor == null) { 258146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project Uri uri = CalendarAlerts.CONTENT_URI_BY_INSTANCE; 259e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan mQueryHandler.startQuery(0, null, uri, PROJECTION, SELECTION, 260e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan SELECTIONARG, CalendarAlerts.DEFAULT_SORT_ORDER); 261146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } else { 2621a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa if (!mCursor.requery()) { 2631a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa Log.w(TAG, "Cursor#requery() failed."); 2641a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa mCursor.close(); 2651a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa mCursor = null; 2661a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa } 267146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 268146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 2695c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 270146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 271146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project protected void onStop() { 272146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project super.onStop(); 273e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan AlertService.updateAlertNotification(this); 2745c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 275146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mCursor != null) { 276146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mCursor.deactivate(); 277146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 278146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 2795c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 280146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project @Override 281146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project protected void onDestroy() { 282146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project super.onDestroy(); 283146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (mCursor != null) { 284146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project mCursor.close(); 285146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 286146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 2875c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 2881a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa @Override 2891a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa public void onClick(View v) { 2901a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa if (v == mSnoozeAllButton) { 2915c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan long alarmTime = System.currentTimeMillis() + SNOOZE_DELAY; 2925c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 293146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project NotificationManager nm = 294146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 295146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project nm.cancel(NOTIFICATION_ID); 296e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan 2971a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa if (mCursor != null) { 2981a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa long scheduleAlarmTime = 0; 2991a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa mCursor.moveToPosition(-1); 3001a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa while (mCursor.moveToNext()) { 3011a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa long eventId = mCursor.getLong(INDEX_EVENT_ID); 3021a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa long begin = mCursor.getLong(INDEX_BEGIN); 3031a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa long end = mCursor.getLong(INDEX_END); 3041a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa 3051a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa // Set the "minutes" to zero to indicate this is a snoozed 3061a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa // alarm. There is code in AlertService.java that checks 3071a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa // this field. 3081a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa ContentValues values = 3091a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa makeContentValues(eventId, begin, end, alarmTime, 0 /* minutes */); 3101a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa 3111a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa // Create a new alarm entry in the CalendarAlerts table 3121a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa if (mCursor.isLast()) { 3131a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa scheduleAlarmTime = alarmTime; 3141a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa } 3151a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa mQueryHandler.startInsert(0, 3161a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa scheduleAlarmTime, CalendarAlerts.CONTENT_URI, values, 3171a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa Utils.UNDO_DELAY); 318e2ae1ef8decfddcc4e5802483e92cab93c6fc67cMichael Chan } 3191a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa } else { 3201a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa Log.d(TAG, "Cursor object is null. Ignore the Snooze request."); 321146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 3225c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 3235c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan dismissFiredAlarms(); 324146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project finish(); 3251a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa } else if (v == mDismissAllButton) { 326146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project NotificationManager nm = 327146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 328146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project nm.cancel(NOTIFICATION_ID); 3295c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 3305c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan dismissFiredAlarms(); 3315c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 332146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project finish(); 333146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 3341a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa } 3355c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 336146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public boolean isEmpty() { 3371a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa return mCursor != null ? (mCursor.getCount() == 0) : true; 338146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 3395c7290c760979b1a43acfb6d90d6216d0e0a0934Michael Chan 340146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project public Cursor getItemForView(View view) { 3411a7fa28f2ac6bd293bb4009d22f3f1426e7658c3Daisuke Miyakawa final int index = mListView.getPositionForView(view); 342146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project if (index < 0) { 343146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return null; 344146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 345146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project return (Cursor) mListView.getAdapter().getItem(index); 346146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project } 347146de36083f6ce8b7e8a1f974d3990594a36bfecThe Android Open Source Project} 348