AlertActivity.java revision b8d0a58e51251f4d65917fc27c86f9f0822478a9
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 17package com.android.calendar.alerts; 18 19import android.app.Activity; 20import android.app.NotificationManager; 21import android.app.TaskStackBuilder; 22import android.content.ContentValues; 23import android.content.Context; 24import android.content.Intent; 25import android.database.Cursor; 26import android.net.Uri; 27import android.os.Build; 28import android.os.Bundle; 29import android.provider.CalendarContract; 30import android.provider.CalendarContract.CalendarAlerts; 31import android.util.Log; 32import android.view.View; 33import android.view.View.OnClickListener; 34import android.widget.AdapterView; 35import android.widget.AdapterView.OnItemClickListener; 36import android.widget.Button; 37import android.widget.ListView; 38 39import com.android.calendar.AsyncQueryService; 40import com.android.calendar.EventInfoActivity; 41import com.android.calendar.R; 42import com.android.calendar.Utils; 43 44/** 45 * The alert panel that pops up when there is a calendar event alarm. 46 * This activity is started by an intent that specifies an event id. 47 */ 48public class AlertActivity extends Activity implements OnClickListener { 49 private static final String TAG = "AlertActivity"; 50 51 private static final String[] PROJECTION = new String[] { 52 CalendarAlerts._ID, // 0 53 CalendarAlerts.TITLE, // 1 54 CalendarAlerts.EVENT_LOCATION, // 2 55 CalendarAlerts.ALL_DAY, // 3 56 CalendarAlerts.BEGIN, // 4 57 CalendarAlerts.END, // 5 58 CalendarAlerts.EVENT_ID, // 6 59 CalendarAlerts.CALENDAR_COLOR, // 7 60 CalendarAlerts.RRULE, // 8 61 CalendarAlerts.HAS_ALARM, // 9 62 CalendarAlerts.STATE, // 10 63 CalendarAlerts.ALARM_TIME, // 11 64 }; 65 66 public static final int INDEX_ROW_ID = 0; 67 public static final int INDEX_TITLE = 1; 68 public static final int INDEX_EVENT_LOCATION = 2; 69 public static final int INDEX_ALL_DAY = 3; 70 public static final int INDEX_BEGIN = 4; 71 public static final int INDEX_END = 5; 72 public static final int INDEX_EVENT_ID = 6; 73 public static final int INDEX_COLOR = 7; 74 public static final int INDEX_RRULE = 8; 75 public static final int INDEX_HAS_ALARM = 9; 76 public static final int INDEX_STATE = 10; 77 public static final int INDEX_ALARM_TIME = 11; 78 79 private static final String SELECTION = CalendarAlerts.STATE + "=?"; 80 private static final String[] SELECTIONARG = new String[] { 81 Integer.toString(CalendarAlerts.STATE_FIRED) 82 }; 83 84 private AlertAdapter mAdapter; 85 private QueryHandler mQueryHandler; 86 private Cursor mCursor; 87 private ListView mListView; 88 private Button mDismissAllButton; 89 90 91 private void dismissFiredAlarms() { 92 ContentValues values = new ContentValues(1 /* size */); 93 values.put(PROJECTION[INDEX_STATE], CalendarAlerts.STATE_DISMISSED); 94 String selection = CalendarAlerts.STATE + "=" + CalendarAlerts.STATE_FIRED; 95 mQueryHandler.startUpdate(0, null, CalendarAlerts.CONTENT_URI, values, 96 selection, null /* selectionArgs */, Utils.UNDO_DELAY); 97 } 98 99 private void dismissAlarm(long id) { 100 ContentValues values = new ContentValues(1 /* size */); 101 values.put(PROJECTION[INDEX_STATE], CalendarAlerts.STATE_DISMISSED); 102 String selection = CalendarAlerts._ID + "=" + id; 103 mQueryHandler.startUpdate(0, null, CalendarAlerts.CONTENT_URI, values, 104 selection, null /* selectionArgs */, Utils.UNDO_DELAY); 105 } 106 107 private class QueryHandler extends AsyncQueryService { 108 public QueryHandler(Context context) { 109 super(context); 110 } 111 112 @Override 113 protected void onQueryComplete(int token, Object cookie, Cursor cursor) { 114 // Only set mCursor if the Activity is not finishing. Otherwise close the cursor. 115 if (!isFinishing()) { 116 mCursor = cursor; 117 mAdapter.changeCursor(cursor); 118 mListView.setSelection(cursor.getCount() - 1); 119 120 // The results are in, enable the buttons 121 mDismissAllButton.setEnabled(true); 122 } else { 123 cursor.close(); 124 } 125 } 126 127 @Override 128 protected void onInsertComplete(int token, Object cookie, Uri uri) { 129 if (uri != null) { 130 Long alarmTime = (Long) cookie; 131 132 if (alarmTime != 0) { 133 // Set a new alarm to go off after the snooze delay. 134 // TODO make provider schedule this automatically when 135 // inserting an alarm 136 AlertUtils.scheduleAlarm(AlertActivity.this, null, alarmTime); 137 } 138 } 139 } 140 141 @Override 142 protected void onUpdateComplete(int token, Object cookie, int result) { 143 // Ignore 144 } 145 } 146 147 148 149 private final OnItemClickListener mViewListener = new OnItemClickListener() { 150 151 @Override 152 public void onItemClick(AdapterView<?> parent, View view, int position, 153 long i) { 154 AlertActivity alertActivity = AlertActivity.this; 155 Cursor cursor = alertActivity.getItemForView(view); 156 157 // Mark this alarm as DISMISSED 158 dismissAlarm(cursor.getLong(INDEX_ROW_ID)); 159 160 // build an intent and task stack to start EventInfoActivity with AllInOneActivity 161 // as the parent activity rooted to home. 162 long id = cursor.getInt(AlertActivity.INDEX_EVENT_ID); 163 long startMillis = cursor.getLong(AlertActivity.INDEX_BEGIN); 164 long endMillis = cursor.getLong(AlertActivity.INDEX_END); 165 Intent eventIntent = AlertUtils.buildEventViewIntent(AlertActivity.this, id, 166 startMillis, endMillis); 167 168 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { 169 alertActivity.startActivity(eventIntent); 170 } else { 171 TaskStackBuilder.create(AlertActivity.this).addParentStack(EventInfoActivity.class) 172 .addNextIntent(eventIntent).startActivities(); 173 } 174 175 alertActivity.finish(); 176 } 177 }; 178 179 @Override 180 protected void onCreate(Bundle icicle) { 181 super.onCreate(icicle); 182 183 setContentView(R.layout.alert_activity); 184 setTitle(R.string.alert_title); 185 186 mQueryHandler = new QueryHandler(this); 187 mAdapter = new AlertAdapter(this, R.layout.alert_item); 188 189 mListView = (ListView) findViewById(R.id.alert_container); 190 mListView.setItemsCanFocus(true); 191 mListView.setAdapter(mAdapter); 192 mListView.setOnItemClickListener(mViewListener); 193 194 mDismissAllButton = (Button) findViewById(R.id.dismiss_all); 195 mDismissAllButton.setOnClickListener(this); 196 197 // Disable the buttons, since they need mCursor, which is created asynchronously 198 mDismissAllButton.setEnabled(false); 199 } 200 201 @Override 202 protected void onResume() { 203 super.onResume(); 204 205 // If the cursor is null, start the async handler. If it is not null just requery. 206 if (mCursor == null) { 207 Uri uri = CalendarAlerts.CONTENT_URI_BY_INSTANCE; 208 mQueryHandler.startQuery(0, null, uri, PROJECTION, SELECTION, SELECTIONARG, 209 CalendarContract.CalendarAlerts.DEFAULT_SORT_ORDER); 210 } else { 211 if (!mCursor.requery()) { 212 Log.w(TAG, "Cursor#requery() failed."); 213 mCursor.close(); 214 mCursor = null; 215 } 216 } 217 } 218 219 @Override 220 protected void onStop() { 221 super.onStop(); 222 AlertService.updateAlertNotification(this); 223 224 if (mCursor != null) { 225 mCursor.deactivate(); 226 } 227 } 228 229 @Override 230 protected void onDestroy() { 231 super.onDestroy(); 232 if (mCursor != null) { 233 mCursor.close(); 234 } 235 } 236 237 @Override 238 public void onClick(View v) { 239 if (v == mDismissAllButton) { 240 NotificationManager nm = 241 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 242 nm.cancelAll(); 243 244 dismissFiredAlarms(); 245 246 finish(); 247 } 248 } 249 250 public boolean isEmpty() { 251 return mCursor != null ? (mCursor.getCount() == 0) : true; 252 } 253 254 public Cursor getItemForView(View view) { 255 final int index = mListView.getPositionForView(view); 256 if (index < 0) { 257 return null; 258 } 259 return (Cursor) mListView.getAdapter().getItem(index); 260 } 261} 262