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