com.dwdesign.tweetings.activity.HomeActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.dwdesign.tweetings.activity.HomeActivity.java

Source

/*
 *            Tweetings - Twitter client for Android
 * 
 * Copyright (C) 2012-2013 RBD Solutions Limited <apps@tweetings.net>
 * Copyright (C) 2012 Mariotaku Lee <mariotaku.lee@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.dwdesign.tweetings.activity;

import static com.dwdesign.tweetings.util.Utils.cleanDatabasesByItemLimit;
import static com.dwdesign.tweetings.util.Utils.getNewestMessageIdsFromDatabase;
import static com.dwdesign.tweetings.util.Utils.getNewestStatusIdsFromDatabase;
import static com.dwdesign.tweetings.util.Utils.getAccountIds;
import static com.dwdesign.tweetings.util.Utils.getActivatedAccountIds;
import static com.dwdesign.tweetings.util.Utils.getTabs;
import static com.dwdesign.tweetings.util.Utils.openDirectMessagesConversation;
import static com.dwdesign.tweetings.util.Utils.haveNetworkConnection;

import twitter4j.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.dwdesign.actionbarcompat.ActionBar;
import com.dwdesign.tweetings.R;
import com.dwdesign.tweetings.adapter.TabsAdapter;
import com.dwdesign.tweetings.app.TweetingsApplication;
import com.dwdesign.tweetings.fragment.AccountsFragment;
import com.dwdesign.tweetings.fragment.DirectMessagesFragment;
import com.dwdesign.tweetings.fragment.HomeTimelineFragment;
import com.dwdesign.tweetings.fragment.ListsFragment;
import com.dwdesign.tweetings.fragment.MentionsFragment;
import com.dwdesign.tweetings.fragment.SearchFragment;
import com.dwdesign.tweetings.model.DraftItem;
import com.dwdesign.tweetings.model.TabSpec;
import com.dwdesign.tweetings.provider.TweetStore;
import com.dwdesign.tweetings.provider.TweetStore.Accounts;
import com.dwdesign.tweetings.provider.TweetStore.DirectMessages.Inbox;
import com.dwdesign.tweetings.provider.TweetStore.DirectMessages;
import com.dwdesign.tweetings.provider.TweetStore.Drafts;
import com.dwdesign.tweetings.provider.TweetStore.Mentions;
import com.dwdesign.tweetings.provider.TweetStore.Statuses;
import com.dwdesign.tweetings.util.ArrayUtils;
import com.dwdesign.tweetings.util.ServiceInterface;
import com.dwdesign.tweetings.util.SetHomeButtonEnabledAccessor;
import com.dwdesign.tweetings.view.ExtendedViewPager;
import com.dwdesign.tweetings.view.TabPageIndicator;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.backup.BackupManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentManagerTrojan;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Toast;

@TargetApi(16)
public class HomeActivity extends MultiSelectActivity implements OnClickListener, OnPageChangeListener {

    private SharedPreferences mPreferences;
    private ServiceInterface mService;
    private TweetingsApplication mApplication;

    private ActionBar mActionBar;
    private TabsAdapter mAdapter;

    private ExtendedViewPager mViewPager;
    private ImageButton mComposeButton;
    private TabPageIndicator mIndicator;
    private ProgressBar mProgress;

    private boolean mProgressBarIndeterminateVisible = false;

    private boolean mIsNavigateToDefaultAccount = false;
    private boolean mDisplayAppIcon;
    private boolean mPushNotifications = false;

    public static final int TAB_POSITION_HOME = 0;

    public static final int TAB_POSITION_MENTIONS = 1;
    public static final int TAB_POSITION_MESSAGES = 2;
    public static final int TAB_POSITION_SEARCH = 3;
    public static final int TAB_POSITION_LISTS = 4;
    private final ArrayList<TabSpec> mCustomTabs = new ArrayList<TabSpec>();

    protected boolean refresh_on_start;
    protected Bundle bundle;

    protected int initial_tab;

    protected BackupManager backupManager;

    protected TwitterStream twitterStream;
    protected static long[] friendsList;

    protected boolean hasStreamLoaded = false;
    private boolean mStreaming = false;

    private boolean mShowHomeTab, mShowMentionsTab, mShowMessagesTab, mShowSearchTab, mShowAccountsTab,
            mShowListsTab;

    public static String BROADCAST_STATUS_RECEIVED = "com.dwdesign.tweetings.broadcast.STATUS_RECEIVED";

    private final BroadcastReceiver mStateReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(final Context context, final Intent intent) {

            final String action = intent.getAction();
            if (BROADCAST_REFRESHSTATE_CHANGED.equals(action)) {
                setSupportProgressBarIndeterminateVisibility(mProgressBarIndeterminateVisible);
            } else if (WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION.equals(action)) {
                if (intent.getBooleanExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, false)) {
                    // We have a wifi connection
                    connectToStream();
                } else {
                    // Lost Wifi connection
                    closeStream();
                }
            } else if (BROADCAST_NETWORK_STATE_CHANGED.equals(action)) {
                if (haveNetworkConnection(HomeActivity.this)) {
                    checkAndSendFailedTweets();
                }
            } else if (BROADCAST_ACCOUNT_LIST_DATABASE_UPDATED.equals(action)) {
                mPreferences.edit().putInt(PREFERENCE_KEY_SAVED_TAB_POSITION, mViewPager.getCurrentItem()).commit();
                restart();
            } else if (BROADCAST_TABS_NEW_TWEETS.equals(action)) {
                int tab = intent.getIntExtra(INTENT_KEY_UPDATE_TAB, -1);
                final int activated_color = getResources().getColor(R.color.holo_blue_light);
                Drawable icon = null;
                int tabPosition = -1;
                switch (tab) {
                case TAB_HOME: {
                    tabPosition = TAB_POSITION_HOME;
                    break;
                }
                case TAB_MENTIONS: {
                    tabPosition = TAB_POSITION_MENTIONS;
                    break;
                }
                case TAB_DIRECT_MESSAGES: {
                    tabPosition = TAB_POSITION_MENTIONS;
                    break;
                }
                default:
                    break;
                }
                if (tabPosition >= 0) {
                    icon = mAdapter.getIcon(tabPosition).mutate();
                    icon.setColorFilter(activated_color, Mode.MULTIPLY);
                    mAdapter.setIcon(tabPosition, icon);
                }
                mAdapter.notifyDataSetChanged();
            } else if (BROADCAST_TABS_READ_TWEETS.equals(action)) {
                int tab = intent.getIntExtra(INTENT_KEY_UPDATE_TAB, -1);
                Drawable icon = null;
                int tabPosition = -1;
                switch (tab) {
                case TAB_HOME: {
                    tabPosition = TAB_POSITION_HOME;
                    break;
                }
                case TAB_MENTIONS: {
                    tabPosition = TAB_POSITION_MENTIONS;
                    break;
                }
                case TAB_DIRECT_MESSAGES: {
                    tabPosition = TAB_POSITION_MENTIONS;
                    break;
                }
                default:
                    break;
                }
                if (tabPosition >= 0) {
                    icon = mAdapter.getIcon(tabPosition).mutate();
                    icon.clearColorFilter();
                    mAdapter.setIcon(tabPosition, icon);
                }
                mAdapter.notifyDataSetChanged();
            }
        }

    };

    private final BroadcastReceiver mStateReceiver2 = new BroadcastReceiver() {

        @Override
        public void onReceive(final Context context, final Intent intent) {

            final String action = intent.getAction();
            if (BROADCAST_BACKGROUND_CHANGED.equals(action)) {
                boolean isBackground = intent.getBooleanExtra(INTENT_KEY_BACKGROUND, false);
                if (isBackground) {
                    closeStream();
                } else {
                    if (refresh_on_start) {
                        refreshOnResume();
                    }
                    connectToStream();
                }
            }
        }

    };

    public boolean checkDefaultAccountSet() {
        boolean result = true;
        final long[] activated_ids = getActivatedAccountIds(this);
        final long default_account_id = mPreferences.getLong(PREFERENCE_KEY_DEFAULT_ACCOUNT_ID, -1);
        if (default_account_id == -1 || !ArrayUtils.contains(activated_ids, default_account_id)) {
            if (activated_ids.length == 1) {
                mPreferences.edit().putLong(PREFERENCE_KEY_DEFAULT_ACCOUNT_ID, activated_ids[0]).commit();
                if (mIndicator != null) {
                    mIndicator.setPagingEnabled(true);
                }
                mIsNavigateToDefaultAccount = false;
            } else if (activated_ids.length > 1) {
                final int count = mAdapter.getCount();
                if (count > 0) {
                    mViewPager.setCurrentItem(count - 1, false);
                }
                if (mIndicator != null) {
                    mIndicator.setPagingEnabled(false);
                }
                if (!mIsNavigateToDefaultAccount) {
                    Toast.makeText(this, R.string.set_default_account_hint, Toast.LENGTH_LONG).show();
                }
                mIsNavigateToDefaultAccount = true;
                result = false;
            }
        } else {
            mIndicator.setPagingEnabled(true);
            mIsNavigateToDefaultAccount = false;
        }
        return result;
    }

    @Override
    public void onBackPressed() {
        final FragmentManager fm = getSupportFragmentManager();
        if (fm.getBackStackEntryCount() == 0
                && !mPreferences.getBoolean(PREFERENCE_KEY_STOP_SERVICE_AFTER_CLOSED, false)
                && mPreferences.getBoolean(PREFERENCE_KEY_KEEP_IN_BACKGROUND, false)) {
            moveTaskToBack(true);
            return;
        }
        super.onBackPressed();
    }

    @Override
    public void onBackStackChanged() {
        super.onBackStackChanged();
        if (!isDualPaneMode())
            return;
        final FragmentManager fm = getSupportFragmentManager();
        final Fragment left_pane_fragment = fm.findFragmentById(PANE_LEFT);
        final boolean left_pane_used = left_pane_fragment != null && left_pane_fragment.isAdded();
        setPagingEnabled(!left_pane_used);
        final int count = fm.getBackStackEntryCount();
        if (count == 0) {
            bringLeftPaneToFront();
        }
        invalidateSupportOptionsMenu();
    }

    @Override
    public void onClick(final View v) {
        switch (v.getId()) {
        case R.id.compose:
        case R.id.button_compose:
            if (mViewPager == null)
                return;
            final int position = mViewPager.getCurrentItem();

            if (position == mAdapter.getCount() - 1 && mShowAccountsTab) {
                startActivity(new Intent(INTENT_ACTION_TWITTER_LOGIN));
            } else {
                int messagesPosition = TAB_POSITION_MESSAGES;
                if (mShowHomeTab == false) {
                    messagesPosition--;
                }
                if (mShowMentionsTab == false) {
                    messagesPosition--;
                }
                if (mShowMessagesTab && position == messagesPosition) {
                    openDirectMessagesConversation(this, -1, -1);
                } else {
                    startActivity(new Intent(INTENT_ACTION_COMPOSE));
                }
            }
            break;
        }
    }

    @Override
    public void onContentChanged() {
        super.onContentChanged();
        mViewPager = (ExtendedViewPager) findViewById(R.id.pager);
        mComposeButton = (ImageButton) findViewById(R.id.button_compose);
    }

    public void refreshOnResume() {
        mService.refreshAll();
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(final Bundle savedInstanceState) {
        mApplication = getTweetingsApplication();
        mService = mApplication.getServiceInterface();
        mPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE);
        super.onCreate(savedInstanceState);
        sendBroadcast(new Intent(BROADCAST_APPLICATION_LAUNCHED));
        final Resources res = getResources();
        mDisplayAppIcon = res.getBoolean(R.bool.home_display_icon);
        final long[] account_ids = getAccountIds(this);
        if (account_ids.length <= 0) {
            startActivity(new Intent(INTENT_ACTION_TWITTER_LOGIN));
            finish();
            return;
        }
        refresh_on_start = mPreferences.getBoolean(PREFERENCE_KEY_REFRESH_ON_START, true);
        bundle = getIntent().getExtras();
        initial_tab = -1;
        mActionBar = getSupportActionBar();
        mActionBar.setCustomView(R.layout.base_tabs);
        mActionBar.setDisplayShowTitleEnabled(false);
        mActionBar.setDisplayShowCustomEnabled(true);
        mActionBar.setDisplayShowHomeEnabled(mDisplayAppIcon);
        if (mDisplayAppIcon && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            SetHomeButtonEnabledAccessor.setHomeButtonEnabled(this, true);
        }
        final View view = mActionBar.getCustomView();

        mProgress = (ProgressBar) view.findViewById(android.R.id.progress);
        mIndicator = (TabPageIndicator) view.findViewById(android.R.id.tabs);
        boolean tab_display_label = res.getBoolean(R.bool.tab_display_label);
        boolean tab_hide_label_always = mPreferences.getBoolean(PREFERENCE_KEY_HIDE_TAB_LABEL, false);
        boolean tab_display_label_always = mPreferences.getBoolean(PREFERENCE_KEY_DISPLAY_TAB_LABEL, false);
        if (tab_display_label_always == true) {
            tab_display_label = true;
        } else if (tab_hide_label_always == true) {
            tab_display_label = false;
        }
        mAdapter = new TabsAdapter(this, getSupportFragmentManager(), mIndicator);
        mAdapter.setDisplayLabel(tab_display_label);
        mShowHomeTab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_HOME_TAB, true);
        mShowMentionsTab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_MENTIONS_TAB, true);
        mShowMessagesTab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_MESSAGES_TAB, true);
        mShowSearchTab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_SEARCH_TAB, true);
        mShowListsTab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_LISTS_TAB, true);
        mShowAccountsTab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_ACCOUNTS_TAB, true);
        initTabs(getTabs(this));
        mViewPager.setAdapter(mAdapter);
        mViewPager.setOffscreenPageLimit(3);
        mIndicator.setViewPager(mViewPager);
        mIndicator.setOnPageChangeListener(this);
        getSupportFragmentManager().addOnBackStackChangedListener(this);

        final boolean remember_position = mPreferences.getBoolean(PREFERENCE_KEY_REMEMBER_POSITION, true);
        final long[] activated_ids = getActivatedAccountIds(this);
        if (activated_ids.length <= 0) {
            startActivityForResult(new Intent(INTENT_ACTION_SELECT_ACCOUNT), REQUEST_SELECT_ACCOUNT);
        } else if (checkDefaultAccountSet() && (remember_position || initial_tab >= 0)) {
            final int position = initial_tab >= 0 ? initial_tab
                    : mPreferences.getInt(PREFERENCE_KEY_SAVED_TAB_POSITION, TAB_POSITION_HOME);
            if (position >= 0 || position < mViewPager.getChildCount()) {
                mViewPager.setCurrentItem(position);
            }
        }
        if (refresh_on_start && savedInstanceState == null) {
            mService.getHomeTimelineWithSinceId(activated_ids, null,
                    getNewestStatusIdsFromDatabase(this, Statuses.CONTENT_URI));
            mService.getMentionsWithSinceId(account_ids, null,
                    getNewestStatusIdsFromDatabase(this, Mentions.CONTENT_URI));
            mService.getReceivedDirectMessagesWithSinceId(activated_ids, null,
                    getNewestMessageIdsFromDatabase(this, Inbox.CONTENT_URI));
            //mService.getReceivedDirectMessages(activated_ids, null);

            //mService.getSentDirectMessages(account_ids, null);
        }

        if (!mPreferences.getBoolean(PREFERENCE_KEY_FOLLOW_DIALOG, false)) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(getString(R.string.follow_dialog_title));
            builder.setMessage(getString(R.string.follow_dialog));
            builder.setCancelable(true);
            builder.setPositiveButton(getString(R.string.follow), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int id) {
                    mPreferences.edit().putBoolean(PREFERENCE_KEY_FOLLOW_DIALOG, true).commit();
                    final long[] activated_ids = getActivatedAccountIds(mApplication);
                    for (final long account_id : activated_ids) {
                        mService.createFriendship(account_id, 41573166);
                    }
                }
            });
            builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int id) {
                    mPreferences.edit().putBoolean(PREFERENCE_KEY_FOLLOW_DIALOG, true).commit();
                }
            });
            //
            AlertDialog alert = builder.create();
            alert.show();
        }

        mStreaming = mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_ENABLED, false);
        mPushNotifications = mPreferences.getBoolean(PREFERENCE_KEY_PUSH_NOTIFICATIONS, false);
        backupManager = new BackupManager(getApplicationContext());
        final IntentFilter filter = new IntentFilter(BROADCAST_BACKGROUND_CHANGED);
        registerReceiver(mStateReceiver2, filter);

    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        menu.clear();
        getMenuInflater().inflate(R.menu.menu_home, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
        case MENU_HOME: {
            final FragmentManager fm = getSupportFragmentManager();
            if (isDualPaneMode() && !FragmentManagerTrojan.isStateSaved(fm)) {
                final int count = fm.getBackStackEntryCount();
                for (int i = 0; i < count; i++) {
                    fm.popBackStackImmediate();
                }
                setSupportProgressBarIndeterminateVisibility(false);
            }
            break;
        }
        case MENU_COMPOSE: {
            if (mComposeButton != null) {
                onClick(mComposeButton);
            }
            break;
        }
        case MENU_SEARCH: {
            onSearchRequested();
            break;
        }
        case MENU_SELECT_ACCOUNT: {
            startActivityForResult(new Intent(INTENT_ACTION_SELECT_ACCOUNT), REQUEST_SELECT_ACCOUNT);
            break;
        }
        case MENU_SETTINGS: {
            startActivity(new Intent(INTENT_ACTION_SETTINGS));
            break;
        }
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {

    }

    @Override
    public void onPageScrollStateChanged(final int state) {

    }

    @Override
    public void onPageSelected(final int position) {
        switch (position) {
        case TAB_POSITION_HOME: {
            mService.clearNotification(NOTIFICATION_ID_HOME_TIMELINE);
            break;
        }
        case TAB_POSITION_MENTIONS: {
            mService.clearNotification(NOTIFICATION_ID_MENTIONS);
            break;
        }
        case TAB_POSITION_MESSAGES: {
            mService.clearNotification(NOTIFICATION_ID_DIRECT_MESSAGES);
            break;
        }
        }
        invalidateSupportOptionsMenu();
    }

    @Override
    public boolean onPrepareOptionsMenu(final Menu menu) {
        final boolean bottom_actions = mPreferences.getBoolean(PREFERENCE_KEY_COMPOSE_BUTTON, false);
        final boolean leftside_compose_button = mPreferences.getBoolean(PREFERENCE_KEY_LEFTSIDE_COMPOSE_BUTTON,
                false);
        int icon = R.drawable.ic_menu_tweet, title = R.string.compose;
        if (mViewPager != null && mAdapter != null) {
            final int position = mViewPager.getCurrentItem();
            int messagesPosition = TAB_POSITION_MESSAGES;
            if (mShowHomeTab == false) {
                messagesPosition--;
            }
            if (mShowMentionsTab == false) {
                messagesPosition--;
            }
            if (position == mAdapter.getCount() - 1 && mShowAccountsTab) {
                icon = R.drawable.ic_menu_add;
                title = R.string.add_account;
            } else {
                title = R.string.compose;
                if (mShowMessagesTab && position == messagesPosition) {
                    icon = R.drawable.ic_menu_compose;
                } else {
                    icon = R.drawable.ic_menu_tweet;
                }
            }
            final MenuItem composeItem = menu.findItem(MENU_COMPOSE);
            if (composeItem != null) {
                composeItem.setIcon(icon);
                composeItem.setTitle(title);
                composeItem.setVisible(!bottom_actions && mViewPager.getVisibility() == View.VISIBLE);
            }
            if (mComposeButton != null) {
                mComposeButton.setImageResource(icon);
                mComposeButton.setVisibility(
                        bottom_actions && mViewPager.getVisibility() == View.VISIBLE ? View.VISIBLE : View.GONE);
                if (bottom_actions) {
                    final FrameLayout.LayoutParams compose_lp = (FrameLayout.LayoutParams) mComposeButton
                            .getLayoutParams();
                    compose_lp.gravity = Gravity.BOTTOM | (leftside_compose_button ? Gravity.LEFT : Gravity.RIGHT);
                    mComposeButton.setLayoutParams(compose_lp);
                }
            }
        }
        return super.onPrepareOptionsMenu(menu);
    }

    @Override
    public void onResume() {
        super.onResume();
        invalidateSupportOptionsMenu();

        NotificationManager notificationManager = (NotificationManager) this
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancelAll();

        if (!hasStreamLoaded || isStreamChanged()) {
            hasStreamLoaded = false;
            connectToStream();
        }

        if (isPushChanged() && mPushNotifications) {
            mApplication.registerPush();
        }

    }

    private boolean isStreamChanged() {
        final boolean streaming = mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_ENABLED, false);
        return mStreaming != streaming;
    }

    private boolean isPushChanged() {
        final boolean push_notifications = mPreferences.getBoolean(PREFERENCE_KEY_PUSH_NOTIFICATIONS, false);
        return mPushNotifications != push_notifications;
    }

    public void checkAndSendFailedTweets() {
        if (mPreferences.getBoolean(PREFERENCE_KEY_AUTOMATIC_RETRY, false)) {
            ContentResolver mResolver = getContentResolver();

            final String[] cols = Drafts.COLUMNS;
            final Cursor cur = getContentResolver().query(Drafts.CONTENT_URI, cols, null, null, null);
            if (cur != null) {
                cur.moveToFirst();
                int i = 0;
                while (!cur.isAfterLast()) {
                    final DraftItem draft = new DraftItem(cur, i);

                    if (draft.is_queued) {
                        final Uri image_uri = draft.media_uri == null ? null : Uri.parse(draft.media_uri);

                        mService.updateStatus(draft.account_ids, draft.text, null, image_uri,
                                draft.in_reply_to_status_id, draft.is_possibly_sensitive,
                                draft.is_photo_attached && !draft.is_image_attached);

                        mResolver.delete(Drafts.CONTENT_URI, Drafts._ID + " = " + draft._id, null);
                    }

                    i++;
                    cur.moveToNext();
                }
                cur.close();
            }
        }
    }

    public void connectToStream() {
        if (mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_ENABLED, false) == true) {
            if (mService != null && twitterStream != null) {
                try {
                    // user() method internally creates a thread which manipulates TwitterStream and calls these adequate listener methods continuously.
                    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                    if (cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI) != null) {
                        if (cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) {
                            hasStreamLoaded = true;
                            twitterStream.user();
                            if (mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_NOTIFICATION, false) == true) {
                                NotificationManager notificationManager = (NotificationManager) getSystemService(
                                        Context.NOTIFICATION_SERVICE);
                                final Intent intent = new Intent(this, HomeActivity.class);
                                final Notification.Builder builder = new Notification.Builder(this);
                                builder.setOngoing(true);
                                builder.setContentIntent(PendingIntent.getActivity(this, 0, intent,
                                        PendingIntent.FLAG_UPDATE_CURRENT));
                                builder.setSmallIcon(R.drawable.ic_launcher);
                                builder.setContentTitle(getString(R.string.app_name));
                                builder.setContentText(getString(R.string.streaming_service_running));
                                builder.setTicker(getString(R.string.streaming_service_running));
                                notificationManager.notify(NOTIFICATION_ID_STREAMING, builder.build());
                            }
                        }
                    }
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void closeStream() {
        if (mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_ENABLED, false) == true) {
            if (mService != null && twitterStream != null) {
                try {
                    twitterStream.shutdown();
                    if (mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_NOTIFICATION, false) == true) {
                        NotificationManager notificationManager = (NotificationManager) getSystemService(
                                Context.NOTIFICATION_SERVICE);
                        notificationManager.cancel(NOTIFICATION_ID_STREAMING);
                    }
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

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

    public boolean isStreamActive() {
        if (mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_ENABLED, false) == true) {
            if (mService != null && twitterStream != null) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void setSupportProgressBarIndeterminateVisibility(final boolean visible) {
        mProgressBarIndeterminateVisible = visible;
        mProgress.setVisibility(visible || mService.hasActivatedTask() ? View.VISIBLE : View.INVISIBLE);
    }

    @Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
        final ContentResolver resolver = getContentResolver();
        ContentValues values;
        switch (requestCode) {
        case REQUEST_SELECT_ACCOUNT: {
            if (resultCode == RESULT_OK) {
                if (intent == null || intent.getExtras() == null) {
                    break;
                }
                final Bundle bundle = intent.getExtras();
                if (bundle == null) {
                    break;
                }
                final long[] account_ids = bundle.getLongArray(INTENT_KEY_IDS);
                if (account_ids != null) {
                    values = new ContentValues();
                    values.put(Accounts.IS_ACTIVATED, 0);
                    resolver.update(Accounts.CONTENT_URI, values, null, null);
                    values = new ContentValues();
                    values.put(Accounts.IS_ACTIVATED, 1);
                    for (final long account_id : account_ids) {
                        final String where = Accounts.USER_ID + " = " + account_id;
                        resolver.update(Accounts.CONTENT_URI, values, where, null);
                    }
                }
                checkDefaultAccountSet();
            } else if (resultCode == RESULT_CANCELED) {
                if (getActivatedAccountIds(this).length <= 0) {
                    finish();
                } else {
                    checkDefaultAccountSet();
                }
            }
            break;
        }
        }
        super.onActivityResult(requestCode, resultCode, intent);
    }

    protected void onDefaultAccountSet() {
        mIsNavigateToDefaultAccount = false;
    }

    @Override
    protected void onDestroy() {
        // Delete unused items in databases.
        try {
            unregisterReceiver(mStateReceiver2);
        } catch (IllegalArgumentException e) {

        }
        closeStream();

        cleanDatabasesByItemLimit(this);
        sendBroadcast(new Intent(BROADCAST_APPLICATION_QUITTED));
        super.onDestroy();
        if (mPreferences.getBoolean(PREFERENCE_KEY_STOP_SERVICE_AFTER_CLOSED, false)) {
            // What the f**k are you think about? Stop service causes tweetings
            // slow and unstable!
            // Well, all right... If you still want to enable this option, I
            // take no responsibility for any problems occurred.
            mService.shutdownService();
        }
    }

    @Override
    protected void onNewIntent(final Intent intent) {
        final Bundle bundle = intent.getExtras();
        if (bundle != null) {
            final long[] refreshed_ids = bundle.getLongArray(INTENT_KEY_IDS);
            final int initial_tab = bundle.getInt(INTENT_KEY_INITIAL_TAB, -1);
            if (initial_tab != -1 && mViewPager != null) {
                switch (initial_tab) {
                case TAB_POSITION_HOME: {
                    mService.clearNotification(NOTIFICATION_ID_HOME_TIMELINE);
                    break;
                }
                case TAB_POSITION_MENTIONS: {
                    mService.clearNotification(NOTIFICATION_ID_MENTIONS);
                    break;
                }
                case TAB_POSITION_MESSAGES: {
                    mService.clearNotification(NOTIFICATION_ID_DIRECT_MESSAGES);
                    break;
                }
                }
                if (initial_tab >= 0 || initial_tab < mViewPager.getChildCount()) {
                    mViewPager.setCurrentItem(initial_tab);
                }
            }
            if (refreshed_ids != null) {
                mService.getHomeTimelineWithSinceId(refreshed_ids, null,
                        getNewestStatusIdsFromDatabase(this, Statuses.CONTENT_URI));
                mService.getMentionsWithSinceId(refreshed_ids, null,
                        getNewestStatusIdsFromDatabase(this, Mentions.CONTENT_URI));
                mService.getReceivedDirectMessagesWithSinceId(refreshed_ids, null,
                        getNewestMessageIdsFromDatabase(this, Inbox.CONTENT_URI));
                //mService.getReceivedDirectMessages(refreshed_ids, null);
            }

        }
        super.onNewIntent(intent);
    }

    @Override
    public void onStart() {
        super.onStart();
        setSupportProgressBarIndeterminateVisibility(mProgressBarIndeterminateVisible);
        final IntentFilter filter = new IntentFilter(BROADCAST_REFRESHSTATE_CHANGED);
        filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
        filter.addAction(BROADCAST_NETWORK_STATE_CHANGED);
        filter.addAction(BROADCAST_TABS_NEW_TWEETS);
        filter.addAction(BROADCAST_TABS_READ_TWEETS);
        filter.addAction(BROADCAST_ACCOUNT_LIST_DATABASE_UPDATED);
        registerReceiver(mStateReceiver, filter);
        final boolean show_home_tab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_HOME_TAB, true);
        final boolean show_mentions_tab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_MENTIONS_TAB, true);
        final boolean show_messages_tab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_MESSAGES_TAB, true);
        final boolean show_accounts_tab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_ACCOUNTS_TAB, true);
        final boolean show_search_tab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_SEARCH_TAB, true);
        final boolean show_lists_tab = mPreferences.getBoolean(PREFERENCE_KEY_SHOW_LISTS_TAB, true);

        final List<TabSpec> tabs = getTabs(this);
        if (isTabsChanged(tabs) || show_home_tab != mShowHomeTab || show_mentions_tab != mShowMentionsTab
                || show_messages_tab != mShowMessagesTab || show_accounts_tab != mShowAccountsTab
                || show_search_tab != mShowSearchTab || show_lists_tab != mShowListsTab) {
            restart();
        }
        if (mPreferences.getBoolean(PREFERENCE_KEY_STREAMING_ENABLED, false) == true) {

            if (mService != null) {
                try {
                    Twitter twitter = com.dwdesign.tweetings.util.Utils
                            .getDefaultTwitterInstance(getApplicationContext(), true);
                    twitterStream = new TwitterStreamFactory().getInstance(twitter.getAuthorization());
                    twitterStream.addListener(listener);
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onStop() {
        unregisterReceiver(mStateReceiver);
        mPreferences.edit().putInt(PREFERENCE_KEY_SAVED_TAB_POSITION, mViewPager.getCurrentItem()).commit();
        super.onStop();
    }

    protected void setPagingEnabled(final boolean enabled) {
        if (mIndicator != null) {
            mIndicator.setPagingEnabled(enabled);
            mIndicator.setEnabled(enabled);
        }
    }

    private void initTabs(final Collection<? extends TabSpec> tabs) {
        mCustomTabs.clear();
        mCustomTabs.addAll(tabs);
        mAdapter.clear();
        if (mShowHomeTab) {
            mAdapter.addTab(HomeTimelineFragment.class, null, getString(R.string.home), R.drawable.ic_tab_home,
                    TAB_POSITION_HOME);
        }
        if (mShowMentionsTab) {
            mAdapter.addTab(MentionsFragment.class, null, getString(R.string.mentions), R.drawable.ic_tab_mention,
                    TAB_POSITION_MENTIONS);
        }
        if (mShowMessagesTab) {
            mAdapter.addTab(DirectMessagesFragment.class, null, getString(R.string.direct_messages),
                    R.drawable.ic_tab_message, TAB_POSITION_MESSAGES);
        }
        if (mShowSearchTab) {
            mAdapter.addTab(SearchFragment.class, null, getString(R.string.search), R.drawable.ic_tab_search,
                    TAB_POSITION_SEARCH);
        }
        if (mShowListsTab) {
            mAdapter.addTab(ListsFragment.class, null, getString(R.string.lists), R.drawable.ic_tab_list,
                    TAB_POSITION_LISTS);
        }
        mAdapter.addTabs(tabs);
        if (mShowAccountsTab) {
            mAdapter.addTab(AccountsFragment.class, null, getString(R.string.accounts), R.drawable.ic_tab_accounts,
                    mAdapter.getCount());
        }

    }

    private boolean isTabsChanged(final List<TabSpec> tabs) {
        if (mCustomTabs.size() == 0 && tabs == null)
            return false;
        if (mCustomTabs.size() != tabs.size())
            return true;
        final int size = mCustomTabs.size();
        for (int i = 0; i < size; i++) {
            if (!mCustomTabs.get(i).equals(tabs.get(i)))
                return true;
        }
        return false;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (mPreferences.getBoolean(PREFERENCE_KEY_VOLUME_NAVIGATION, false)) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                switch (event.getKeyCode()) {
                case KeyEvent.KEYCODE_VOLUME_UP: {
                    Intent broadcast = new Intent();
                    broadcast.setAction(BROADCAST_VOLUME_UP);
                    sendBroadcast(broadcast);
                    //scrollToPrevious();
                    return true;
                }
                case KeyEvent.KEYCODE_VOLUME_DOWN: {
                    Intent broadcast = new Intent();
                    broadcast.setAction(BROADCAST_VOLUME_DOWN);
                    sendBroadcast(broadcast);
                    //scrollToNext();
                    return true;
                }
                }
            }
            if (event.getAction() == KeyEvent.ACTION_UP && (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP
                    || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN)) {
                return true;
            }
        }
        return super.dispatchKeyEvent(event);
    }

    @Override
    int getDualPaneLayoutRes() {
        return R.layout.home_dual_pane;
    }

    @Override
    int getNormalLayoutRes() {
        return R.layout.home;
    }

    UserStreamListener listener = new UserStreamListener() {

        @Override
        public void onStatus(Status status) {
            //System.out.println("onStatus @" + status.getUser().getScreenName() + " - " + status.getText());
            final long account_id = com.dwdesign.tweetings.util.Utils.getDefaultAccountId(HomeActivity.this);
            final String screen_name = com.dwdesign.tweetings.util.Utils
                    .getAccountUsername(HomeActivity.this, account_id).toLowerCase();
            boolean followingUser = false;
            for (long friendId : friendsList) {
                // Is the user in the list of users someone follows
                if (friendId == status.getUser().getId()) {
                    followingUser = true;
                    break;
                }
            }
            // Is the tweet the user's own
            if (status.getUser().getId() == account_id) {
                followingUser = true;
            }

            // Delivery to home timeline
            if (followingUser == true) {
                // We have a home timeline tweet
                Intent broadcast = new Intent();
                broadcast.putExtra("status", status);
                broadcast.setAction(BROADCAST_STREAM_STATUS_RECEIVED);

                HomeActivity.this.mService.insertStreamToHomeTimeline(account_id, broadcast);
            }

            // Check for mentions
            if (status.getText().toLowerCase().contains("@" + screen_name)) {
                // We've found @screenName but now we need to check it's not @screenNameSomethingElse
                /*int position = status.getText().toLowerCase().indexOf("@" + screen_name);
                int tweetLength = status.getText().length();
                boolean deliverToMentions = false;
                if (position > 0) { 
                   // +1 for the @ symbol
                   int nextCharacterPosition = position + screen_name.length() + 1;
                   // +1 as position starts at 0
                   if (nextCharacterPosition + 1 >= tweetLength) {
                 // OK we are at the end of the tweet, that's fine
                 deliverToMentions = true;
                   }
                   else {
                 String charAtPosition = status.getText().toLowerCase().substring(nextCharacterPosition, nextCharacterPosition + 1);
                 if (charAtPosition.equals(" ") || charAtPosition.equals("\n") || charAtPosition.equals("\t") || charAtPosition.equals(".") || charAtPosition.equals(",") || charAtPosition.equals("?")
                       || charAtPosition.equals("!") || charAtPosition.equals(";") || charAtPosition.equals(":")) {
                    deliverToMentions = true;
                 }
                   }
                       
                }
                if (deliverToMentions == true) {*/
                Intent broadcast = new Intent();
                broadcast.putExtra("status", status);
                broadcast.setAction(BROADCAST_STREAM_STATUS_RECEIVED);

                HomeActivity.this.mService.insertStreamToMentions(account_id, broadcast);
                //}
            }

        }

        @Override
        public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) {
            final Intent intent = new Intent(BROADCAST_STATUS_DESTROYED);
            final long status_id = statusDeletionNotice.getStatusId();

            final StringBuilder where = new StringBuilder();
            where.append(Statuses.STATUS_ID + " = " + status_id);
            where.append(" OR " + Statuses.RETWEET_ID + " = " + status_id);
            for (final Uri uri : TweetStore.STATUSES_URIS) {
                getContentResolver().delete(uri, where.toString(), null);
            }
            intent.putExtra(INTENT_KEY_STATUS_ID, status_id);
            intent.putExtra(INTENT_KEY_SUCCEED, true);

            sendBroadcast(intent);
        }

        @Override
        public void onDeletionNotice(long directMessageId, long userId) {
            final String where = DirectMessages.MESSAGE_ID + " = " + directMessageId;

            getContentResolver().delete(DirectMessages.Inbox.CONTENT_URI, where, null);
            getContentResolver().delete(DirectMessages.Outbox.CONTENT_URI, where, null);
        }

        @Override
        public void onTrackLimitationNotice(int numberOfLimitedStatuses) {

        }

        @Override
        public void onScrubGeo(long userId, long upToStatusId) {
        }

        @Override
        public void onStallWarning(StallWarning warning) {
        }

        @Override
        public void onFriendList(long[] friendIds) {
            friendsList = friendIds;
        }

        public void onFavorite(User source, User target, Status favoritedStatus) {
        }

        public void onUnfavorite(User source, User target, Status unfavoritedStatus) {
        }

        public void onFollow(User source, User followedUser) {
            long[] toAppend = { source.getId() };
            long[] tmp = new long[friendsList.length + toAppend.length];
            System.arraycopy(friendsList, 0, tmp, 0, friendsList.length);
            System.arraycopy(toAppend, 0, tmp, friendsList.length, toAppend.length);

            friendsList = tmp;
        }

        public void onRetweet(User source, User target, Status retweetedStatus) {
        }

        public void onDirectMessage(DirectMessage directMessage) {
            Intent broadcast = new Intent();
            broadcast.putExtra("status", directMessage);
            broadcast.setAction(BROADCAST_STREAM_STATUS_RECEIVED);
            final long account_id = com.dwdesign.tweetings.util.Utils.getDefaultAccountId(HomeActivity.this);
            HomeActivity.this.mService.insertStreamToInbox(account_id, broadcast);
        }

        public void onUserListMemberAddition(User addedMember, User listOwner, UserList list) {
        }

        public void onUserListMemberDeletion(User deletedMember, User listOwner, UserList list) {
        }

        public void onUserListSubscription(User subscriber, User listOwner, UserList list) {
        }

        public void onUserListUnsubscription(User subscriber, User listOwner, UserList list) {
        }

        public void onUserListCreation(User listOwner, UserList list) {
        }

        public void onUserListUpdate(User listOwner, UserList list) {
        }

        public void onUserListDeletion(User listOwner, UserList list) {
        }

        public void onUserProfileUpdate(User updatedUser) {
        }

        public void onBlock(User source, User blockedUser) {
        }

        public void onUnblock(User source, User unblockedUser) {
        }

        public void onException(Exception ex) {
            ex.printStackTrace();
            System.out.println("onException:" + ex.getMessage());
        }
    };

}