/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.calendar; import static android.provider.Calendar.EVENT_BEGIN_TIME; import static android.provider.Calendar.EVENT_END_TIME; import android.app.Activity; import android.app.AlarmManager; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.AsyncQueryHandler; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.res.TypedArray; import android.database.Cursor; import android.graphics.PixelFormat; import android.net.Uri; import android.os.Bundle; import android.provider.Calendar; import android.provider.Calendar.CalendarAlerts; import android.provider.Calendar.Events; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.Button; import android.widget.ListView; import android.widget.AdapterView.OnItemClickListener; /** * The alert panel that pops up when there is a calendar event alarm. * This activity is started by an intent that specifies an event id. */ public class AlertActivity extends Activity { // The default snooze delay: 5 minutes public static final long SNOOZE_DELAY = 5 * 60 * 1000L; private static final String[] PROJECTION = new String[] { CalendarAlerts._ID, // 0 CalendarAlerts.TITLE, // 1 CalendarAlerts.EVENT_LOCATION, // 2 CalendarAlerts.ALL_DAY, // 3 CalendarAlerts.BEGIN, // 4 CalendarAlerts.END, // 5 CalendarAlerts.EVENT_ID, // 6 CalendarAlerts.COLOR, // 7 CalendarAlerts.RRULE, // 8 CalendarAlerts.HAS_ALARM, // 9 CalendarAlerts.STATE, // 10 CalendarAlerts.ALARM_TIME, // 11 }; public static final int INDEX_TITLE = 1; public static final int INDEX_EVENT_LOCATION = 2; public static final int INDEX_ALL_DAY = 3; public static final int INDEX_BEGIN = 4; public static final int INDEX_END = 5; public static final int INDEX_EVENT_ID = 6; public static final int INDEX_COLOR = 7; public static final int INDEX_RRULE = 8; public static final int INDEX_HAS_ALARM = 9; public static final int INDEX_STATE = 10; public static final int INDEX_ALARM_TIME = 11; // We use one notification id for all events so that we don't clutter // the notification screen. It doesn't matter what the id is, as long // as it is used consistently everywhere. public static final int NOTIFICATION_ID = 0; private ContentResolver mResolver; private AlertAdapter mAdapter; private QueryHandler mQueryHandler; private Cursor mCursor; private ListView mListView; private Button mSnoozeAllButton; private Button mDismissAllButton; private class QueryHandler extends AsyncQueryHandler { public QueryHandler(ContentResolver cr) { super(cr); } @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { // Only set mCursor if the Activity is not finishing. Otherwise close the cursor. if (!isFinishing()) { mCursor = cursor; mAdapter.changeCursor(cursor); // The results are in, enable the buttons mSnoozeAllButton.setEnabled(true); mDismissAllButton.setEnabled(true); } else { cursor.close(); } } } private OnItemClickListener mViewListener = new OnItemClickListener() { public void onItemClick(AdapterView parent, View view, int position, long i) { AlertActivity alertActivity = AlertActivity.this; Cursor cursor = alertActivity.getItemForView(view); long id = cursor.getInt(AlertActivity.INDEX_EVENT_ID); long startMillis = cursor.getLong(AlertActivity.INDEX_BEGIN); long endMillis = cursor.getLong(AlertActivity.INDEX_END); Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, id); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.setClass(alertActivity, EventInfoActivity.class); intent.putExtra(EVENT_BEGIN_TIME, startMillis); intent.putExtra(EVENT_END_TIME, endMillis); // Mark this alarm as DISMISSED cursor.updateInt(INDEX_STATE, CalendarAlerts.DISMISSED); cursor.commitUpdates(); startActivity(intent); alertActivity.finish(); } }; @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.alert_activity); setTitle(R.string.alert_title); WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.width = ViewGroup.LayoutParams.FILL_PARENT; lp.height = ViewGroup.LayoutParams.FILL_PARENT; // Get the dim amount from the theme TypedArray a = obtainStyledAttributes(com.android.internal.R.styleable.Theme); lp.dimAmount = a.getFloat(android.R.styleable.Theme_backgroundDimAmount, 0.5f); a.recycle(); getWindow().setAttributes(lp); getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); mResolver = getContentResolver(); mQueryHandler = new QueryHandler(mResolver); mAdapter = new AlertAdapter(this, R.layout.alert_item); mListView = (ListView) findViewById(R.id.alert_container); mListView.setItemsCanFocus(true); mListView.setAdapter(mAdapter); mListView.setOnItemClickListener(mViewListener); mSnoozeAllButton = (Button) findViewById(R.id.snooze_all); mSnoozeAllButton.setOnClickListener(mSnoozeAllListener); mDismissAllButton = (Button) findViewById(R.id.dismiss_all); mDismissAllButton.setOnClickListener(mDismissAllListener); // Disable the buttons, since they need mCursor, which is created asynchronously mSnoozeAllButton.setEnabled(false); mDismissAllButton.setEnabled(false); } @Override protected void onResume() { super.onResume(); // If the cursor is null, start the async handler. If it is not null just requery. if (mCursor == null) { Uri uri = CalendarAlerts.CONTENT_URI_BY_INSTANCE; String selection = CalendarAlerts.STATE + "=" + CalendarAlerts.FIRED; mQueryHandler.startQuery(0, null, uri, PROJECTION, selection, null /* selection args */, CalendarAlerts.DEFAULT_SORT_ORDER); } else { mCursor.requery(); } } @Override protected void onStop() { super.onStop(); AlertReceiver.updateAlertNotification(this); if (mCursor != null) { mCursor.deactivate(); } } @Override protected void onDestroy() { super.onDestroy(); if (mCursor != null) { mCursor.close(); } } private OnClickListener mSnoozeAllListener = new OnClickListener() { public void onClick(View v) { NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.cancel(NOTIFICATION_ID); mCursor.moveToPosition(-1); while (mCursor.moveToNext()) { long eventId = mCursor.getLong(INDEX_EVENT_ID); long begin = mCursor.getLong(INDEX_BEGIN); long end = mCursor.getLong(INDEX_END); long alarmTime = mCursor.getLong(INDEX_ALARM_TIME); // Mark this alarm as DISMISSED mCursor.updateInt(INDEX_STATE, CalendarAlerts.DISMISSED); // Create a new alarm entry in the CalendarAlerts table long now = System.currentTimeMillis(); alarmTime = now + SNOOZE_DELAY; // Set the "minutes" to zero to indicate this is a snoozed // alarm. There is code in AlertService.java that checks // this field. Uri uri = CalendarAlerts.insert(mResolver, eventId, begin, end, alarmTime, 0 /* minutes */); // Set a new alarm to go off after the snooze delay. Intent intent = new Intent(Calendar.EVENT_REMINDER_ACTION); intent.setData(uri); intent.putExtra(Calendar.EVENT_BEGIN_TIME, begin); intent.putExtra(Calendar.EVENT_END_TIME, end); PendingIntent sender = PendingIntent.getBroadcast(AlertActivity.this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); Object service = getSystemService(Context.ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) service; alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, sender); } mCursor.commitUpdates(); finish(); } }; private OnClickListener mDismissAllListener = new OnClickListener() { public void onClick(View v) { NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.cancel(NOTIFICATION_ID); mCursor.moveToPosition(-1); while (mCursor.moveToNext()) { mCursor.updateInt(INDEX_STATE, CalendarAlerts.DISMISSED); } mCursor.commitUpdates(); finish(); } }; public boolean isEmpty() { return (mCursor.getCount() == 0); } public Cursor getItemForView(View view) { int index = mListView.getPositionForView(view); if (index < 0) { return null; } return (Cursor) mListView.getAdapter().getItem(index); } }