The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2007 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Mason Tang | 23e7da3 | 2010-07-27 15:24:02 -0700 | [diff] [blame] | 17 | package com.android.calendar.alerts; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 18 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 19 | import android.app.Activity; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 20 | import android.app.NotificationManager; |
Isaac Katzenelson | 0ef732f | 2012-04-26 17:39:14 -0700 | [diff] [blame] | 21 | import android.app.TaskStackBuilder; |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 22 | import android.content.ContentValues; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 23 | import android.content.Context; |
Erik | db4ce4a | 2010-10-27 12:50:59 -0700 | [diff] [blame] | 24 | import android.content.Intent; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 25 | import android.database.Cursor; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 26 | import android.net.Uri; |
| 27 | import android.os.Bundle; |
Michael Chan | 8f7f1ab | 2012-05-11 07:03:26 -0700 | [diff] [blame] | 28 | import android.provider.CalendarContract; |
RoboErik | a7c0390 | 2011-06-14 11:06:44 -0700 | [diff] [blame] | 29 | import android.provider.CalendarContract.CalendarAlerts; |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 30 | import android.util.Log; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 31 | import android.view.View; |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 32 | import android.view.View.OnClickListener; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 33 | import android.widget.AdapterView; |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 34 | import android.widget.AdapterView.OnItemClickListener; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 35 | import android.widget.Button; |
| 36 | import android.widget.ListView; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 37 | |
Michael Chan | 8f7f1ab | 2012-05-11 07:03:26 -0700 | [diff] [blame] | 38 | import com.android.calendar.AsyncQueryService; |
| 39 | import com.android.calendar.EventInfoActivity; |
| 40 | import com.android.calendar.R; |
| 41 | import com.android.calendar.Utils; |
| 42 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 43 | /** |
| 44 | * The alert panel that pops up when there is a calendar event alarm. |
| 45 | * This activity is started by an intent that specifies an event id. |
| 46 | */ |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 47 | public class AlertActivity extends Activity implements OnClickListener { |
| 48 | private static final String TAG = "AlertActivity"; |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 49 | |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 50 | private static final String[] PROJECTION = new String[] { |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 51 | CalendarAlerts._ID, // 0 |
| 52 | CalendarAlerts.TITLE, // 1 |
| 53 | CalendarAlerts.EVENT_LOCATION, // 2 |
| 54 | CalendarAlerts.ALL_DAY, // 3 |
| 55 | CalendarAlerts.BEGIN, // 4 |
| 56 | CalendarAlerts.END, // 5 |
| 57 | CalendarAlerts.EVENT_ID, // 6 |
Isaac Katzenelson | 9881907 | 2012-03-01 15:58:30 -0800 | [diff] [blame] | 58 | CalendarAlerts.CALENDAR_COLOR, // 7 |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 59 | CalendarAlerts.RRULE, // 8 |
| 60 | CalendarAlerts.HAS_ALARM, // 9 |
| 61 | CalendarAlerts.STATE, // 10 |
| 62 | CalendarAlerts.ALARM_TIME, // 11 |
| 63 | }; |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 64 | |
| 65 | public static final int INDEX_ROW_ID = 0; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 66 | public static final int INDEX_TITLE = 1; |
| 67 | public static final int INDEX_EVENT_LOCATION = 2; |
| 68 | public static final int INDEX_ALL_DAY = 3; |
| 69 | public static final int INDEX_BEGIN = 4; |
| 70 | public static final int INDEX_END = 5; |
| 71 | public static final int INDEX_EVENT_ID = 6; |
| 72 | public static final int INDEX_COLOR = 7; |
| 73 | public static final int INDEX_RRULE = 8; |
| 74 | public static final int INDEX_HAS_ALARM = 9; |
| 75 | public static final int INDEX_STATE = 10; |
| 76 | public static final int INDEX_ALARM_TIME = 11; |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 77 | |
Sara Ting | bb57710 | 2012-05-11 15:55:48 -0700 | [diff] [blame] | 78 | private static final String SELECTION = CalendarAlerts.STATE + "=?"; |
| 79 | private static final String[] SELECTIONARG = new String[] { |
| 80 | Integer.toString(CalendarAlerts.STATE_FIRED) |
| 81 | }; |
Michael Chan | e2ae1ef | 2009-11-18 18:37:09 -0800 | [diff] [blame] | 82 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 83 | private AlertAdapter mAdapter; |
| 84 | private QueryHandler mQueryHandler; |
| 85 | private Cursor mCursor; |
| 86 | private ListView mListView; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 87 | private Button mDismissAllButton; |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 88 | |
| 89 | |
Sara Ting | bb57710 | 2012-05-11 15:55:48 -0700 | [diff] [blame] | 90 | private void dismissFiredAlarms() { |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 91 | ContentValues values = new ContentValues(1 /* size */); |
RoboErik | fa292a0 | 2011-06-30 12:49:42 -0700 | [diff] [blame] | 92 | values.put(PROJECTION[INDEX_STATE], CalendarAlerts.STATE_DISMISSED); |
Sara Ting | bb57710 | 2012-05-11 15:55:48 -0700 | [diff] [blame] | 93 | String selection = CalendarAlerts.STATE + "=" + CalendarAlerts.STATE_FIRED; |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 94 | mQueryHandler.startUpdate(0, null, CalendarAlerts.CONTENT_URI, values, |
Michael Chan | bed0275 | 2010-04-27 10:56:53 -0700 | [diff] [blame] | 95 | selection, null /* selectionArgs */, Utils.UNDO_DELAY); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 96 | } |
| 97 | |
| 98 | private void dismissAlarm(long id) { |
| 99 | ContentValues values = new ContentValues(1 /* size */); |
RoboErik | fa292a0 | 2011-06-30 12:49:42 -0700 | [diff] [blame] | 100 | values.put(PROJECTION[INDEX_STATE], CalendarAlerts.STATE_DISMISSED); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 101 | String selection = CalendarAlerts._ID + "=" + id; |
| 102 | mQueryHandler.startUpdate(0, null, CalendarAlerts.CONTENT_URI, values, |
Michael Chan | bed0275 | 2010-04-27 10:56:53 -0700 | [diff] [blame] | 103 | selection, null /* selectionArgs */, Utils.UNDO_DELAY); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 104 | } |
| 105 | |
Michael Chan | bed0275 | 2010-04-27 10:56:53 -0700 | [diff] [blame] | 106 | private class QueryHandler extends AsyncQueryService { |
| 107 | public QueryHandler(Context context) { |
| 108 | super(context); |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 109 | } |
| 110 | |
| 111 | @Override |
| 112 | protected void onQueryComplete(int token, Object cookie, Cursor cursor) { |
| 113 | // Only set mCursor if the Activity is not finishing. Otherwise close the cursor. |
| 114 | if (!isFinishing()) { |
| 115 | mCursor = cursor; |
| 116 | mAdapter.changeCursor(cursor); |
Michael Chan | 10d9f11 | 2011-01-17 21:17:08 -0800 | [diff] [blame] | 117 | mListView.setSelection(cursor.getCount() - 1); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 118 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 119 | // The results are in, enable the buttons |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 120 | mDismissAllButton.setEnabled(true); |
| 121 | } else { |
| 122 | cursor.close(); |
| 123 | } |
| 124 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 125 | |
| 126 | @Override |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 127 | protected void onUpdateComplete(int token, Object cookie, int result) { |
| 128 | // Ignore |
| 129 | } |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 130 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 131 | |
Isaac Katzenelson | 0ef732f | 2012-04-26 17:39:14 -0700 | [diff] [blame] | 132 | private final OnItemClickListener mViewListener = new OnItemClickListener() { |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 133 | |
Isaac Katzenelson | 9881907 | 2012-03-01 15:58:30 -0800 | [diff] [blame] | 134 | @Override |
Christian Mehlmauer | 4ce500b | 2010-05-17 01:10:01 +0200 | [diff] [blame] | 135 | public void onItemClick(AdapterView<?> parent, View view, int position, |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 136 | long i) { |
| 137 | AlertActivity alertActivity = AlertActivity.this; |
| 138 | Cursor cursor = alertActivity.getItemForView(view); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 139 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 140 | // Mark this alarm as DISMISSED |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 141 | dismissAlarm(cursor.getLong(INDEX_ROW_ID)); |
| 142 | |
Isaac Katzenelson | 0ef732f | 2012-04-26 17:39:14 -0700 | [diff] [blame] | 143 | // build an intent and task stack to start EventInfoActivity with AllInOneActivity |
| 144 | // as the parent activity rooted to home. |
Michael Chan | 9e89dca | 2010-07-13 17:56:09 -0700 | [diff] [blame] | 145 | long id = cursor.getInt(AlertActivity.INDEX_EVENT_ID); |
| 146 | long startMillis = cursor.getLong(AlertActivity.INDEX_BEGIN); |
| 147 | long endMillis = cursor.getLong(AlertActivity.INDEX_END); |
Isaac Katzenelson | 9881907 | 2012-03-01 15:58:30 -0800 | [diff] [blame] | 148 | Intent eventIntent = AlertUtils.buildEventViewIntent(AlertActivity.this, id, |
| 149 | startMillis, endMillis); |
Isaac Katzenelson | 0ef732f | 2012-04-26 17:39:14 -0700 | [diff] [blame] | 150 | |
Sara Ting | fac2d15 | 2012-05-31 14:59:57 -0700 | [diff] [blame] | 151 | if (Utils.isJellybeanOrLater()) { |
Michael Chan | 693ca60 | 2012-05-31 12:24:11 -0700 | [diff] [blame] | 152 | TaskStackBuilder.create(AlertActivity.this).addParentStack(EventInfoActivity.class) |
| 153 | .addNextIntent(eventIntent).startActivities(); |
Sara Ting | fac2d15 | 2012-05-31 14:59:57 -0700 | [diff] [blame] | 154 | } else { |
| 155 | alertActivity.startActivity(eventIntent); |
Michael Chan | 693ca60 | 2012-05-31 12:24:11 -0700 | [diff] [blame] | 156 | } |
Michael Chan | 9e89dca | 2010-07-13 17:56:09 -0700 | [diff] [blame] | 157 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 158 | alertActivity.finish(); |
| 159 | } |
| 160 | }; |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 161 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 162 | @Override |
| 163 | protected void onCreate(Bundle icicle) { |
| 164 | super.onCreate(icicle); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 165 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 166 | setContentView(R.layout.alert_activity); |
Sara Ting | bb57710 | 2012-05-11 15:55:48 -0700 | [diff] [blame] | 167 | setTitle(R.string.alert_title); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 168 | |
Michael Chan | bed0275 | 2010-04-27 10:56:53 -0700 | [diff] [blame] | 169 | mQueryHandler = new QueryHandler(this); |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 170 | mAdapter = new AlertAdapter(this, R.layout.alert_item); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 171 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 172 | mListView = (ListView) findViewById(R.id.alert_container); |
| 173 | mListView.setItemsCanFocus(true); |
| 174 | mListView.setAdapter(mAdapter); |
| 175 | mListView.setOnItemClickListener(mViewListener); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 176 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 177 | mDismissAllButton = (Button) findViewById(R.id.dismiss_all); |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 178 | mDismissAllButton.setOnClickListener(this); |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 179 | |
| 180 | // Disable the buttons, since they need mCursor, which is created asynchronously |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 181 | mDismissAllButton.setEnabled(false); |
| 182 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 183 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 184 | @Override |
| 185 | protected void onResume() { |
| 186 | super.onResume(); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 187 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 188 | // If the cursor is null, start the async handler. If it is not null just requery. |
| 189 | if (mCursor == null) { |
| 190 | Uri uri = CalendarAlerts.CONTENT_URI_BY_INSTANCE; |
Sara Ting | bb57710 | 2012-05-11 15:55:48 -0700 | [diff] [blame] | 191 | mQueryHandler.startQuery(0, null, uri, PROJECTION, SELECTION, SELECTIONARG, |
Michael Chan | 8f7f1ab | 2012-05-11 07:03:26 -0700 | [diff] [blame] | 192 | CalendarContract.CalendarAlerts.DEFAULT_SORT_ORDER); |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 193 | } else { |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 194 | if (!mCursor.requery()) { |
| 195 | Log.w(TAG, "Cursor#requery() failed."); |
| 196 | mCursor.close(); |
| 197 | mCursor = null; |
| 198 | } |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 199 | } |
| 200 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 201 | |
Sara Ting | c912980 | 2012-07-26 13:59:25 -0700 | [diff] [blame] | 202 | void closeActivityIfEmpty() { |
Sara Ting | 5023750 | 2012-07-31 16:18:55 -0700 | [diff] [blame] | 203 | if (mCursor != null && !mCursor.isClosed() && mCursor.getCount() == 0) { |
Sara Ting | c912980 | 2012-07-26 13:59:25 -0700 | [diff] [blame] | 204 | AlertActivity.this.finish(); |
| 205 | } |
| 206 | } |
| 207 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 208 | @Override |
| 209 | protected void onStop() { |
| 210 | super.onStop(); |
Sara Ting | bb57710 | 2012-05-11 15:55:48 -0700 | [diff] [blame] | 211 | AlertService.updateAlertNotification(this); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 212 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 213 | if (mCursor != null) { |
| 214 | mCursor.deactivate(); |
| 215 | } |
| 216 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 217 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 218 | @Override |
| 219 | protected void onDestroy() { |
| 220 | super.onDestroy(); |
| 221 | if (mCursor != null) { |
| 222 | mCursor.close(); |
| 223 | } |
| 224 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 225 | |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 226 | @Override |
| 227 | public void onClick(View v) { |
Sara Ting | 42ba5ef | 2012-05-04 10:28:56 -0700 | [diff] [blame] | 228 | if (v == mDismissAllButton) { |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 229 | NotificationManager nm = |
| 230 | (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
Sara Ting | ff23072 | 2012-05-30 12:31:27 -0700 | [diff] [blame] | 231 | nm.cancelAll(); |
Michael Chan | e2ae1ef | 2009-11-18 18:37:09 -0800 | [diff] [blame] | 232 | |
Sara Ting | bb57710 | 2012-05-11 15:55:48 -0700 | [diff] [blame] | 233 | dismissFiredAlarms(); |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 234 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 235 | finish(); |
| 236 | } |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 237 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 238 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 239 | public boolean isEmpty() { |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 240 | return mCursor != null ? (mCursor.getCount() == 0) : true; |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 241 | } |
Michael Chan | 5c7290c | 2009-07-16 17:41:59 -0700 | [diff] [blame] | 242 | |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 243 | public Cursor getItemForView(View view) { |
Daisuke Miyakawa | 1a7fa28 | 2010-10-15 17:37:37 -0700 | [diff] [blame] | 244 | final int index = mListView.getPositionForView(view); |
The Android Open Source Project | 146de36 | 2009-03-03 19:32:18 -0800 | [diff] [blame] | 245 | if (index < 0) { |
| 246 | return null; |
| 247 | } |
| 248 | return (Cursor) mListView.getAdapter().getItem(index); |
| 249 | } |
| 250 | } |