com.richtodd.android.quiltdesign.app.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.richtodd.android.quiltdesign.app.MainActivity.java

Source

/* Copyright (c) 2013 Richard G. Todd.
 * Licensed under the terms of the GNU General Public License (GPL) Version 3.0.
 */

package com.richtodd.android.quiltdesign.app;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.richtodd.android.quiltdesign.block.JSONRepository;
import com.richtodd.android.quiltdesign.block.QuiltDesignThumbnailProvider;
import com.richtodd.android.quiltdesign.block.Repository;
import com.richtodd.android.quiltdesign.block.Repository.MergeModes;
import com.richtodd.android.repository.JSONUtility;
import com.richtodd.android.repository.RepositoryException;

public class MainActivity extends Activity implements RefreshListSource, AsyncTaskListener {

    //
    // Fields
    //

    private static final DateFormat s_dateFormat = DateFormat.getDateTimeInstance();

    private static AsyncTask<?, ?, ?> s_sampleLoaderTask;

    private ActionBar m_actionBar;
    private HomeCollectionPagerAdapter m_pagerAdapter;
    private ViewPager m_viewPager;

    private List<RefreshListListener> m_refreshListListeners = new ArrayList<RefreshListListener>();

    //
    // Overrides
    //

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        PreferenceManager.setDefaultValues(this, R.xml.application_preferences, false);
        PreferenceManager.setDefaultValues(this, R.xml.block_preferences, false);
        PreferenceManager.setDefaultValues(this, R.xml.quilt_preferences, false);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getFragmentManager();

        m_pagerAdapter = new HomeCollectionPagerAdapter(fm);

        m_viewPager = (ViewPager) findViewById(R.id.viewPager);
        m_viewPager.setAdapter(m_pagerAdapter);
        m_viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            @Override
            public void onPageSelected(int position) {
                getActionBar().setSelectedNavigationItem(position);
            }

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

            @Override
            public void onPageScrollStateChanged(int state) {
            }
        });

        m_actionBar = getActionBar();
        m_actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        ActionBar.TabListener actionBarTabListener = new TabListener() {

            @Override
            public void onTabReselected(Tab tab, FragmentTransaction ft) {
            }

            @Override
            public void onTabSelected(Tab tab, FragmentTransaction ft) {
                m_viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            }
        };

        m_actionBar.addTab(m_actionBar.newTab().setText("Blocks").setTabListener(actionBarTabListener));
        m_actionBar.addTab(m_actionBar.newTab().setText("Quilts").setTabListener(actionBarTabListener));
        m_actionBar.addTab(m_actionBar.newTab().setText("Themes").setTabListener(actionBarTabListener));
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.options_activity_main, menu);
        return true;
    }

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

        try {
            if (Repository.getDefaultRepository(this).isEmpty() && !hasSampleLoaderTask()) {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage("Would you like to add some sample blocks and quilts?")
                        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int id) {

                                SampleLoaderTask task = new SampleLoaderTask();
                                setSampleLoaderTask(task);
                                task.execute(MainActivity.this);
                            }
                        }).setNegativeButton("No", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int id) {
                                // No action required.
                            }
                        });

                Dialog dialog = builder.create();
                dialog.show();
            }
        } catch (RepositoryException e) {
            Handle.asRuntimeError(e);
        }
    }

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

        SampleLoaderTask.registerListener(this);

        verifySampleLoaderTask();
    }

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

        SampleLoaderTask.unregisterListener(this);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        switch (itemId) {
        case R.id.menu_settings: {
            Intent intent = new Intent(this, MainPreferenceActivity.class);
            startActivity(intent);

            return true;
        }
        case R.id.menu_about: {
            TextDialogFragment dialog = TextDialogFragment.create("About Quilt Design", getString(R.string.about),
                    "Close");
            dialog.show(getFragmentManager(), null);

            return true;
        }
        case R.id.menu_help: {
            // Intent intent = new Intent(this, BrowserActivity.class);
            // intent.putExtra(BrowserActivity.ARG_URL,
            // "http://quiltdesign.richtodd.com");

            Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://quiltdesign.richtodd.com"));
            startActivity(intent);

            return true;
        }
        case R.id.menu_backup: {
            Uri uriFile;
            try {
                uriFile = saveRepository();

                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.putExtra(Intent.EXTRA_STREAM, uriFile);
                intent.setType("application/vnd.richtodd.quiltdesign");
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                startActivity(Intent.createChooser(intent, "Backup"));

            } catch (RepositoryException e) {
                Handle.asRuntimeError(e);
            }

            return true;
        }
        case R.id.menu_loadSamples: {

            SampleLoaderTask task = new SampleLoaderTask();
            setSampleLoaderTask(task);
            task.execute(this);

            return true;
        }
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void addListener(RefreshListListener listener) {
        m_refreshListListeners.add(listener);
    }

    @Override
    public void removeListener(RefreshListListener listener) {
        m_refreshListListeners.remove(listener);
    }

    @Override
    public void onPostExecute(AsyncTask<?, ?, ?> task, String result) {
        clearSampleLoaderTask(task);

        try {
            refreshLists();
        } catch (RepositoryException e) {
            Handle.asRuntimeError(e);
        }

        Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onCancelled(AsyncTask<?, ?, ?> task, String result) {
        clearSampleLoaderTask(task);
    }

    synchronized void setSampleLoaderTask(AsyncTask<?, ?, ?> task) {
        if (s_sampleLoaderTask != null) {
            throw new IllegalStateException("Sample loader task already in progress.");
        }

        s_sampleLoaderTask = task;

        ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setVisibility(View.VISIBLE);
    }

    synchronized void clearSampleLoaderTask(AsyncTask<?, ?, ?> task) {
        if (s_sampleLoaderTask != task) {
            throw new IllegalStateException("Sample loader task not in progress.");
        }

        s_sampleLoaderTask = null;

        ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setVisibility(View.GONE);
    }

    synchronized boolean hasSampleLoaderTask() {
        return s_sampleLoaderTask != null;
    }

    synchronized void verifySampleLoaderTask() {
        ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
        if (s_sampleLoaderTask == null) {
            progressBar.setVisibility(View.GONE);

        } else {
            progressBar.setVisibility(View.VISIBLE);
        }
    }

    //
    // Private Methods
    //

    private Uri saveRepository() throws RepositoryException {
        Repository repository = Repository.getDefaultRepository(this);

        JSONObject targetJsonRepository = new JSONObject();
        JSONRepository targetRepository = new JSONRepository(targetJsonRepository, null);
        targetRepository.merge(repository, MergeModes.New);

        String name = "Quilt Design Backup - " + s_dateFormat.format(new Date()) + ".quiltdesign";

        File file;
        try {
            file = new File(StorageUtility.getPublicFolder(), name);
        } catch (IOException e) {
            throw new RepositoryException(e);
        }
        JSONUtility.saveJSONObject(file, targetJsonRepository);

        Uri uri = Uri.fromFile(file);

        return uri;
    }

    private void refreshLists() throws RepositoryException {
        for (RefreshListListener listener : m_refreshListListeners) {
            listener.refreshList();
        }
    }

    private static class SampleLoaderTask extends AsyncTask<Context, Void, String> {

        private static Object s_syncRoot = new Object();
        private static List<AsyncTaskListener> s_listeners = new ArrayList<AsyncTaskListener>();

        synchronized static void registerListener(AsyncTaskListener listener) {
            s_listeners.add(listener);
        }

        synchronized static void unregisterListener(AsyncTaskListener listener) {
            s_listeners.remove(listener);
        }

        synchronized static void raiseOnPostExecute(AsyncTask<?, ?, ?> task, String result) {
            for (AsyncTaskListener listener : s_listeners) {
                listener.onPostExecute(task, result);
            }
        }

        synchronized static void raiseOnCancelled(AsyncTask<?, ?, ?> task, String result) {
            for (AsyncTaskListener listener : s_listeners) {
                listener.onCancelled(task, result);
            }
        }

        @Override
        protected String doInBackground(Context... params) {
            Context context = params[0];

            try {
                String json = loadSampleJSON(context);
                if (json != null) {
                    synchronized (s_syncRoot) {
                        Repository sampleRepository = new JSONRepository(new JSONObject(json),
                                new QuiltDesignThumbnailProvider());

                        Repository repository = Repository.getDefaultRepository(context);
                        repository.merge(sampleRepository, MergeModes.New);
                        repository.getThemes().createStandardThemes(
                                context.getResources().getInteger(R.integer.theme_swatch_count));
                    }
                    return context.getString(R.string.toast_samplesLoaded_success);
                }
            } catch (IOException e) {
            } catch (RepositoryException e) {
            } catch (JSONException e) {
            }

            return context.getString(R.string.toast_samplesLoaded_failure);
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            raiseOnPostExecute(this, result);
        }

        @Override
        protected void onCancelled(String result) {
            super.onCancelled(result);

            raiseOnCancelled(this, result);
        }

        private String loadSampleJSON(Context context) throws IOException {
            final int BUFFER_SIZE = 10000;
            final char[] buffer = new char[BUFFER_SIZE];

            InputStream resourceStream = context.getResources().openRawResource(R.raw.samples);
            ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(resourceStream));
            try {
                ZipEntry ze = zipStream.getNextEntry();
                if (ze != null) {
                    InputStreamReader reader = new InputStreamReader(zipStream);
                    try {
                        StringBuilder sb = new StringBuilder();
                        int count = reader.read(buffer);
                        while (count >= 0) {
                            sb.append(buffer, 0, count);
                            count = reader.read(buffer);
                        }
                        return sb.toString();
                    } finally {
                        reader.close();
                    }
                } else {
                    return null;
                }
            } finally {
                zipStream.close();
            }
        }
    }
}