eu.e43.impeller.activity.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for eu.e43.impeller.activity.MainActivity.java

Source

/* Copyright 2013 Owen Shepherd. A part of Impeller.
 *
 * 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 eu.e43.impeller.activity;

import java.util.Calendar;
import java.util.GregorianCalendar;

import android.accounts.Account;
import android.annotation.TargetApi;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ViewFlipper;

import eu.e43.impeller.api.Constants;
import eu.e43.impeller.api.Content;
import eu.e43.impeller.account.Authenticator;
import eu.e43.impeller.content.FeedNotificationReceiver;
import eu.e43.impeller.fragment.DrawerFragment;
import eu.e43.impeller.fragment.FeedFragment;
import eu.e43.impeller.fragment.ObjectContainerFragment;
import eu.e43.impeller.R;
import eu.e43.impeller.fragment.SplashFragment;
import eu.e43.impeller.uikit.OverlayController;

public class MainActivity extends ActivityWithAccount implements DrawerFragment.DrawerActionListener {
    static final String TAG = "MainActivity";

    private Calendar m_nextFetch = null; // Time to do next feed fetch
    private boolean m_isTablet = false; // Tablet UI mode?
    private Toolbar m_toolbar = null; // (Feed) toolbar
    private ActionBarDrawerToggle m_drawerToggle = null; // Drawer controller
    private DrawerLayout m_drawerLayout = null; // Drawer layout
    private DrawerFragment m_drawerFragment = null; // Drawer fragment
    private FeedFragment m_feedFragment = null; // Pointer to the active feed fragment (if any)
    private ObjectContainerFragment m_objectFragment = null; // Pointer to the active object fragment (if any)
    Mode m_displayMode = Mode.FEED;
    private boolean m_pendingIntent = false; // Is there an intent pending until we have an account?

    @Override
    protected void onCreateEx(Bundle savedInstanceState) {
        PreferenceManager.setDefaultValues(this, R.xml.pref_general, false);
        PreferenceManager.setDefaultValues(this, R.xml.pref_data_sync, false);
        setContentView(R.layout.activity_main);

        m_toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(m_toolbar);
        m_toolbar.inflateMenu(R.menu.main);

        m_drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        m_drawerFragment = (DrawerFragment) getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
        m_drawerToggle = new ActionBarDrawerToggle(this, m_drawerLayout, R.string.drawer_open,
                R.string.drawer_close);
        m_drawerLayout.setDrawerListener(m_drawerToggle);

        m_isTablet = "two_pane".equals(findViewById(R.id.main_activity).getTag());
        Log.v(TAG, "isTwoPane? " + (m_isTablet ? "YES" : "NO"));

        if (savedInstanceState == null) {
            getSupportActionBar().hide();
            getSupportFragmentManager().beginTransaction().add(R.id.feed_fragment, new SplashFragment())
                    .setTransition(FragmentTransaction.TRANSIT_NONE).commit();
        } else {
            m_feedFragment = (FeedFragment) getSupportFragmentManager().getFragment(savedInstanceState,
                    "feedFragment");
            m_objectFragment = (ObjectContainerFragment) getSupportFragmentManager().getFragment(savedInstanceState,
                    "objectFragment");

            setDisplayMode((Mode) savedInstanceState.getSerializable("displayMode"));
            Log.i(TAG, "Restoring in display mode " + m_displayMode.toString());
        }
    }

    @Override
    protected void queryForAccount(QueryReason reason) {
        if (reason == QueryReason.Startup) {
            SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
            Account[] accts = m_accountManager.getAccountsByType(Authenticator.ACCOUNT_TYPE);

            Account theAccount = null;
            String lastAccount = prefs.getString("lastAccount", null);
            if (lastAccount != null) {
                for (Account act : accts) {
                    if (lastAccount.equals(act.name)) {
                        theAccount = act;
                        break;
                    }
                }
            }

            if (theAccount == null) {
                if (accts.length > 0) {
                    theAccount = accts[0];
                } else {
                    super.queryForAccount(reason);
                    return;
                }
            }

            haveGotAccount(theAccount);
        } else {
            super.queryForAccount(reason);
        }
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        m_drawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        m_drawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putSerializable("displayMode", m_displayMode);

        if (m_feedFragment != null)
            getSupportFragmentManager().putFragment(outState, "feedFragment", m_feedFragment);
        if (m_objectFragment != null)
            getSupportFragmentManager().putFragment(outState, "objectFragment", m_objectFragment);
    }

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

        // Ensure notifications are up to date
        Intent startIntent = new Intent(Constants.ACTION_REFRESH_NOTIFICATIONS, null, this,
                FeedNotificationReceiver.class);
        sendBroadcast(startIntent);

        // Refresh regularly while we are displayed
        Calendar now = GregorianCalendar.getInstance();
        if (m_nextFetch == null || m_nextFetch.before(now) && m_account != null) {
            Log.v(TAG, "onStart() - requesting sync");

            getContentResolver().requestSync(m_account, Content.AUTHORITY, new Bundle());
            now.add(Calendar.MINUTE, 5);
            m_nextFetch = now;
        }
    }

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

    @Override
    protected void gotAccount(Account acct) {
        PreferenceManager.getDefaultSharedPreferences(this).edit().putString("lastAccount", acct.name).commit();

        getSupportActionBar().show();

        if (m_feedFragment == null || !acct.equals(m_feedFragment.getAccount())) {
            FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
            if (m_objectFragment != null) {
                tx.remove(m_objectFragment);
            }
            tx.replace(R.id.feed_fragment, new FeedFragment());
            tx.commit();
            setDisplayMode(Mode.FEED);
        } else
            setDisplayMode(m_displayMode);

        if (m_drawerFragment != null)
            m_drawerFragment.onAccountChanged(acct);

        if (m_pendingIntent) {
            onNewIntent(getIntent());
        }
    }

    @Override
    protected void onStartIntent(Intent startIntent) {
        onNewIntent(startIntent);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        m_pendingIntent = false;
        Log.i(TAG, "New intent " + intent);

        if (intent.hasExtra(Constants.EXTRA_ACCOUNT)) {
            haveGotAccount((Account) intent.getParcelableExtra(Constants.EXTRA_ACCOUNT));
        }

        if (m_account == null) {
            setIntent(intent);
            m_pendingIntent = true;
            return;
        }

        String action = intent.getAction();
        if (Intent.ACTION_VIEW.equals(action)) {
            Uri uri = intent.getData();
            if (uri == null)
                return;

            Uri id = null;
            if (uri.getScheme().equals("content") && uri.getHost().equals("eu.e43.impeller.content")) {
                id = Uri.parse(uri.getLastPathSegment());
            } else {
                id = uri;
            }

            setIntent(intent);
            showObjectInMode(Mode.OBJECT, id);
        } else if (Constants.ACTION_SHOW_FEED.equals(action)) {
            showFeed((Constants.FeedID) intent.getSerializableExtra(Constants.EXTRA_FEED_ID));
        } else {
            Log.d(TAG, "Unknown new intent " + intent);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (m_drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        switch (item.getItemId()) {
        case android.R.id.home:
            FragmentManager fm = getSupportFragmentManager();
            fm.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
            return true;

        case R.id.action_settings:
            startActivity(new Intent(this, SettingsActivity.class));
            return true;

        case R.id.action_about:
            startActivity(new Intent(this, AboutActivity.class));
            return true;

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

    private void setDisplayMode(Mode m) {
        View fdFrag = m_isTablet ? findViewById(R.id.feed_fragment) : findViewById(R.id.feed_container);
        View ctFrag = m_isTablet ? findViewById(R.id.content_container) : findViewById(R.id.content_fragment);

        Log.d(TAG, "Mode " + m_displayMode.toString() + " -> " + m.toString());
        if (m != m_displayMode)
            evictOverlay();

        switch (m) {
        case FEED:
            fdFrag.setVisibility(View.VISIBLE);
            ctFrag.setVisibility(View.GONE);
            break;

        case FEED_OBJECT:
            fdFrag.setVisibility(m_isTablet ? View.VISIBLE : View.GONE);
            ctFrag.setVisibility(View.VISIBLE);
            break;

        case OBJECT:
            fdFrag.setVisibility(View.GONE);
            ctFrag.setVisibility(View.VISIBLE);
            break;
        }

        m_displayMode = m;
    }

    public boolean isTwoPane() {
        return m_isTablet && m_displayMode == Mode.FEED_OBJECT;
    }

    public void showObjectInMode(Mode mode, Uri id) {
        ObjectContainerFragment objFrag = ObjectContainerFragment.newInstance(id.toString(), mode);
        FragmentManager fm = getSupportFragmentManager();
        if (m_objectFragment != null && mode == Mode.FEED_OBJECT) {
            fm.popBackStack();
        }

        FragmentTransaction txn = fm.beginTransaction();
        txn.replace(R.id.content_fragment, objFrag);
        txn.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        txn.addToBackStack(null);
        txn.commit();

        setDisplayMode(mode);
    }

    public void onAddFeedFragment(FeedFragment fFrag) {
        Log.i(TAG, "Add feed fragment");
        m_feedFragment = fFrag;

        if (m_displayMode == Mode.FEED) {
            setTitle(m_feedFragment.getFeedId().getNameString());
        }

        if (m_objectFragment != null) {
            m_feedFragment.setSelectedItem((Uri) m_objectFragment.getArguments().getParcelable("id"));
        }
    }

    public void onRemoveFeedFragment(FeedFragment fFrag) {
        Log.i(TAG, "Remove feed fragment");
        if (m_feedFragment == fFrag)
            m_feedFragment = null;
    }

    public void onShowObjectFragment(ObjectContainerFragment oFrag) {
        Log.i(TAG, "Show object fragment in mode " + oFrag.getMode() + " " + oFrag);
        m_objectFragment = oFrag;

        if (m_feedFragment != null && m_displayMode == Mode.FEED_OBJECT)
            m_feedFragment
                    .setSelectedItem(Uri.parse(oFrag.getArguments().getString(ObjectContainerFragment.PARAM_ID)));

        setDisplayMode(oFrag.getMode());
    }

    public void onHideObjectFragment(ObjectContainerFragment oFrag) {
        Log.i(TAG, "Hide object fragment " + oFrag);
        if (m_objectFragment == oFrag) {
            m_objectFragment = null;
        } else {
            return;
        }

        setDisplayMode(Mode.FEED);

        //if(m_feedFragment != null)
        //    m_feedFragment.setSelection(-1);
    }

    /* Navigation listener */

    @Override
    public void onSelectFeed(Constants.FeedID feed) {
        m_drawerLayout.closeDrawers();
        showFeed(feed);
    }

    @Override
    public void doChangeAccount() {
        m_drawerLayout.closeDrawers();
        super.queryForAccount(QueryReason.User);
    }

    private void showFeed(Constants.FeedID id) {
        if (m_feedFragment == null)
            return;

        FragmentTransaction trans = getSupportFragmentManager().beginTransaction();

        if (m_feedFragment.getFeedId() != id) {
            FeedFragment ff = new FeedFragment();
            Bundle args = new Bundle();
            args.putSerializable("feed", id);
            ff.setArguments(args);
            trans.replace(R.id.feed_fragment, ff);
        }

        if (m_objectFragment != null) {
            trans.remove(m_objectFragment);
        }

        setDisplayMode(Mode.FEED);
        trans.commit();
        m_drawerLayout.closeDrawers();
    }

    // Overlays
    OverlayController m_overlayController;

    public void showOverlay(OverlayController controller, View overlay) {
        if (m_overlayController != null) {
            evictOverlay();
        }
        ViewFlipper flipper = (ViewFlipper) findViewById(R.id.overlay_flipper);
        flipper.addView(overlay);
        flipper.setDisplayedChild(1);
        m_overlayController = controller;
        setUiFlags();
    }

    private void evictOverlay() {
        OverlayController controller = m_overlayController;
        if (controller != null) {
            hideOverlay(controller);
            controller.onHidden();
        }
    }

    @Override
    public void onBackPressed() {
        if (m_overlayController != null) {
            evictOverlay();
        } else
            super.onBackPressed();
    }

    public void hideOverlay(OverlayController controller) {
        if (m_overlayController == controller) {
            ViewFlipper flipper = (ViewFlipper) findViewById(R.id.overlay_flipper);
            flipper.setDisplayedChild(0);
            flipper.removeViewAt(1);
            m_overlayController = null;
            setUiFlags();
        }
    }

    @TargetApi(Build.VERSION_CODES.KITKAT)
    void setUiFlags() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
            return;

        ViewFlipper flipper = (ViewFlipper) findViewById(R.id.overlay_flipper);
        if (m_overlayController != null) {
            // Fullscreen
            int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_FULLSCREEN;

            if (m_overlayController.isImmersive()) {
                flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
                }
            }

            flipper.setSystemUiVisibility(flags);
        } else {
            // Standard
            flipper.setSystemUiVisibility(0);
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus)
            setUiFlags();
    }

    /** Display mode */
    public enum Mode {
        /** Showing feed */
        FEED,

        /** Showing an object from the feed */
        FEED_OBJECT,

        /** Showing an object */
        OBJECT
    }
}