co.ldln.android.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for co.ldln.android.MainActivity.java

Source

/*
 * Copyright (c) 2017 LDLN
 *
 * This file is part of LDLN's Responder for Android.
 *
 * Responder for Android 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 any
 * later version.
 *
 * Responder for Android 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 LDLN Responder for Android.  If not, see <http://www.gnu.org/licenses/>.
 */

package co.ldln.android;

import java.util.ArrayList;

import co.ldln.android.sdk.LDLN;
import co.ldln.android.sdk.LDLN.LoginListener;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentManager.OnBackStackChangedListener;
import android.support.v4.app.FragmentTransaction;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends FragmentActivity
        implements LoginListener, OnBackStackChangedListener, LDLN.InitiateSyncListener {
    private ArrayList<FragmentId> mNavItems;
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private ListView mDrawerList;
    private CharSequence mTitle;
    private FragmentManager mFragmentManager;

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.action_bar, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(null);
        setContentView(R.layout.drawer_layout);

        mFragmentManager = getSupportFragmentManager();
        mFragmentManager.addOnBackStackChangedListener(this);

        // Set up navigation bar based on session state
        mNavItems = new ArrayList<FragmentId>();
        if (LDLN.isLoggedIn()) {
            mNavItems.add(FragmentId.SYNC_HISTORY);
            mNavItems.add(FragmentId.OBJECT_TYPES);
            mNavItems.add(FragmentId.MAP);
            mNavItems.add(FragmentId.SYNC_OPTIONS);
            mNavItems.add(FragmentId.LOG_OUT);
        } else {
            mNavItems.add(FragmentId.SYNC_OPTIONS);
            mNavItems.add(FragmentId.LOG_IN);
        }

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, /* host Activity */
                mDrawerLayout, /* DrawerLayout object */
                R.drawable.ic_drawer, /* nav drawer icon to replace 'Up' caret */
                R.string.drawer_open, /* "open drawer" description */
                R.string.drawer_close /* "close drawer" description */
        ) {

            /** Called when a drawer has settled in a completely closed state. */
            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                getActionBar().setTitle(mTitle);
            }

            /** Called when a drawer has settled in a completely open state. */
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                getActionBar().setTitle("Select an Action");
            }
        };

        // Set the drawer toggle as the DrawerListener
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        // Get the nav list view for population
        mDrawerList = (ListView) findViewById(R.id.left_drawer);

        // Set the adapter for the list view
        mDrawerList.setAdapter(new ArrayAdapter<FragmentId>(this, R.layout.drawer_list_item, mNavItems));

        // Set the list's click listener
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        // Register to receive messages broadcast from other parts of the app
        LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
                new IntentFilter(LDLN.BROADCAST_KEY));

        if (LDLN.isLoggedIn()) {
            if (savedInstanceState != null && mFragmentManager.getBackStackEntryCount() > 0) {
                Fragment currentFragment = mFragmentManager.findFragmentById(R.id.content_frame);
                mFragmentManager.beginTransaction().detach(currentFragment).attach(currentFragment).commit();
            } else {
                this.openFragment(FragmentId.OBJECT_TYPES, null);
            }
        } else {
            this.openFragment(FragmentId.LOG_IN, null);
        }
    }

    // Our handler for received LDLN Intents.
    private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // Get extra data included in the Intent
            LDLN.BroadcastMessageType messageType = (LDLN.BroadcastMessageType) intent
                    .getSerializableExtra("message");
            if (messageType.equals(LDLN.BroadcastMessageType.SYNCABLE_OBJECTS_REFRESHED)) {
                refreshFragment();
            }
        }
    };

    private class DrawerItemClickListener implements ListView.OnItemClickListener {
        @Override
        public void onItemClick(AdapterView parent, View view, int position, long id) {
            selectNavItem(position);
        }
    }

    /** Swaps fragments in the main content view */
    public void openFragment(FragmentId selectedItem, Bundle args) {

        // Create a fragment and add args based on selected item
        Fragment fragment = selectedItem.getFragment();

        // Handle log out and unfinished items in a special way
        if (selectedItem == FragmentId.LOG_OUT) {
            LDLN.logout(this);
            recreate();
            return;
        } else if (fragment == null) {
            Toast.makeText(this, selectedItem + " Not Implemented Yet!", Toast.LENGTH_SHORT).show();
            return;
        }

        // Add any args that were set above
        fragment.setArguments(args);

        // Insert the fragment by replacing any existing fragment
        FragmentTransaction fragmentTransaction;
        if (selectedItem == FragmentId.SYNCABLE_OBJECT_CREATE) {
            fragmentTransaction = mFragmentManager.beginTransaction().add(R.id.content_frame, fragment);
        } else {
            // If it's a map fragment, reuse any previous instance of it that may exist
            if (selectedItem == FragmentId.MAP) {
                Fragment tmpFrag = mFragmentManager.findFragmentByTag(selectedItem.toString());
                fragment = (tmpFrag == null) ? fragment : tmpFrag;
            }
            fragmentTransaction = mFragmentManager.beginTransaction().replace(R.id.content_frame, fragment);
        }
        if (selectedItem != FragmentId.LOG_IN) {
            fragmentTransaction.addToBackStack(selectedItem.toString());
        }
        fragmentTransaction.commit();

        // Highlight the selected item, update the title, and close the drawer
        setTitle(selectedItem.toString());
    }

    public void refreshFragment() {
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        Fragment currentFragment = mFragmentManager.findFragmentById(R.id.content_frame);
        if (currentFragment.getClass().equals(MapFragment.class)) {
            ((MapFragment) currentFragment).insertMarkersAndCenter();
        } else {
            ft.detach(currentFragment).attach(currentFragment).commit();
        }
    }

    /** Updates view based on clicked navigation item */
    private void selectNavItem(int position) {
        openFragment(mNavItems.get(position), new Bundle());
        mDrawerList.setItemChecked(position, true);
        mDrawerLayout.closeDrawer(mDrawerList);
    }

    @Override
    public void setTitle(CharSequence title) {
        mTitle = title;
        getActionBar().setTitle(mTitle);
    }

    @Override
    protected void onDestroy() {
        // Unregister since the activity is about to be closed.
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
        super.onDestroy();
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

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

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        // Handle other ActionBar Items
        switch (item.getItemId()) {
        case R.id.action_refresh:
            // User chose the "Refresh" action, sync data
            LDLN.initiateSync(this, this);
            return true;

        default:
            // If we got here, the user's action was not recognized.
            // Invoke the superclass to handle it.
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onInitiateSynchronizationResult(boolean success) {
        if (success) {
            Toast.makeText(this, "Successfully Initiated Synchronization!", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this,
                    "Error Initiating Synchronization! Please ensure you're connected to a LDLN network and try again...",
                    Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onLoginResult(boolean success) {
        Log.d("LoginResult", String.valueOf(success));
        if (success) {
            // w00t! we're in...do some 1337 sheeez
            recreate();
        } else {
            // There has been an error!
            Toast.makeText(this, "There was an error logging in. Please check your credentials and try again.",
                    Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onBackStackChanged() {
        // TODO: fix multiple instances of the same fragment (e.g. maps) being loaded into memory
        if (mFragmentManager.getBackStackEntryCount() > 0) {
            mTitle = mFragmentManager.getBackStackEntryAt(mFragmentManager.getBackStackEntryCount() - 1).getName();
            getActionBar().setTitle(mTitle);
        }
    }
}