com.chalmers.feedlr.activity.FeedActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.chalmers.feedlr.activity.FeedActivity.java

Source

/*
 * Copyright 2012 Feedlr
 *
 * 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.chalmers.feedlr.activity;

import java.util.ArrayList;

import com.chalmers.feedlr.R;
import com.chalmers.feedlr.adapter.PageAdapter;
import com.chalmers.feedlr.adapter.UserAdapter;
import com.chalmers.feedlr.client.Clients;
import com.chalmers.feedlr.client.ClientHandler;
import com.chalmers.feedlr.database.DatabaseHelper;
import com.chalmers.feedlr.service.DataServiceHelper;
import com.chalmers.feedlr.listener.AuthListener;
import com.chalmers.feedlr.listener.FeedListener;
import com.chalmers.feedlr.model.Feed;
import com.viewpagerindicator.CirclePageIndicator;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Typeface;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewAnimator;
import android.widget.ViewFlipper;

/**
 * FeedActivity is the activity in which almost all parts of the application is
 * run. This is the default activity.
 */
public class FeedActivity extends FragmentActivity implements FeedListener {

    private DataServiceHelper feedService;
    private ClientHandler clientHandler;

    private DatabaseHelper db;

    // Twitter strings
    public static final String TWITTER_USERS_UPDATED = "com.chalmers.feedlr.TWITTER_USERS_UPDATED";
    public static final String TWITTER_USERS_PROBLEM_UPDATING = "com.chalmers.feedlr.TWITTER_USERS_PROBLEM_UPDATING";

    // Facebook strings
    public static final String FACEBOOK_TIMELINE_UPDATED = "com.chalmers.feedlr.FACEBOOK_TIMELINE_UPDATED";
    public static final String FACEBOOK_USERS_UPDATED = "com.chalmers.feedlr.FACEBOOK_USERS_UPDATED";
    public static final String FACEBOOK_USERS_PROBLEM_UPDATING = "com.chalmers.feedlr.FACEBOOK_USERS_PROBLEM_UPDATING";
    public static final String FACEBOOK_USER_NEWS_UPDATED = "com.chalmers.feedlr.FACEBOOK_USER_NEWS_UPDATED";

    public static final String FEED_UPDATED = "com.chalmers.feedlr.FEED_UPDATED";
    public static final String FEED_PROBLEM_UPDATING = "com.chalmers.feedlr.FEED_PROBLEM_UPDATING";
    public static final String NO_CONNECTION = "com.chalmers.feedlr.NO_CONNECTION";

    // Android system helpers
    private Resources res;
    private LocalBroadcastManager lbm;
    private LayoutInflater inflater;
    private IntentFilter intentFilter;

    // Adapters
    private PageAdapter feedAdapter;
    private UserAdapter userAdapter;

    // Views
    private ViewFlipper mainViewFlipper;
    private ViewPager feedViewSwiper;
    private ViewAnimator settingsViewFlipper;
    private ListView userListView;
    private LinearLayout userListLayout;

    private Button facebookAuthButton;
    private Button twitterAuthButton;

    private TextView feedTitleTextView;

    // Animations
    private Animation slideOutLeft;
    private Animation slideOutRight;
    private Animation slideInLeft;
    private Animation slideInRight;

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String broadcast = intent.getAction();

            if (broadcast.equals(TWITTER_USERS_UPDATED)) {
                userAdapter.swapCursor(db.getAllUsers());

            } else if (broadcast.equals(FACEBOOK_USERS_UPDATED)) {
                userAdapter.swapCursor(db.getAllUsers());

            } else if (broadcast.equals(TWITTER_USERS_PROBLEM_UPDATING)) {
                Toast.makeText(context,
                        "The was a problem refreshing your twitter friends. Please check your connection and try again.",
                        Toast.LENGTH_SHORT).show();

            } else if (broadcast.equals(FACEBOOK_USERS_PROBLEM_UPDATING)) {
                Toast.makeText(context,
                        "The was a problem refreshing your facebook friends. Please check your connection and try again.",
                        Toast.LENGTH_SHORT).show();
            } else if (broadcast.equals(FEED_PROBLEM_UPDATING)) {
                Toast.makeText(context,
                        "The was a problem refreshing the feed. Please check your connection and try again.",
                        Toast.LENGTH_SHORT).show();
            } else {
                Log.wtf(getClass().getName(), "broadcast from unknown intent recieved!");
            }
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_view_flipper);

        // get helpers from android system
        res = getResources();
        lbm = LocalBroadcastManager.getInstance(this);
        inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // add intent filter to be used by broadcast reciever
        intentFilter = new IntentFilter();
        intentFilter.addAction(TWITTER_USERS_UPDATED);
        intentFilter.addAction(TWITTER_USERS_PROBLEM_UPDATING);
        intentFilter.addAction(FACEBOOK_TIMELINE_UPDATED);
        intentFilter.addAction(FACEBOOK_USERS_UPDATED);
        intentFilter.addAction(FACEBOOK_USERS_PROBLEM_UPDATING);
        intentFilter.addAction(FACEBOOK_USER_NEWS_UPDATED);
        intentFilter.addAction(FEED_PROBLEM_UPDATING);

        // instanciate database helper
        db = new DatabaseHelper(this);

        // load typefaces from assets
        Typeface robotoMedium = Typeface.createFromAsset(getAssets(), "fonts/Roboto-Medium.ttf");

        // find views inflated from xml
        mainViewFlipper = (ViewFlipper) findViewById(R.id.main_view_flipper);
        feedViewSwiper = (ViewPager) findViewById(R.id.feed_view_pager);
        settingsViewFlipper = (ViewAnimator) findViewById(R.id.settings_view_flipper);

        facebookAuthButton = (Button) findViewById(R.id.button_facebook);
        twitterAuthButton = (Button) findViewById(R.id.button_twitter);
        Button cfb = (Button) findViewById(R.id.button_create_feed);
        Button s = (Button) findViewById(R.id.button_settings);
        settingsViewFlipper.getBackground().setDither(true);

        feedTitleTextView = (TextView) findViewById(R.id.feed_action_bar_title);

        // Set typefaces manually since Android can't handle custom typefaces in
        // xml in any way whatsoever. Shame on them.
        twitterAuthButton.setTypeface(robotoMedium);
        facebookAuthButton.setTypeface(robotoMedium);

        feedTitleTextView = (TextView) findViewById(R.id.feed_action_bar_title);

        cfb.setTypeface(robotoMedium);
        s.setTypeface(robotoMedium);

        feedTitleTextView.setTypeface(robotoMedium);

        // set adapters
        feedAdapter = new PageAdapter(getSupportFragmentManager(), db, this);
        feedViewSwiper.setAdapter(feedAdapter);

        // lets 3 feedsviews to each side of the current one be retained in an
        // idle state.
        feedViewSwiper.setOffscreenPageLimit(3);

        CirclePageIndicator circleIndicator = (CirclePageIndicator) findViewById(R.id.indicator);
        circleIndicator.setViewPager(feedViewSwiper);
        circleIndicator.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int feedIndex) {
                String feedTitle = feedAdapter.getFeedTitle(feedIndex);
                feedTitleTextView.setText(feedTitle);
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub'
            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub
            }
        });

        // instanciate client and service helpers
        clientHandler = new ClientHandler(this);
        feedService = new DataServiceHelper(this);
        feedService.startService();

        // load animations from res/anim
        slideOutLeft = AnimationUtils.loadAnimation(this, R.anim.slide_out_left);
        slideOutRight = AnimationUtils.loadAnimation(this, R.anim.slide_out_right);
        slideInLeft = AnimationUtils.loadAnimation(this, R.anim.slide_in_left);
        slideInRight = AnimationUtils.loadAnimation(this, R.anim.slide_in_right);

        // Display name correct
        if (feedAdapter.getCount() > 0) {
            String feedTitle = feedAdapter.getFeedTitle(0);
            feedTitleTextView.setText(feedTitle);
        }

        // misc
        settingsViewFlipper.setInAnimation(slideInRight);
        settingsViewFlipper.setOutAnimation(slideOutLeft);

        updateOverlay();
    }

    @Override
    protected void onDestroy() {
        feedService.stopService();
        super.onDestroy();
    }

    @Override
    protected void onStart() {
        super.onStart();
        feedService.bindService();
    }

    @Override
    protected void onStop() {
        feedService.unbindService();
        super.onStop();
    }

    @Override
    protected void onResume() {
        super.onResume();

        boolean isFacebookAuthorized = Clients.isAuthorized(Clients.FACEBOOK, this);
        facebookAuthButton.setText(isFacebookAuthorized ? res.getString(R.string.facebook_authorized)
                : res.getString(R.string.authorize_facebook));
        facebookAuthButton.setEnabled(!isFacebookAuthorized);
        if (isFacebookAuthorized) {
            facebookAuthButton.setTextColor(Color.parseColor("#919191"));
            facebookAuthButton.setBackgroundResource(R.drawable.facebook_logo_disabled);
        }

        boolean isTwitterAuthorized = Clients.isAuthorized(Clients.TWITTER, this);
        twitterAuthButton.setText(isTwitterAuthorized ? res.getString(R.string.twitter_authorized)
                : res.getString(R.string.authorize_twitter));
        twitterAuthButton.setEnabled(!isTwitterAuthorized);
        if (isTwitterAuthorized) {
            twitterAuthButton.setTextColor(Color.parseColor("#919191"));
            twitterAuthButton.setBackgroundResource(R.drawable.twitter_logo_disabled);
        }

        lbm.registerReceiver(receiver, intentFilter);

        // facebook kittens will die if this isn't called onResume
        clientHandler.extendFacebookAccessTokenIfNeeded();
    }

    @Override
    protected void onPause() {
        lbm.unregisterReceiver(receiver);
        super.onPause();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.feed_layout, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_settings:
            toggleSettingsView(null);
            break;
        case R.id.menu_exit:
            finish();
            break;

        }
        return true;
    }

    @Override
    public void onBackPressed() {
        // TODO: Toggle animation for the create feed view. Currently sliding
        // away in the wring direction.

        if (mainViewFlipper.getCurrentView().getId() == R.id.settings_layout) {
            if (settingsViewFlipper.getCurrentView().getId() == R.id.user_list_layout) {
                settingsViewFlipper.showPrevious();
            } else {
                toggleSettingsView(null);
            }
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
            case Clients.TWITTER:
                clientHandler.onTwitterAuthCallback(data);
                break;
            case Clients.FACEBOOK:
                clientHandler.onFacebookAuthCallback(requestCode, resultCode, data);
                break;
            default:
                Log.wtf(getClass().getName(), "Result callback from unknown intent");
            }
        }
    }

    @Override
    public void onFeedUpdateRequest(String feedTitle) {
        if (isOnline()) {
            feedService.updateFeed(new Feed(feedTitle));
        } else {
            Intent intent = new Intent();
            intent.setAction(NO_CONNECTION);
            lbm.sendBroadcast(intent);
        }
    }

    public boolean isOnline() {
        ConnectivityManager cm;
        NetworkInfo info = null;

        try {
            cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            info = cm.getActiveNetworkInfo();
        } catch (Exception e) {
            Log.e("Check connection", e.getMessage());
        }

        if (info != null) {
            return info.isConnected();
        } else {
            return false;
        }
    }

    // Methods called on button press below. See xml files.

    public void toggleSettingsView(View v) {
        int currentView = mainViewFlipper.getCurrentView().getId();

        if (currentView == R.id.main_layout) {
            mainViewFlipper.setInAnimation(slideInLeft);
            mainViewFlipper.setOutAnimation(slideOutRight);
            mainViewFlipper.showNext();
        } else {
            mainViewFlipper.setInAnimation(slideInRight);
            mainViewFlipper.setOutAnimation(slideOutLeft);
            mainViewFlipper.showPrevious();
        }
    }

    public void initCreateFeedView(View v) {
        userListLayout = (LinearLayout) inflater.inflate(R.layout.user_list_layout, null);
        userListView = (ListView) userListLayout.findViewById(R.id.user_list_view);

        if (isOnline()) {
            feedService.updateUsers();
        } else {
            Intent intent = new Intent();
            intent.setAction(NO_CONNECTION);
            lbm.sendBroadcast(intent);
        }

        Cursor cursor = db.getAllUsers();

        String[] columns = new String[] { DatabaseHelper.USER_COLUMN_USERNAME, DatabaseHelper.USER_COLUMN_USERID,
                DatabaseHelper.USER_COLUMN_SOURCE };
        int[] to = new int[] { R.id.user_item_text_view };

        userAdapter = new UserAdapter(this, R.layout.user_list_item, cursor, columns, to,
                CursorAdapter.NO_SELECTION);

        userListView.setAdapter(userAdapter);

        settingsViewFlipper.addView(userListLayout);
        settingsViewFlipper.showNext();
    }

    public void createFeed(View button) {

        // Animate switch to main view
        toggleSettingsView(null);

        // Extract new feed title
        EditText titleEditText = (EditText) userListLayout.findViewById(R.id.create_feed_action_bar_title);
        String feedTitle = titleEditText.getText().toString();
        Feed feed = new Feed(feedTitle);

        // Extract new feed users
        SparseBooleanArray checked = userListView.getCheckedItemPositions();
        ArrayList<Integer> userIDs = new ArrayList<Integer>();

        UserAdapter adapter = (UserAdapter) userListView.getAdapter();

        Cursor c;
        for (int i = 0; i < adapter.getCount(); i++) {
            if (checked.get(i)) {
                c = (Cursor) adapter.getItem(i);
                userIDs.add(c.getInt(c.getColumnIndex(DatabaseHelper.USER_COLUMN_USERID)));
            }
        }

        // Save user list as a feed in database
        db.addFeed(feed);
        long feed_id = db.getFeed_id(feed);
        for (Integer i : userIDs)
            db.addFeedUserBridge(feed_id, i);
        Log.i(getClass().getName(), "Added feed \"" + feed.getTitle() + "\" with " + userIDs.size() + " users.");

        // Hide keyboard
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(titleEditText.getWindowToken(), 0);

        // Animate switch to new feed view
        this.feedAdapter.addFeed(feed);
        feedViewSwiper.setCurrentItem(adapter.getCount());
        feedTitleTextView.setText(feed.getTitle());

        // Remove the createFeedView
        View v = settingsViewFlipper.getCurrentView();
        settingsViewFlipper.showPrevious();
        settingsViewFlipper.removeView(v);
        userListLayout = null;
        userListView = null;

        // Check overlay
        updateOverlay();
    }

    private void updateOverlay() {
        if (feedAdapter.getCount() > 0) {
            LinearLayout overlayLayout = (LinearLayout) mainViewFlipper.findViewById(R.id.main_layout);
            ImageView overlay = (ImageView) overlayLayout.findViewById(R.id.no_feed_image);
            overlay.setVisibility(View.INVISIBLE);
        }
    }

    public void authorizeTwitter(View v) {
        if (!isOnline()) {
            return;
        }

        clientHandler.authorize(Clients.TWITTER, new AuthListener() {
            @Override
            public void onAuthorizationComplete() {
                twitterAuthButton.setText(res.getString(R.string.twitter_authorized));
                twitterAuthButton.setEnabled(false);
                twitterAuthButton.setTextColor(Color.parseColor("#919191"));
                twitterAuthButton.setBackgroundResource(R.drawable.twitter_logo_disabled);
            }

            @Override
            public void onAuthorizationFail() {
                Toast.makeText(FeedActivity.this, "Twitter authorization failed", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void authorizeFacebook(View v) {
        if (!isOnline()) {
            return;
        }

        clientHandler.authorize(Clients.FACEBOOK, new AuthListener() {
            @Override
            public void onAuthorizationComplete() {
                facebookAuthButton.setText(res.getString(R.string.facebook_authorized));
                facebookAuthButton.setEnabled(false);
                facebookAuthButton.setTextColor(Color.parseColor("#919191"));
                facebookAuthButton.setBackgroundResource(R.drawable.facebook_logo_disabled);
            }

            @Override
            public void onAuthorizationFail() {
                Toast.makeText(FeedActivity.this, "Facebook authorization failed", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void testSomething(View v) {
        // This button is for testing only. Use it for all your testing needs <3
        db.clearItemTable();
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        Window window = getWindow();
        window.setFormat(PixelFormat.RGBA_8888);
    }
}