au.com.cybersearch2.classyfy.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for au.com.cybersearch2.classyfy.MainActivity.java

Source

/**
Copyright (C) 2015  www.cybersearch2.com.au
    
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 au.com.cybersearch2.classyfy;

import javax.inject.Inject;
import android.app.SearchManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.Loader;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.Toast;
import au.com.cybersearch2.classyfy.data.Node;
import au.com.cybersearch2.classyfy.helper.ViewHelper;
import au.com.cybersearch2.classyfy.module.ClassyLogicModule;
import au.com.cybersearch2.classyfy.provider.ClassyFyProvider;
import au.com.cybersearch2.classyfy.provider.ClassyFySearchEngine;
import au.com.cybersearch2.classyjpa.entity.PersistenceWork;
import au.com.cybersearch2.classyjpa.entity.PersistenceWorkModule;
import au.com.cybersearch2.classyjpa.persist.PersistenceWorker;
import au.com.cybersearch2.classytask.AsyncBackgroundTask;
import au.com.cybersearch2.classytask.Executable;

/**
 * ClassyFy MainActivity
 * ClassyFy displays node details when ACTION_VIEW intent received. 
 * Fast Text Search is provided by ClassyFyProvider.
 * This activity prompts the user to navigate or search ClassyFy records.
 * @author Andrew Bowley
 * 26 Jun 2015
 */
public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";
    /** Error message for interrupted node search. Not expected to happen in normal operation */
    public static final String SEARCH_NOT_COMPLETED = "Record search did not complete";
    public static final String START_FAIL_MESSAGE = "ClassyFy failed to start due to unexpected error";
    /** Start state tracks appplication initialization progress */
    volatile protected StartState startState = StartState.precreate;

    private ClassyFyComponent classyFyComponent;
    /** Finds and formats records */
    @Inject
    ClassyfyLogic classyfyLogic;

    /**
     * onCreate
     * @see android.support.v7.app.AppCompatActivity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "In MainActivity onCreate()");
        final ClassyFyApplication classyFyApplication = ClassyFyApplication.getInstance();
        final MainActivity activity = this;
        setContentView(R.layout.activity_main);
        // Complete initialization in background
        AsyncBackgroundTask starter = new AsyncBackgroundTask(getApplication()) {
            NodeDetailsBean nodeDetails;

            @Override
            public Boolean loadInBackground() {
                Log.i(TAG, "Loading in background...");
                startState = StartState.build;
                classyFyComponent = classyFyApplication.getClassyFyComponent();
                classyFyComponent.inject(activity);
                // Invoke ClassyFyProvider using ContentResolver to force initialization
                ContentResolver contentResolver = getContentResolver();
                String type = contentResolver.getType(ClassyFySearchEngine.CONTENT_URI);
                Log.i(TAG, "Search Engine initialized for content type: " + type);
                Log.i(TAG, "Getting top level record...");
                // Get first node, which is root of records tree
                nodeDetails = getNodeDetailsBean(classyFyApplication, 1);
                return nodeDetails != null;
            }

            @Override
            public void onLoadComplete(Loader<Boolean> loader, Boolean success) {
                Log.i(TAG, "Loading completed " + success);
                startState = success ? StartState.run : StartState.fail;
                if (success)
                    displayContent(nodeDetails);
                else
                    displayToast(START_FAIL_MESSAGE);
            }
        };
        starter.onStartLoading();
    }

    private NodeDetailsBean getNodeDetailsBean(ClassyFyApplication classyFyApplication, int nodeId) {
        MainActivity activity = this;
        ClassyLogicModule classyLogicModule = new ClassyLogicModule(activity, nodeId);
        ClassyLogicComponent classyLogicComponent = classyFyComponent.plus(classyLogicModule);
        Node data = classyLogicComponent.node();
        if (data == null)
            return null;
        // Get first node, which is root of records tree
        NodeDetailsBean nodeDetails = classyfyLogic.getNodeDetails(data);
        if ((nodeDetails == null) || nodeDetails.getCategoryTitles().isEmpty())
            return null;
        return nodeDetails;
    }

    /**
     * onCreateOptionsMenu
     * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        // Get the action view of the menu item whose id is action_search
        createSearchView(menu);
        return super.onCreateOptionsMenu(menu);
    }

    /**
     * onOptionsItemSelected
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings)
            return true;
        switch (item.getItemId()) {
        case R.id.action_search:
            if (isReady()) {
                onSearchRequested();
                return true;
            } else
                return false;
        default:
        }
        return super.onOptionsItemSelected(item);
    }

    private boolean isReady() {
        if (startState == StartState.fail)
            displayToast(START_FAIL_MESSAGE);
        return !startState.isStarting();
    }

    /**
    * onNewIntent
    * @see android.support.v4.app.FragmentActivity#onNewIntent(android.content.Intent)
    */
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        parseIntent(intent);
    }

    /**
     * Display content - Heading and list of top categories
     * @param nodeDetails Bean containing details to be displayed
     */
    protected void displayContent(NodeDetailsBean nodeDetails) {
        View categoryDetails = ViewHelper.createRecordView(this, nodeDetails.getHeading(),
                nodeDetails.getCategoryTitles(), true, new OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        Intent viewIntent = new Intent(MainActivity.this, TitleSearchResultsActivity.class);
                        viewIntent.setData(
                                Uri.withAppendedPath(ClassyFySearchEngine.CONTENT_URI, String.valueOf(id)));
                        viewIntent.setAction(Intent.ACTION_VIEW);
                        startActivity(viewIntent);
                        finish();
                    }
                });
        LinearLayout categoryLayout = (LinearLayout) findViewById(R.id.top_category);
        categoryLayout.addView(categoryDetails);
    }

    /**
     * Parse intent - placeholder only
     * @param intent Intent object
     */
    protected void parseIntent(Intent intent) {
    }

    /**
     * Create search view SearchableInfo (xml/searchable.xml) and IconifiedByDefault (false)
     * @param menu Menu object
     */
    protected void createSearchView(Menu menu) {
        /** Get the action view of the menu item whose id is action_search */

        // Associate searchable configuration (in res/xml/searchable.xml with the SearchView
        SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        MenuItem searchMenuItem = menu.findItem(R.id.action_search);
        if (searchMenuItem == null)
            throw new IllegalStateException("Search menu item not found in main menu");
        SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
        if (searchView == null)
            throw new IllegalStateException("SearchView not found in main menu");
        // Assumes current activity is the searchable activity
        searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
        searchView.setIconifiedByDefault(false); // Do not iconify the widget; expand it by default
    }

    /**
     * Display toast
     * @param text Message
     */
    protected void displayToast(String text) {
        Log.e(TAG, text);
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }

}