Home | History | Annotate | Download | only in calendar
      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;
     18 
     19 import static android.provider.Calendar.EVENT_BEGIN_TIME;
     20 import dalvik.system.VMRuntime;
     21 
     22 import android.app.Activity;
     23 import android.content.BroadcastReceiver;
     24 import android.content.ContentResolver;
     25 import android.content.Context;
     26 import android.content.Intent;
     27 import android.content.IntentFilter;
     28 import android.content.SharedPreferences;
     29 import android.database.ContentObserver;
     30 import android.os.Bundle;
     31 import android.os.Handler;
     32 import android.provider.Calendar.Events;
     33 import android.text.TextUtils;
     34 import android.text.format.DateFormat;
     35 import android.text.format.DateUtils;
     36 import android.text.format.Time;
     37 import android.util.Log;
     38 import android.view.KeyEvent;
     39 import android.view.Menu;
     40 import android.view.MenuItem;
     41 
     42 import java.util.Locale;
     43 import java.util.TimeZone;
     44 
     45 public class AgendaActivity extends Activity implements Navigator {
     46 
     47     private static final String TAG = "AgendaActivity";
     48 
     49     private static boolean DEBUG = false;
     50 
     51     protected static final String BUNDLE_KEY_RESTORE_TIME = "key_restore_time";
     52 
     53     private static final long INITIAL_HEAP_SIZE = 4*1024*1024;
     54 
     55     private ContentResolver mContentResolver;
     56 
     57     private AgendaListView mAgendaListView;
     58 
     59     private Time mTime;
     60 
     61     private String mTitle;
     62 
     63     // This gets run if the time zone is updated in the db
     64     private Runnable mUpdateTZ = new Runnable() {
     65         @Override
     66         public void run() {
     67             long time = mTime.toMillis(true);
     68             mTime = new Time(Utils.getTimeZone(AgendaActivity.this, this));
     69             mTime.set(time);
     70             updateTitle();
     71         }
     72     };
     73 
     74     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
     75         @Override
     76         public void onReceive(Context context, Intent intent) {
     77             String action = intent.getAction();
     78             if (action.equals(Intent.ACTION_TIME_CHANGED)
     79                     || action.equals(Intent.ACTION_DATE_CHANGED)
     80                     || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
     81                 mAgendaListView.refresh(true);
     82             }
     83         }
     84     };
     85 
     86     private ContentObserver mObserver = new ContentObserver(new Handler()) {
     87         @Override
     88         public boolean deliverSelfNotifications() {
     89             return true;
     90         }
     91 
     92         @Override
     93         public void onChange(boolean selfChange) {
     94             mAgendaListView.refresh(true);
     95         }
     96     };
     97 
     98     @Override
     99     protected void onCreate(Bundle icicle) {
    100         super.onCreate(icicle);
    101 
    102         // Eliminate extra GCs during startup by setting the initial heap size to 4MB.
    103         // TODO: We should restore the old heap size once the activity reaches the idle state
    104         VMRuntime.getRuntime().setMinimumHeapSize(INITIAL_HEAP_SIZE);
    105 
    106         mAgendaListView = new AgendaListView(this);
    107         setContentView(mAgendaListView);
    108 
    109         mContentResolver = getContentResolver();
    110 
    111         mTitle = getResources().getString(R.string.agenda_view);
    112 
    113         long millis = 0;
    114         mTime = new Time(Utils.getTimeZone(this, mUpdateTZ));
    115         if (icicle != null) {
    116             // Returns 0 if key not found
    117             millis = icicle.getLong(BUNDLE_KEY_RESTORE_TIME);
    118             if (DEBUG) {
    119                 Log.v(TAG, "Restore value from icicle: " + millis);
    120             }
    121         }
    122 
    123         if (millis == 0) {
    124             // Returns 0 if key not found
    125             millis = getIntent().getLongExtra(EVENT_BEGIN_TIME, 0);
    126             if (DEBUG) {
    127                 Time time = new Time();
    128                 time.set(millis);
    129                 Log.v(TAG, "Restore value from intent: " + time.toString());
    130             }
    131         }
    132 
    133         if (millis == 0) {
    134             if (DEBUG) {
    135                 Log.v(TAG, "Restored from current time");
    136             }
    137             millis = System.currentTimeMillis();
    138         }
    139         mTime.set(millis);
    140         updateTitle();
    141     }
    142 
    143     private void updateTitle() {
    144         StringBuilder title = new StringBuilder(mTitle);
    145         String tz = Utils.getTimeZone(this, mUpdateTZ);
    146         if (!TextUtils.equals(tz, Time.getCurrentTimezone())) {
    147             int flags = DateUtils.FORMAT_SHOW_TIME;
    148             if (DateFormat.is24HourFormat(this)) {
    149                 flags |= DateUtils.FORMAT_24HOUR;
    150             }
    151             boolean isDST = mTime.isDst != 0;
    152             long start = System.currentTimeMillis();
    153             TimeZone timeZone = TimeZone.getTimeZone(tz);
    154             title.append(" (").append(Utils.formatDateRange(this, start, start, flags)).append(" ")
    155                     .append(timeZone.getDisplayName(isDST, TimeZone.SHORT, Locale.getDefault()))
    156                     .append(")");
    157         }
    158         setTitle(title.toString());
    159     }
    160 
    161     @Override
    162     protected void onNewIntent(Intent intent) {
    163         long time = Utils.timeFromIntentInMillis(intent);
    164         if (time > 0) {
    165             mTime.set(time);
    166             goTo(mTime, false);
    167         }
    168     }
    169 
    170     @Override
    171     protected void onResume() {
    172         super.onResume();
    173         if (DEBUG) {
    174             Log.v(TAG, "OnResume to " + mTime.toString());
    175         }
    176 
    177         SharedPreferences prefs = CalendarPreferenceActivity.getSharedPreferences(
    178                 getApplicationContext());
    179         boolean hideDeclined = prefs.getBoolean(
    180                 CalendarPreferenceActivity.KEY_HIDE_DECLINED, false);
    181 
    182         mAgendaListView.setHideDeclinedEvents(hideDeclined);
    183         mAgendaListView.goTo(mTime, true);
    184         mAgendaListView.onResume();
    185 
    186         // Register for Intent broadcasts
    187         IntentFilter filter = new IntentFilter();
    188         filter.addAction(Intent.ACTION_TIME_CHANGED);
    189         filter.addAction(Intent.ACTION_DATE_CHANGED);
    190         filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
    191         registerReceiver(mIntentReceiver, filter);
    192 
    193         mContentResolver.registerContentObserver(Events.CONTENT_URI, true, mObserver);
    194         mUpdateTZ.run();
    195 
    196         // Record Agenda View as the (new) default detailed view.
    197         Utils.setDefaultView(this, CalendarApplication.AGENDA_VIEW_ID);
    198     }
    199 
    200     @Override
    201     protected void onSaveInstanceState(Bundle outState) {
    202         super.onSaveInstanceState(outState);
    203 
    204         long firstVisibleTime = mAgendaListView.getFirstVisibleTime();
    205         if (firstVisibleTime > 0) {
    206             mTime.set(firstVisibleTime);
    207             outState.putLong(BUNDLE_KEY_RESTORE_TIME, firstVisibleTime);
    208             if (DEBUG) {
    209                 Log.v(TAG, "onSaveInstanceState " + mTime.toString());
    210             }
    211         }
    212     }
    213 
    214     @Override
    215     protected void onPause() {
    216         super.onPause();
    217 
    218         mAgendaListView.onPause();
    219         mContentResolver.unregisterContentObserver(mObserver);
    220         unregisterReceiver(mIntentReceiver);
    221     }
    222 
    223     @Override
    224     public boolean onPrepareOptionsMenu(Menu menu) {
    225         MenuHelper.onPrepareOptionsMenu(this, menu);
    226         return super.onPrepareOptionsMenu(menu);
    227     }
    228 
    229     @Override
    230     public boolean onCreateOptionsMenu(Menu menu) {
    231         MenuHelper.onCreateOptionsMenu(menu);
    232         return super.onCreateOptionsMenu(menu);
    233     }
    234 
    235     @Override
    236     public boolean onOptionsItemSelected(MenuItem item) {
    237         MenuHelper.onOptionsItemSelected(this, item, this);
    238         return super.onOptionsItemSelected(item);
    239     }
    240 
    241     @Override
    242     public boolean onKeyDown(int keyCode, KeyEvent event) {
    243         switch (keyCode) {
    244             case KeyEvent.KEYCODE_DEL:
    245                 // Delete the currently selected event (if any)
    246                 mAgendaListView.deleteSelectedEvent();
    247                 break;
    248         }
    249         return super.onKeyDown(keyCode, event);
    250     }
    251 
    252     /* Navigator interface methods */
    253     public void goToToday() {
    254         Time now = new Time(Utils.getTimeZone(this, mUpdateTZ));
    255         now.setToNow();
    256         mAgendaListView.goTo(now, true); // Force refresh
    257     }
    258 
    259     public void goTo(Time time, boolean animate) {
    260         mAgendaListView.goTo(time, false);
    261     }
    262 
    263     public long getSelectedTime() {
    264         return mAgendaListView.getSelectedTime();
    265     }
    266 
    267     public boolean getAllDay() {
    268         return false;
    269     }
    270 }
    271 
    272