2 * Copyright (C) 2006 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.calendar;
19 import static android.provider.Calendar.EVENT_BEGIN_TIME;
20 import dalvik.system.VMRuntime;
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.preference.PreferenceManager;
33 import android.provider.Calendar.Events;
34 import android.text.format.DateUtils;
35 import android.text.format.Time;
36 import android.view.KeyEvent;
37 import android.view.Menu;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.view.animation.Animation;
41 import android.view.animation.AnimationUtils;
42 import android.view.animation.Animation.AnimationListener;
43 import android.widget.ProgressBar;
44 import android.widget.TextView;
45 import android.widget.ViewSwitcher;
46 import android.widget.Gallery.LayoutParams;
48 import java.util.Calendar;
50 public class MonthActivity extends Activity implements ViewSwitcher.ViewFactory,
51 Navigator, AnimationListener {
52 private static final int INITIAL_HEAP_SIZE = 4 * 1024 * 1024;
53 private Animation mInAnimationPast;
54 private Animation mInAnimationFuture;
55 private Animation mOutAnimationPast;
56 private Animation mOutAnimationFuture;
57 private ViewSwitcher mSwitcher;
60 private ContentResolver mContentResolver;
61 EventLoader mEventLoader;
62 private int mStartDay;
64 private ProgressBar mProgressBar;
66 protected void startProgressSpinner() {
67 // start the progress spinner
68 mProgressBar.setVisibility(View.VISIBLE);
71 protected void stopProgressSpinner() {
72 // stop the progress spinner
73 mProgressBar.setVisibility(View.GONE);
76 /* ViewSwitcher.ViewFactory interface methods */
77 public View makeView() {
78 MonthView mv = new MonthView(this, this);
79 mv.setLayoutParams(new ViewSwitcher.LayoutParams(
80 LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
81 mv.setSelectedTime(mTime);
85 /* Navigator interface methods */
86 public void goTo(Time time) {
87 TextView title = (TextView) findViewById(R.id.title);
88 title.setText(Utils.formatMonthYear(time));
90 MonthView current = (MonthView) mSwitcher.getCurrentView();
91 current.dismissPopup();
93 Time currentTime = current.getTime();
95 // Compute a month number that is monotonically increasing for any
96 // two adjacent months.
97 // This is faster than calling getSelectedTime() because we avoid
98 // a call to Time#normalize().
99 int currentMonth = currentTime.month + currentTime.year * 12;
100 int nextMonth = time.month + time.year * 12;
101 if (nextMonth < currentMonth) {
102 mSwitcher.setInAnimation(mInAnimationPast);
103 mSwitcher.setOutAnimation(mOutAnimationPast);
105 mSwitcher.setInAnimation(mInAnimationFuture);
106 mSwitcher.setOutAnimation(mOutAnimationFuture);
109 MonthView next = (MonthView) mSwitcher.getNextView();
110 next.setSelectionMode(current.getSelectionMode());
111 next.setSelectedTime(time);
113 next.animationStarted();
114 mSwitcher.showNext();
119 public void goToToday() {
120 Time now = new Time();
121 now.set(System.currentTimeMillis());
123 TextView title = (TextView) findViewById(R.id.title);
124 title.setText(Utils.formatMonthYear(now));
127 MonthView view = (MonthView) mSwitcher.getCurrentView();
128 view.setSelectedTime(now);
132 public long getSelectedTime() {
133 MonthView mv = (MonthView) mSwitcher.getCurrentView();
134 return mv.getSelectedTimeInMillis();
137 public boolean getAllDay() {
145 void eventsChanged() {
146 MonthView view = (MonthView) mSwitcher.getCurrentView();
151 * Listens for intent broadcasts
153 private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
155 public void onReceive(Context context, Intent intent) {
156 String action = intent.getAction();
157 if (action.equals(Intent.ACTION_TIME_CHANGED)
158 || action.equals(Intent.ACTION_DATE_CHANGED)
159 || action.equals(Intent.ACTION_TIMEZONE_CHANGED)) {
165 // Create an observer so that we can update the views whenever a
166 // Calendar event changes.
167 private ContentObserver mObserver = new ContentObserver(new Handler())
170 public boolean deliverSelfNotifications() {
175 public void onChange(boolean selfChange) {
180 public void onAnimationStart(Animation animation) {
183 // Notifies the MonthView when an animation has finished.
184 public void onAnimationEnd(Animation animation) {
185 MonthView monthView = (MonthView) mSwitcher.getCurrentView();
186 monthView.animationFinished();
189 public void onAnimationRepeat(Animation animation) {
193 protected void onCreate(Bundle icicle) {
194 super.onCreate(icicle);
196 // Eliminate extra GCs during startup by setting the initial heap size to 4MB.
197 // TODO: We should restore the old heap size once the activity reaches the idle state
198 VMRuntime.getRuntime().setMinimumHeapSize(INITIAL_HEAP_SIZE);
200 setContentView(R.layout.month_activity);
201 mContentResolver = getContentResolver();
204 if (icicle != null) {
205 time = icicle.getLong(EVENT_BEGIN_TIME);
207 time = Utils.timeFromIntentInMillis(getIntent());
212 mTime.normalize(true);
214 // Get first day of week based on locale and populate the day headers
215 mStartDay = Calendar.getInstance().getFirstDayOfWeek();
216 int diff = mStartDay - Calendar.SUNDAY - 1;
218 String dayString = DateUtils.getDayOfWeekString((Calendar.SUNDAY + diff) % 7 + 1,
219 DateUtils.LENGTH_MEDIUM);
220 ((TextView) findViewById(R.id.day0)).setText(dayString);
221 dayString = DateUtils.getDayOfWeekString((Calendar.MONDAY + diff) % 7 + 1,
222 DateUtils.LENGTH_MEDIUM);
223 ((TextView) findViewById(R.id.day1)).setText(dayString);
224 dayString = DateUtils.getDayOfWeekString((Calendar.TUESDAY + diff) % 7 + 1,
225 DateUtils.LENGTH_MEDIUM);
226 ((TextView) findViewById(R.id.day2)).setText(dayString);
227 dayString = DateUtils.getDayOfWeekString((Calendar.WEDNESDAY + diff) % 7 + 1,
228 DateUtils.LENGTH_MEDIUM);
229 ((TextView) findViewById(R.id.day3)).setText(dayString);
230 dayString = DateUtils.getDayOfWeekString((Calendar.THURSDAY + diff) % 7 + 1,
231 DateUtils.LENGTH_MEDIUM);
232 ((TextView) findViewById(R.id.day4)).setText(dayString);
233 dayString = DateUtils.getDayOfWeekString((Calendar.FRIDAY + diff) % 7 + 1,
234 DateUtils.LENGTH_MEDIUM);
235 ((TextView) findViewById(R.id.day5)).setText(dayString);
236 dayString = DateUtils.getDayOfWeekString((Calendar.SATURDAY + diff) % 7 + 1,
237 DateUtils.LENGTH_MEDIUM);
238 ((TextView) findViewById(R.id.day6)).setText(dayString);
240 // Set the initial title
241 TextView title = (TextView) findViewById(R.id.title);
242 title.setText(Utils.formatMonthYear(mTime));
244 mEventLoader = new EventLoader(this);
245 mProgressBar = (ProgressBar) findViewById(R.id.progress_circular);
247 mSwitcher = (ViewSwitcher) findViewById(R.id.switcher);
248 mSwitcher.setFactory(this);
249 mSwitcher.getCurrentView().requestFocus();
251 mInAnimationPast = AnimationUtils.loadAnimation(this, R.anim.slide_down_in);
252 mOutAnimationPast = AnimationUtils.loadAnimation(this, R.anim.slide_down_out);
253 mInAnimationFuture = AnimationUtils.loadAnimation(this, R.anim.slide_up_in);
254 mOutAnimationFuture = AnimationUtils.loadAnimation(this, R.anim.slide_up_out);
256 mInAnimationPast.setAnimationListener(this);
257 mInAnimationFuture.setAnimationListener(this);
261 protected void onNewIntent(Intent intent) {
262 long timeMillis = Utils.timeFromIntentInMillis(intent);
263 if (timeMillis > 0) {
264 Time time = new Time();
265 time.set(timeMillis);
271 protected void onPause() {
274 mEventLoader.stopBackgroundThread();
276 mContentResolver.unregisterContentObserver(mObserver);
277 unregisterReceiver(mIntentReceiver);
279 MonthView view = (MonthView) mSwitcher.getCurrentView();
281 view = (MonthView) mSwitcher.getNextView();
283 mEventLoader.stopBackgroundThread();
287 protected void onResume() {
289 mEventLoader.startBackgroundThread();
292 MonthView view1 = (MonthView) mSwitcher.getCurrentView();
293 MonthView view2 = (MonthView) mSwitcher.getNextView();
294 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
295 String str = prefs.getString(CalendarPreferenceActivity.KEY_DETAILED_VIEW,
296 CalendarPreferenceActivity.DEFAULT_DETAILED_VIEW);
297 view1.setDetailedView(str);
298 view2.setDetailedView(str);
300 // Record Month View as the (new) start view
301 String activityString = CalendarApplication.ACTIVITY_NAMES[CalendarApplication.MONTH_VIEW_ID];
302 SharedPreferences.Editor editor = prefs.edit();
303 editor.putString(CalendarPreferenceActivity.KEY_START_VIEW, activityString);
306 // Register for Intent broadcasts
307 IntentFilter filter = new IntentFilter();
309 filter.addAction(Intent.ACTION_TIME_CHANGED);
310 filter.addAction(Intent.ACTION_DATE_CHANGED);
311 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
312 registerReceiver(mIntentReceiver, filter);
314 mContentResolver.registerContentObserver(Events.CONTENT_URI,
319 protected void onSaveInstanceState(Bundle outState) {
320 super.onSaveInstanceState(outState);
321 outState.putLong(EVENT_BEGIN_TIME, mTime.toMillis(true));
325 public boolean onKeyDown(int keyCode, KeyEvent event) {
327 case KeyEvent.KEYCODE_BACK:
331 return super.onKeyDown(keyCode, event);
335 public boolean onPrepareOptionsMenu(Menu menu) {
336 MenuHelper.onPrepareOptionsMenu(this, menu);
337 return super.onPrepareOptionsMenu(menu);
341 public boolean onCreateOptionsMenu(Menu menu) {
342 MenuHelper.onCreateOptionsMenu(menu);
343 return super.onCreateOptionsMenu(menu);
347 public boolean onOptionsItemSelected(MenuItem item) {
348 MenuHelper.onOptionsItemSelected(this, item, this);
349 return super.onOptionsItemSelected(item);