Android Open Source - CampusUB1 Events Activity






From Project

Back to project page CampusUB1.

License

The source code is released under:

Apache License

If you think the Android project CampusUB1 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2013 CampusUB1 Development Team
 *//from  w ww .j  a v  a2s .  co  m
 * 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.dev.campus.event;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;

import android.app.ActionBar;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

import com.dev.campus.CampusUB1App;
import com.dev.campus.R;
import com.dev.campus.SettingsActivity;
import com.dev.campus.util.FilterDialog;
import com.slidingmenu.lib.SlidingMenu;
import com.slidingmenu.lib.app.SlidingListActivity;

/**
 * Class responsible for the events activity UI and lifecycle,
 * handles saving, loading and updating events feeds.
 * 
 * @author CampusUB1 Development Team
 *
 */
public class EventsActivity extends SlidingListActivity implements OnItemClickListener {

  // Extra keys
  public static final String EXTRA_EVENTS = "com.dev.campus.EVENTS";
  public static final String EXTRA_EVENTS_INDEX = "com.dev.campus.EVENTS_POSITION";
  public static final String EXTRA_EVENTS_RESULT = "com.dev.campus.EXTRA_EVENTS_RESULT";
  public static final int REQUEST_CODE = 1;

  // Footer action bar filters
  private boolean mShowUpcomingEvents = false;
  private boolean mShowStarredEvents = false;
  private boolean mShowUnreadOnly = false;

  // Current category and related data
  private Category mCategory;
  private ArrayList<Event> mEvents;
  private ArrayList<Event> mSortedEvents;
  private ArrayList<Date> mBuildDates;

  // Utilities
  private EventAdapter mEventAdapter;
  private EventParser mEventParser;
  private FilterDialog mFilterDialog;
  private MenuItem mRefreshMenuItem;
  private SlidingMenu mSlidingMenu;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mFilterDialog = new FilterDialog(this);
    mEventParser = new EventParser();
    mCategory = Category.MAIN_EVENTS; // Initial category

    setupActionBar();
    setupSlidingMenu();
    setupListAdapter();
  }

  /**
   * Initializes the top custom ActionBar
   */
  private void setupActionBar() {
    ActionBar actionBar = getActionBar();
    actionBar.setSplitBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.holo_dark_black)));
    actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME
                                 | ActionBar.DISPLAY_SHOW_CUSTOM);
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View customActionBarView = inflater.inflate(R.layout.custom_actionbar, null);
    customActionBarView.findViewById(R.id.menu_settings).setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        startActivity(new Intent(EventsActivity.this, SettingsActivity.class));
      }
    });
    customActionBarView.findViewById(R.id.menu_filters).setOnClickListener(new OnClickListener() {

      @Override
      public void onClick(View v) {
        mFilterDialog.showDialog();
      }
    });
    actionBar.setCustomView(customActionBarView);
  }

  /**
   * Initializes the category sliding menu.
   */
  private void setupSlidingMenu() {
    // Initialize parameters
    mSlidingMenu = getSlidingMenu();
    mSlidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
    mSlidingMenu.setShadowWidthRes(R.dimen.shadow_width);
    mSlidingMenu.setShadowDrawable(R.drawable.shadow);
    mSlidingMenu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
    mSlidingMenu.setFadeDegree(0.35f);
    setSlidingActionBarEnabled(false);

    // Create and populate a Category adapter
    ArrayList<Category> categories = new ArrayList<Category>();
    categories.addAll(Arrays.asList(Category.values()));
    ArrayAdapter<Category> adapter = new ArrayAdapter<Category>(this, R.layout.slidemenu_list_item, categories);

    // Assign adapter to slide_menu list view
    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View slideMenu = inflater.inflate(R.layout.slide_menu, null);
    ListView menuView = (ListView) slideMenu.findViewById(R.id.slide_menu);
    menuView.setAdapter(adapter);

    menuView.setItemChecked(0, true);
    menuView.setOnItemClickListener(new OnItemClickListener() {

      @Override
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        saveEvents();
        mCategory = (Category) parent.getItemAtPosition(position);
        clearContent();
        update();
        mSlidingMenu.showContent();
      }
    });

    setBehindContentView(menuView);
  }
  
  /**
   * Initializes the list adapter in charge of displaying
   * and populating event items.
   */
  private void setupListAdapter() {
    mEventAdapter = new EventAdapter(this, new ArrayList<Event>());
    ListView listView = getListView();
    listView.setOnItemClickListener(this);
    listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    listView.setMultiChoiceModeListener(new EventMultiChoiceModeListener(listView));
    listView.setAdapter(mEventAdapter);
  }

  @Override
  public void onPause() {
    saveEvents();
    super.onPause();
  }

  @Override
  public void onBackPressed() {
    if (mSlidingMenu.isMenuShowing())
      mSlidingMenu.showContent();
    else
      super.onBackPressed();
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.actionbar_footer, menu);
    mRefreshMenuItem = menu.findItem(R.id.menu_refresh);
    mSlidingMenu.showMenu();
    /* Delayed call to update method until getting a reference
    to mRefreshMenuItem */
    update();
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_refresh:
      saveEvents();
      update();
      mSlidingMenu.showContent();
      return true;

    case android.R.id.home:
      if (mSlidingMenu.isMenuShowing())
        mSlidingMenu.showContent();
      else
        finish();
      return true;
      
    case R.id.checkbox_show_starred_events:
      if (item.isChecked()) {
        item.setIcon(R.drawable.ic_half_star);
        item.setChecked(false);
        Toast.makeText(this, R.string.showing_all_events, Toast.LENGTH_SHORT).show();
      } else {
        item.setIcon(R.drawable.ic_star_highlight);
        item.setChecked(true);
        Toast.makeText(this, R.string.showing_starred_events, Toast.LENGTH_SHORT).show();
      }
      mShowStarredEvents = item.isChecked();
      reloadContent();
      mSlidingMenu.showContent();
      return true;

    case R.id.checkbox_show_unread_only:
      if (item.isChecked()) {
        item.setIcon(R.drawable.ic_content_read);
        item.setChecked(false);
        Toast.makeText(this, R.string.showing_all_events, Toast.LENGTH_SHORT).show();
      } else {
        item.setIcon(R.drawable.ic_content_unread_highlight);
        item.setChecked(true);
        Toast.makeText(this, R.string.showing_unread_events, Toast.LENGTH_SHORT).show();
      }
      mShowUnreadOnly = item.isChecked();
      reloadContent();
      mSlidingMenu.showContent();
      return true;

    case R.id.checkbox_show_upcoming_events:
      if (item.isChecked()) {
        item.setIcon(R.drawable.btn_check_off_holo_light);
        item.setChecked(false);
        Toast.makeText(this, R.string.showing_all_events, Toast.LENGTH_SHORT).show();
      } else {
        item.setIcon(R.drawable.btn_check_on_holo_light);
        item.setChecked(true);
        Toast.makeText(this, R.string.showing_upcoming_events, Toast.LENGTH_SHORT).show();
      }
      mShowUpcomingEvents = item.isChecked();
      reloadContent();
      mSlidingMenu.showContent();
      return true;

    default:
      return super.onOptionsItemSelected(item);
    }
  }

  /**
   * Sorts the list of displayed events based on current activated filters
   */
  private void sortEvents() {
    ArrayList<Event> sortedEvents = new ArrayList<Event>();
    if (mEvents != null) {
      for (Event event : mEvents) {
        if (event.getSource().isFiltered() &&
           (!mShowUpcomingEvents || (mShowUpcomingEvents && event.getStartDate().getTime() >= System.currentTimeMillis())) &&
           (!mShowUnreadOnly   || (mShowUnreadOnly && !event.isRead())) &&
           (!mShowStarredEvents || (mShowStarredEvents && event.isStarred()))) {
          sortedEvents.add(event);
        }
      }
    }
    Collections.sort(sortedEvents, new Event.EventComparator());
    mSortedEvents = sortedEvents;
  }

  /**
   * Clears all items from the adapter view
   */
  public void clearContent() {
    mEventAdapter.clear();
    mEventAdapter.notifyDataSetChanged();
  }
  
  /**
   * Updates view of current items
   */
  public void reloadContent() {
    sortEvents();
    mEventAdapter.clear();
    mEventAdapter.addAll(mSortedEvents);
    mEventAdapter.notifyDataSetChanged();
  }

  /**
   * Returns a path to a history file based on current subscriptions
   */
  private String getHistoryPath() {
    int sub1 = CampusUB1App.persistence.isSubscribedUB1()? 1 : 0;
    int sub2 = CampusUB1App.persistence.isSubscribedLabri()? 1 : 0;
    return getFilesDir() + "/history_" + mCategory.hashCode() + sub1 + sub2 + ".dat";
  }
  
  /**
   * Handles the update procedure based on current connectivity state
   */
  @SuppressWarnings("unchecked")
  public void update() {
    SimpleEntry<ArrayList<Date>, ArrayList<Event>> feedsEntry = readEventsHistory();

    if (feedsEntry != null) {
      if (CampusUB1App.persistence.isConnected()) {
        new UpdateFeedsTask().execute(feedsEntry);
      } else {
        mBuildDates = feedsEntry.getKey();
        mEvents = feedsEntry.getValue();
        reloadContent();
        Toast.makeText(this, R.string.showing_history, Toast.LENGTH_SHORT).show();
      }
    }
    else {
      if (CampusUB1App.persistence.isConnected()) {
        new UpdateFeedsTask().execute();
        Toast.makeText(this, R.string.updating_events, Toast.LENGTH_SHORT).show();
      } else {
        Toast.makeText(this, R.string.connection_failed, Toast.LENGTH_SHORT).show();
      }
    }
  }

  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    Intent intent = new Intent(EventsActivity.this, EventViewActivity.class);
    intent.putExtra(EXTRA_EVENTS, mSortedEvents);
    intent.putExtra(EXTRA_EVENTS_INDEX, position);
    startActivityForResult(intent, REQUEST_CODE);
  }

  /**
   * Toggles the state of an event's star
   * @param view reference to the clicked view
   */
  public void toggleStar(View view) {
    ListView listView = getListView();
    int position = listView.getPositionForView(view);
    Event event = (Event) listView.getItemAtPosition(position);
    event.setStarred(!event.isStarred());
    mEventAdapter.notifyDataSetChanged();
  }

  @Override
  @SuppressWarnings("unchecked")
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {
      if (resultCode == RESULT_OK) {      
        ArrayList<Event> result = (ArrayList<Event>) data.getSerializableExtra(EXTRA_EVENTS_RESULT);
        // Transfer state changes to mEvents
        for (Event event : result) {
          if (event.isRead()) {
            if (mEvents.contains(event))
              mEvents.get(mEvents.indexOf(event)).setRead(true);
          }
        }
        mEventAdapter.notifyDataSetChanged();
      }
    }
  }
  
  /**
   * Worker thread responsible for fetching updates of specified category
   * and displaying them
   * @author CampusUB1 Development Team
   *
   */
  private class UpdateFeedsTask extends AsyncTask<SimpleEntry<ArrayList<Date>, ArrayList<Event>>, Void, Boolean> {

    @Override
    protected void onPreExecute() {
      mRefreshMenuItem.setActionView(R.layout.progressbar_refresh);
    }

    @Override
    protected Boolean doInBackground(SimpleEntry<ArrayList<Date>, ArrayList<Event>>... entries) {
      try {
        ArrayList<Event> existingEvents = new ArrayList<Event>(); // so far, no existing events

        //check if latest version, and update only if needed
        if (entries.length > 0 && entries[0].getKey() != null && entries[0].getValue() != null) {
          if (entries[0].getKey().size() > 0 && entries[0].getValue().size() > 0) {
            existingEvents = entries[0].getValue();
            mEvents = existingEvents;
            mBuildDates = entries[0].getKey();
            // Display existing events and continue updating task
            runOnUiThread(new Runnable() {
              @Override
              public void run() {
                reloadContent();
              }
            });
            if (mEventParser.isLatestVersion(mCategory, mBuildDates)) {
              return false;
            }
          }
        }
        mEventParser.parseEvents(mCategory, existingEvents);
        mEvents = mEventParser.getParsedEvents();
        mBuildDates = mEventParser.getParsedBuildDates();
      } catch (Exception e) {
        e.printStackTrace();
        cancel(true);
      }
      return true;
    }

    @Override
    protected void onPostExecute(Boolean needsReload) {
      if (needsReload)
        reloadContent();
      mRefreshMenuItem.setActionView(null);
    }

    @Override
    protected void onCancelled() {
      clearContent();
      mEvents.clear();
      mBuildDates.clear();
      mRefreshMenuItem.setActionView(null);
    }
  }

  /**
   * Reads list of events from device memory
   * @return saved data if found, else returns null
   */
  @SuppressWarnings("unchecked")
  private SimpleEntry<ArrayList<Date>, ArrayList<Event>> readEventsHistory() {
    File file = new File(getHistoryPath());
    SimpleEntry<ArrayList<Date>, ArrayList<Event>> feedsEntry = null;

    if (file.exists()) {
      try {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        feedsEntry = (SimpleEntry<ArrayList<Date>, ArrayList<Event>>) ois.readObject();
        ois.close();
      } catch (Exception e) { 
        e.printStackTrace();
      }
    }
    return feedsEntry;
  }

  /**
   * Writes list of events to device memory
   */
  public void saveEvents() {
    ObjectOutputStream oos = null;
    try {
      File history = new File(getHistoryPath());
      history.getParentFile().createNewFile();
      FileOutputStream fout = new FileOutputStream(history);
      oos = new ObjectOutputStream(fout);
      SimpleEntry<ArrayList<Date>, ArrayList<Event>> map = new SimpleEntry<ArrayList<Date>, ArrayList<Event>>(mBuildDates, mEvents);
      oos.writeObject(map);
    } catch (FileNotFoundException ex) {
      ex.printStackTrace();  
    } catch (IOException ex) {
      ex.printStackTrace();
    } finally {
      try {
        if (oos != null) {
          oos.flush();
          oos.close();
        }
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    }
  }

}




Java Source Code List

android.UnusedStub.java
com.dev.campus.CampusUB1App.java
com.dev.campus.LauncherActivity.java
com.dev.campus.SettingsActivity.java
com.dev.campus.directory.Contact.java
com.dev.campus.directory.DirectoryActivity.java
com.dev.campus.directory.DirectoryAdapter.java
com.dev.campus.directory.DirectoryManager.java
com.dev.campus.event.Category.java
com.dev.campus.event.EventAdapter.java
com.dev.campus.event.EventFragment.java
com.dev.campus.event.EventMultiChoiceModeListener.java
com.dev.campus.event.EventPagerAdapter.java
com.dev.campus.event.EventParser.java
com.dev.campus.event.EventViewActivity.java
com.dev.campus.event.Event.java
com.dev.campus.event.EventsActivity.java
com.dev.campus.event.Feed.java
com.dev.campus.home.HomeActivity.java
com.dev.campus.home.HomeAdapter.java
com.dev.campus.home.HomeEntryItem.java
com.dev.campus.home.HomeItem.java
com.dev.campus.home.HomeSeparatorItem.java
com.dev.campus.map.MapActivity.java
com.dev.campus.map.Position.java
com.dev.campus.schedule.Group.java
com.dev.campus.schedule.ScheduleActivity.java
com.dev.campus.schedule.ScheduleAdapter.java
com.dev.campus.schedule.ScheduleImportService.java
com.dev.campus.schedule.ScheduleParser.java
com.dev.campus.util.AboutDialog.java
com.dev.campus.util.FilterDialog.java
com.dev.campus.util.Persistence.java
com.dev.campus.util.PrefFragment.java
com.dev.campus.util.SubscribeDialog.java
com.dev.campus.util.TimeExtractor.java
com.dev.campus.util.UpcomingEventsDialog.java
com.slidingmenu.lib.CanvasTransformerBuilder.java
com.slidingmenu.lib.CustomViewAbove.java
com.slidingmenu.lib.CustomViewBehind.java
com.slidingmenu.lib.MenuInterface.java
com.slidingmenu.lib.SlidingMenu.java
com.slidingmenu.lib.app.SlidingActivityBase.java
com.slidingmenu.lib.app.SlidingActivityHelper.java
com.slidingmenu.lib.app.SlidingActivity.java
com.slidingmenu.lib.app.SlidingFragmentActivity.java
com.slidingmenu.lib.app.SlidingListActivity.java
com.slidingmenu.lib.app.SlidingMapActivity.java
com.slidingmenu.lib.app.SlidingPreferenceActivity.java