com.github.hobbe.android.openkarotz.activity.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.github.hobbe.android.openkarotz.activity.MainActivity.java

Source

/*
 * OpenKarotz-Android
 * http://github.com/hobbe/OpenKarotz-Android
 *
 * Copyright (c) 2014 Olivier Bagot (http://github.com/hobbe)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * http://opensource.org/licenses/MIT
 *
 */

package com.github.hobbe.android.openkarotz.activity;

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

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
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.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
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.ListView;
import android.widget.Toast;

import com.github.hobbe.android.openkarotz.R;
import com.github.hobbe.android.openkarotz.adapter.DrawerListAdapter;
import com.github.hobbe.android.openkarotz.fragment.ColorFragment;
import com.github.hobbe.android.openkarotz.fragment.EarsFragment;
import com.github.hobbe.android.openkarotz.fragment.HomeFragment;
import com.github.hobbe.android.openkarotz.fragment.RadioFragment;
import com.github.hobbe.android.openkarotz.fragment.SystemFragment;
import com.github.hobbe.android.openkarotz.karotz.IKarotz.KarotzStatus;
import com.github.hobbe.android.openkarotz.karotz.IKarotz.SoundControlCommand;
import com.github.hobbe.android.openkarotz.karotz.Karotz;
import com.github.hobbe.android.openkarotz.model.DrawerItem;
import com.github.hobbe.android.openkarotz.net.NetUtils;
import com.github.hobbe.android.openkarotz.task.GetStatusAsyncTask;
import com.github.hobbe.android.openkarotz.task.SoundControlAsyncTask;

/**
 * Main activity.
 */
public class MainActivity extends FragmentActivity {

    @Override
    public void onBackPressed() {
        FragmentManager fragmentManager = getSupportFragmentManager();

        if (fragmentManager != null) {
            int count = fragmentManager.getBackStackEntryCount();

            // Any going back?
            if (count > 1) {
                fragmentManager.popBackStack();
                return;
            }
        }

        // Else default handling
        // super.onBackPressed();
        finish();
    }

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

        // Reload configuration of drawer
        drawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        boolean result = super.onCreateOptionsMenu(menu);

        getMenuInflater().inflate(R.menu.main, menu);

        return result;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        // Pass the event to ActionBarDrawerToggle, if it returns true, then it has handled the icon touch event
        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        // Handle other action bar items...
        switch (item.getItemId()) {
        case R.id.action_sound_stop:
            doActionStopSound();
            return true;
        case R.id.action_settings:
            doActionSettings();
            return true;
        case R.id.action_about:
            doActionAbout();
            return true;
        default:
            break;
        }

        return super.onOptionsItemSelected(item);
    }

    /* Called whenever we call invalidateOptionsMenu() */
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // If the navigation drawer is open, hide action items related to the content view
        boolean drawerOpen = drawerLayout.isDrawerOpen(drawerList);
        menu.findItem(R.id.action_sound_stop).setVisible(!drawerOpen);
        menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
        menu.findItem(R.id.action_about).setVisible(!drawerOpen);

        return super.onPrepareOptionsMenu(menu);
    }

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

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

        switch (requestCode) {
        case RESULT_SETTINGS:
            // Nothing to do
            break;
        default:
            break;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.v(LOG_TAG, "onCreate, bundle: " + savedInstanceState);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fragmentManager = getSupportFragmentManager();
        if (fragmentManager != null) {
            fragmentManager.addOnBackStackChangedListener(new BackStackChangedListener());
        }

        appTitle = drawerTitle = getTitle();
        pageTitles = getResources().getStringArray(R.array.pages);

        initializeDrawer();
        initializeActionBar();

        if (savedInstanceState == null) {
            // Select first page (Home)
            selectDrawerItem(0);
        }
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        Log.v(LOG_TAG, "onPostCreate, bundle: " + savedInstanceState);
        super.onPostCreate(savedInstanceState);

        // Sync the toggle state after onRestoreInstanceState has occurred.
        drawerToggle.syncState();

        if (savedInstanceState == null) {
            // Disable all fields
            disableFields();

            // Check network connection
            if (NetUtils.isNetworkConnectionAvailable(this)) {

                // Set up Karotz instance
                initializeKarotz();

                GetStatusTask task = new GetStatusTask(this);
                task.execute();

            } else {
                Toast.makeText(MainActivity.this, getString(R.string.err_no_connection), Toast.LENGTH_LONG).show();
            }
        }
    }

    /**
     * Disable fields.
     */
    private void disableFields() {
        setFieldsEnabled(false);
    }

    private void doActionAbout() {
        Toast.makeText(MainActivity.this, getString(R.string.version) + " " + getVersion(), Toast.LENGTH_LONG)
                .show();
    }

    private void doActionSettings() {
        Log.d(LOG_TAG, "Launching settings activity...");
        Intent i = new Intent(this, SettingsActivity.class);
        startActivityForResult(i, RESULT_SETTINGS);
    }

    private void doActionStopSound() {
        new SoundControlAsyncTask(this, SoundControlCommand.STOP).execute();
    }

    /**
     * Enable fields.
     */
    private void enableFields() {
        setFieldsEnabled(true);
    }

    private Fragment getColorFragment() {
        if (colorFragment == null) {
            colorFragment = new ColorFragment();

            Bundle args = new Bundle();
            args.putInt(ARG_PAGE_NUMBER, PAGE_COLOR);
            args.putString(ARG_PAGE_TITLE, pageTitles[PAGE_COLOR]);
            colorFragment.setArguments(args);
        }
        return colorFragment;
    }

    private Fragment getEarsFragment() {
        if (earsFragment == null) {
            earsFragment = new EarsFragment();

            Bundle args = new Bundle();
            args.putInt(ARG_PAGE_NUMBER, PAGE_EARS);
            args.putString(ARG_PAGE_TITLE, pageTitles[PAGE_EARS]);
            earsFragment.setArguments(args);
        }
        return earsFragment;
    }

    private Fragment getHomeFragment() {
        if (homeFragment == null) {
            homeFragment = new HomeFragment();

            Bundle args = new Bundle();
            args.putInt(ARG_PAGE_NUMBER, PAGE_HOME);
            args.putString(ARG_PAGE_TITLE, pageTitles[PAGE_HOME]);
            homeFragment.setArguments(args);
        }
        return homeFragment;
    }

    private String getPrefKarotzHost() {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        String h = prefs.getString(SettingsActivity.KEY_PREF_KAROTZ_HOST, null);
        if (h != null && h.length() <= 0) {
            h = null;
        }
        return h;
    }

    private Fragment getRadioFragment() {
        if (radioFragment == null) {
            radioFragment = new RadioFragment();

            Bundle args = new Bundle();
            args.putInt(ARG_PAGE_NUMBER, PAGE_RADIO);
            args.putString(ARG_PAGE_TITLE, pageTitles[PAGE_RADIO]);
            radioFragment.setArguments(args);
        }
        return radioFragment;
    }

    private Fragment getSystemFragment() {
        if (systemFragment == null) {
            systemFragment = new SystemFragment();

            Bundle args = new Bundle();
            args.putInt(ARG_PAGE_NUMBER, PAGE_SYSTEM);
            args.putString(ARG_PAGE_TITLE, pageTitles[PAGE_SYSTEM]);
            systemFragment.setArguments(args);
        }
        return systemFragment;
    }

    private String getVersion() {
        String versionName = "0.0";
        try {
            versionName = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
        } catch (Exception e) {
            Log.e(LOG_TAG, "Cannot version.name from package manager: " + e.getMessage(), e);
        }
        return versionName;
    }

    private Fragment getVisibleFragment() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        List<android.support.v4.app.Fragment> fragments = fragmentManager.getFragments();
        for (Fragment fragment : fragments) {
            if (fragment != null && fragment.isVisible()) {
                return fragment;
            }
        }
        return null;
    }

    private void initializeActionBar() {
        // Enabling Home button
        getActionBar().setHomeButtonEnabled(true);

        // Enabling Up navigation
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }

    /**
     * Put everything in place to provide the drawer: drawer layout, drawer toggle and drawer list.
     */
    private void initializeDrawer() {
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerList = (ListView) findViewById(R.id.drawer_list);
        drawerToggle = new DrawerToggle(this, drawerLayout, R.drawable.ic_drawer, R.string.drawer_open,
                R.string.drawer_close);

        // Set the drawer shadow
        drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

        // Set the drawer toggle as the DrawerListener
        drawerLayout.setDrawerListener(drawerToggle);

        // Load page icons from resources
        TypedArray menuIcons = getResources().obtainTypedArray(R.array.pages_icons);

        // Create a drawer item per page
        ArrayList<DrawerItem> drawerItems = new ArrayList<DrawerItem>();
        for (int i = 0; i < pageTitles.length; i++) {
            drawerItems.add(new DrawerItem(pageTitles[i], menuIcons.getResourceId(i, -1)));
        }

        // Recycle the typed array
        menuIcons.recycle();

        // Creating the adapter to add items to the drawer list view
        DrawerListAdapter adapter = new DrawerListAdapter(getApplicationContext(), drawerItems);

        // Setting the adapter on drawerList
        drawerList.setAdapter(adapter);

        // Setting item click listener for the drawer list view
        drawerList.setOnItemClickListener(new DrawerItemClickListener());
    }

    private void initializeKarotz() {
        Log.d(LOG_TAG, "Initializing Karotz...");
        String hostname = getPrefKarotzHost();
        if (hostname == null) {
            Log.d(LOG_TAG, "Preference Karotz Host not set");
            doActionSettings();
        }

        Karotz.initialize(hostname);
    }

    private void selectDrawerItem(int position) {
        Log.v(LOG_TAG, "selectDrawerItem #" + position);

        // Create a new fragment based on position
        Fragment fragment = null;
        boolean allowBack = false;
        String tag = pageTitles[position];

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        fragment = fragmentManager.findFragmentByTag(tag);

        switch (position) {
        case PAGE_HOME:
            if (fragment == null) {
                fragment = getHomeFragment();
            }
            allowBack = true;
            break;

        case PAGE_RADIO:
            if (fragment == null) {
                fragment = getRadioFragment();
            }
            allowBack = true;
            break;

        case PAGE_COLOR:
            if (fragment == null) {
                fragment = getColorFragment();
            }
            allowBack = true;
            break;

        case PAGE_EARS:
            if (fragment == null) {
                fragment = getEarsFragment();
            }
            allowBack = true;
            break;

        case PAGE_SYSTEM:
            if (fragment == null) {
                fragment = getSystemFragment();
            }
            allowBack = true;
            break;

        default:
            break;
        }

        // Insert the fragment by replacing any existing fragment
        transaction.replace(R.id.content_frame, fragment, tag);

        // Add transaction to back stack
        if (allowBack) {
            transaction.addToBackStack(null);
        }

        // Commit
        transaction.commit();

        // Set selected item in drawer
        updateDrawerSelection(position);

        // Close the drawer
        drawerLayout.closeDrawer(drawerList);
    }

    private void setFieldsEnabled(boolean enabled) {
        drawerList.setEnabled(enabled);
    }

    private void updateDrawerSelection(Fragment fragment) {
        if (fragment != null) {
            // Fetch the selected page number
            int position = fragment.getArguments().getInt(MainActivity.ARG_PAGE_NUMBER);

            updateDrawerSelection(position);
        }
    }

    private void updateDrawerSelection(int position) {
        // Highlight the selected item
        drawerList.setItemChecked(position, true);

        // Update the title
        setTitle(pageTitles[position]);
    }

    private class BackStackChangedListener implements OnBackStackChangedListener {

        @Override
        public void onBackStackChanged() {
            FragmentManager manager = getSupportFragmentManager();
            if (manager != null) {
                updateDrawerSelection(getVisibleFragment());
            }
        }
    }

    /**
     * Click listener for drawer item.
     */
    private final class DrawerItemClickListener implements OnItemClickListener {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectDrawerItem(position);
        }

    }

    private final class DrawerToggle extends ActionBarDrawerToggle {

        /**
         * Create the drawer toggle.
         * @param activity the associated activity
         * @param layout the drawer layout
         * @param imageRes the drawer image
         * @param openDescRes the drawer description for open state
         * @param closeDescRes the drawer description for closed state
         */
        public DrawerToggle(Activity activity, DrawerLayout layout, int imageRes, int openDescRes,
                int closeDescRes) {
            super(activity, layout, imageRes, openDescRes, closeDescRes);
        }

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

        /*
         * Called when a drawer has settled in a completely open state.
         */
        @Override
        public void onDrawerOpened(View drawer) {
            super.onDrawerOpened(drawer);
            getActionBar().setTitle(drawerTitle);
            invalidateOptionsMenu();
        }
    }

    private class GetStatusTask extends GetStatusAsyncTask {

        public GetStatusTask(Activity activity) {
            super(activity);
        }

        @Override
        public void onPostExecute(Object result) {
            super.onPostExecute(result);

            KarotzStatus status = (KarotzStatus) result;

            // Check Karotz status
            if (status != null && status.isOnline()) {
                // Enable fields if Karotz is online
                enableFields();
            } else {
                Toast.makeText(getActivity(), getActivity().getString(R.string.err_cannot_connect),
                        Toast.LENGTH_LONG).show();
            }
        }

    }

    private CharSequence appTitle = null;
    private CharSequence drawerTitle = null;
    private String[] pageTitles = null;

    private DrawerLayout drawerLayout = null;
    private ListView drawerList = null;
    private ActionBarDrawerToggle drawerToggle = null;

    private Fragment homeFragment;
    private Fragment radioFragment;
    private Fragment colorFragment;
    private Fragment earsFragment;
    private Fragment systemFragment;

    // Activity settings
    private static final int RESULT_SETTINGS = 1;

    /**
     * Page number argument.
     */
    public static final String ARG_PAGE_NUMBER = "position";

    /**
     * Page title argument.
     */
    public static final String ARG_PAGE_TITLE = "title";

    // Drawer pages
    private static final int PAGE_HOME = 0;
    private static final int PAGE_RADIO = 1;
    private static final int PAGE_COLOR = 2;
    private static final int PAGE_EARS = 3;
    private static final int PAGE_SYSTEM = 4;

    // Log tag
    private static final String LOG_TAG = MainActivity.class.getSimpleName();
}