• 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
onUpdateComplete(int token, Object cookie, int result)127         protected void onUpdateComplete(int token, Object cookie, int result) {
128             // Ignore
129         }
130     }
131 
132     private final OnItemClickListener mViewListener = new OnItemClickListener() {
133 
134         @Override
135         public void onItemClick(AdapterView<?> parent, View view, int position,
136                 long i) {
137             AlertActivity alertActivity = AlertActivity.this;
138             Cursor cursor = alertActivity.getItemForView(view);
139 
140             // Mark this alarm as DISMISSED
141             dismissAlarm(cursor.getLong(INDEX_ROW_ID));
142 
143             // build an intent and task stack to start EventInfoActivity with AllInOneActivity
144             // as the parent activity rooted to home.
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);
148             Intent eventIntent = AlertUtils.buildEventViewIntent(AlertActivity.this, id,
149                     startMillis, endMillis);
150 
151             if (Utils.isJellybeanOrLater()) {
152                 TaskStackBuilder.create(AlertActivity.this).addParentStack(EventInfoActivity.class)
153                         .addNextIntent(eventIntent).startActivities();
154             } else {
155                 alertActivity.startActivity(eventIntent);
156             }
157 
158             alertActivity.finish();
159         }
160     };
161 
162     @Override
onCreate(Bundle icicle)163     protected void onCreate(Bundle icicle) {
164         super.onCreate(icicle);
165 
166         setContentView(R.layout.alert_activity);
167         setTitle(R.string.alert_title);
168 
169         mQueryHandler = new QueryHandler(this);
170         mAdapter = new AlertAdapter(this, R.layout.alert_item);
171 
172         mListView = (ListView) findViewById(R.id.alert_container);
173         mListView.setItemsCanFocus(true);
174         mListView.setAdapter(mAdapter);
175         mListView.setOnItemClickListener(mViewListener);
176 
177         mDismissAllButton = (Button) findViewById(R.id.dismiss_all);
178         mDismissAllButton.setOnClickListener(this);
179 
180         // Disable the buttons, since they need mCursor, which is created asynchronously
181         mDismissAllButton.setEnabled(false);
182     }
183 
184     @Override
onResume()185     protected void onResume() {
186         super.onResume();
187 
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;
191             mQueryHandler.startQuery(0, null, uri, PROJECTION, SELECTION, SELECTIONARG,
192                     CalendarContract.CalendarAlerts.DEFAULT_SORT_ORDER);
193         } else {
194             if (!mCursor.requery()) {
195                 Log.w(TAG, "Cursor#requery() failed.");
196                 mCursor.close();
197                 mCursor = null;
198             }
199         }
200     }
201 
closeActivityIfEmpty()202     void closeActivityIfEmpty() {
203         if (mCursor != null && !mCursor.isClosed() && mCursor.getCount() == 0) {
204             AlertActivity.this.finish();
205         }
206     }
207 
208     @Override
onStop()209     protected void onStop() {
210         super.onStop();
211         AlertService.updateAlertNotification(this);
212 
213         if (mCursor != null) {
214             mCursor.deactivate();
215         }
216     }
217 
218     @Override
onDestroy()219     protected void onDestroy() {
220         super.onDestroy();
221         if (mCursor != null) {
222             mCursor.close();
223         }
224     }
225 
226     @Override
onClick(View v)227     public void onClick(View v) {
228         if (v == mDismissAllButton) {
229             NotificationManager nm =
230                 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
231             nm.cancelAll();
232 
233             dismissFiredAlarms();
234 
235             finish();
236         }
237     }
238 
isEmpty()239     public boolean isEmpty() {
240         return mCursor != null ? (mCursor.getCount() == 0) : true;
241     }
242 
getItemForView(View view)243     public Cursor getItemForView(View view) {
244         final int index = mListView.getPositionForView(view);
245         if (index < 0) {
246             return null;
247         }
248         return (Cursor) mListView.getAdapter().getItem(index);
249     }
250 }
251