com.zns.comicdroid.activity.Comics.java Source code

Java tutorial

Introduction

Here is the source code for com.zns.comicdroid.activity.Comics.java

Source

/*******************************************************************************
 * Copyright (c) 2013 Ulrik Andersson.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Ulrik Andersson - initial API and implementation
 ******************************************************************************/
package com.zns.comicdroid.activity;

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

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.app.backup.BackupManager;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.util.DisplayMetrics;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.amazon.device.associates.AssociatesAPI;
import com.amazon.device.associates.LinkService;
import com.amazon.device.associates.NotInitializedException;
import com.amazon.device.associates.OpenProductPageRequest;
import com.commonsware.cwac.loaderex.acl.SQLiteCursorLoader;
import com.zns.comicdroid.BaseFragmentActivity;
import com.zns.comicdroid.R;
import com.zns.comicdroid.adapter.ComicAdapter;
import com.zns.comicdroid.adapter.ExpandableAmazonAdapter;
import com.zns.comicdroid.amazon.AmazonSearchTask;
import com.zns.comicdroid.amazon.Book;
import com.zns.comicdroid.data.Group;
import com.zns.comicdroid.dialog.GroupDialogFragment;
import com.zns.comicdroid.dialog.RenameDialogFragment;

public class Comics extends BaseFragmentActivity implements LoaderCallbacks<Cursor>,
        RenameDialogFragment.OnRenameDialogListener, OnCheckedChangeListener, OnChildClickListener {

    public static final String INTENT_COMICS_TYPE = "com.zns.comic.COMICS_TYPE";
    public static final String INTENT_COMICS_VALUE = "com.zns.comic.COMICS_VALUE";
    public static final String INTENT_COMICS_HEADING = "com.zns.comic.COMICS_HEADING";
    public static final String INTENT_COMICS_ID = "com.zns.comics.COMICS_ID";

    public static final int VIEWTYPE_GROUP = 1;
    public static final int VIEWTYPE_AUTHOR = 2;
    public static final int VIEWTYPE_PUBLISHER = 3;
    public static final int VIEWTYPE_ILLUSTRATOR = 4;
    public static final int VIEWTYPE_READ = 5;

    private static final int LOADER_ID = 100;
    private static final String STATE_BOOKS = "BOOKS";

    private SQLiteCursorLoader mLoader;
    private ComicAdapter mAdapter;
    private ListView mLvComics;
    private TextView mTvHeading;
    private int mViewType;
    private String mViewWhereValue;
    private boolean mDeleteComics = false;
    private int mGroupId;
    private String mHeading;
    private Group mCurrentGroup;
    private CheckBox mCbIsWatched;
    private CheckBox mCbIsFinished;
    private CheckBox mCbIsComplete;
    private TextView mTvEmpty;
    private ExpandableAmazonAdapter mAmazonAdapter;
    private ExpandableListView mElvAmazon;
    private ProgressDialog mProgress;

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

        mLvComics = (ListView) findViewById(R.id.comics_lvComics);
        mTvHeading = (TextView) findViewById(R.id.comics_txtHeading);
        mTvEmpty = (TextView) findViewById(R.id.comics_tvEmpty);
        mElvAmazon = (ExpandableListView) findViewById(R.id.comics_elvBooks);
        mElvAmazon.setOnChildClickListener(this);

        mAdapter = new ComicAdapter(this, getImagePath(true));
        mLvComics.setAdapter(mAdapter);
        mLvComics.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
                int comicId = mAdapter.getComicId(position);
                Intent intent = new Intent(Comics.this, ComicView.class);
                intent.putExtra(ComicView.INTENT_COMIC_ID, comicId);
                startActivity(intent);
            }
        });

        Intent intent = getIntent();
        mViewType = intent.getIntExtra(INTENT_COMICS_TYPE, 0);
        mViewWhereValue = intent.getCharSequenceExtra(INTENT_COMICS_VALUE).toString();
        mHeading = intent.getCharSequenceExtra(INTENT_COMICS_HEADING).toString();
        if (mHeading.length() == 0) {
            mHeading = getString(R.string.list_name_na);
        }
        mTvHeading.setText(mHeading);

        if (mViewType == VIEWTYPE_GROUP) {
            mGroupId = intent.getIntExtra(INTENT_COMICS_ID, 0);
            mCurrentGroup = getDBHelper().getGroup(mGroupId);
            mCbIsWatched = (CheckBox) findViewById(R.id.comics_cbWatched);
            mCbIsWatched.setChecked(mCurrentGroup.getIsWatched());
            mCbIsWatched.setOnCheckedChangeListener(this);
            mCbIsFinished = (CheckBox) findViewById(R.id.comics_cbFinished);
            mCbIsFinished.setChecked(mCurrentGroup.getIsFinished());
            mCbIsFinished.setOnCheckedChangeListener(this);
            mCbIsComplete = (CheckBox) findViewById(R.id.comics_cbComplete);
            mCbIsComplete.setChecked(mCurrentGroup.getIsComplete());
            mCbIsComplete.setOnCheckedChangeListener(this);
            mAdapter.mRenderTitle = false;
            findViewById(R.id.comics_group_alts).setVisibility(View.VISIBLE);
            registerForContextMenu(mLvComics);
        } else if (mViewType == VIEWTYPE_READ) {
            findViewById(R.id.comics_ivAmazonsearch).setVisibility(View.GONE);
        }

        //Amazon
        AssociatesAPI.initialize(new AssociatesAPI.Config(getString(R.string.key_amazon_appkey), this));

        //Restore State
        if (savedInstanceState != null && savedInstanceState.containsKey(STATE_BOOKS)) {
            ArrayList<Book> books = savedInstanceState.getParcelableArrayList(STATE_BOOKS);
            if (books != null) {
                mAmazonAdapter = new ExpandableAmazonAdapter(this, books);
                mElvAmazon.setAdapter(mAmazonAdapter);
                mElvAmazon.setVisibility(View.VISIBLE);
            }
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle state) {
        super.onSaveInstanceState(state);
        if (mAmazonAdapter != null) {
            List<Book> books = mAmazonAdapter.getAllChildren(0);
            if (books != null) {
                state.putParcelableArrayList(STATE_BOOKS, new ArrayList<Book>(books));
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        //Load data
        loadData();
    }

    private void loadData() {
        final LoaderManager lm = getSupportLoaderManager();
        if (lm.getLoader(LOADER_ID) == null) {
            lm.initLoader(LOADER_ID, null, this);
        } else {
            lm.restartLoader(LOADER_ID, null, this);
        }
    }

    @SuppressLint("NewApi")
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        //Set indicator on the right side.
        //TODO:Figure out why it gets distorted even though I use 9 patch
        int margin = dpToPx(5);
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
            mElvAmazon.setIndicatorBounds(mElvAmazon.getRight() - (dpToPx(48) + margin),
                    mElvAmazon.getRight() - margin);
        } else {
            mElvAmazon.setIndicatorBoundsRelative(mElvAmazon.getRight() - (dpToPx(48) + margin),
                    mElvAmazon.getRight() - margin);
        }
    }

    private int dpToPx(int dp) {
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }

    //Loader Implementation
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
        String sql = "SELECT _id AS _id, Title, Subtitle, Author, Image, Issue, IsBorrowed, IsRead, Rating FROM tblBooks ";

        switch (mViewType) {
        case VIEWTYPE_GROUP:
            sql += "WHERE GroupId = ? ORDER BY Issue, Title";
            break;
        case VIEWTYPE_AUTHOR:
            sql += "WHERE Author = ? ORDER BY Title, Issue";
            break;
        case VIEWTYPE_PUBLISHER:
            sql += "WHERE Publisher = ? ORDER BY Title, Issue";
            break;
        case VIEWTYPE_ILLUSTRATOR:
            sql += "WHERE Illustrator = ? ORDER BY Title, Issue";
            break;
        case VIEWTYPE_READ:
            sql += " WHERE IsRead = ? ORDER BY Title, Issue";
            break;
        }

        mLoader = new SQLiteCursorLoader(Comics.this, getDBHelper(), sql, new String[] { mViewWhereValue });
        return (mLoader);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        mAdapter.changeCursor(cursor);
        if (cursor != null && cursor.getCount() <= 0) {
            if (mViewType == VIEWTYPE_READ) {
                mTvEmpty.setText(R.string.read_empty);
                mTvEmpty.setVisibility(View.VISIBLE);
            }
        } else {
            mTvEmpty.setVisibility(View.GONE);
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        if (mAdapter != null) {
            mAdapter.changeCursor(null);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        com.actionbarsherlock.view.MenuInflater inflater = getSupportMenuInflater();
        inflater.inflate(R.menu.actionbar_view, (com.actionbarsherlock.view.Menu) menu);
        if (mViewType == VIEWTYPE_READ) {
            menu.findItem(R.id.menu_edit).setVisible(false);
        }
        if (mViewType == VIEWTYPE_GROUP) {
            //Show edit all
            menu.findItem(R.id.submenu_view).setVisible(true);
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.menu_edit:
            if (mViewType == VIEWTYPE_GROUP) {
                GroupDialogFragment dialogGroup = GroupDialogFragment.newInstance(mGroupId, mCurrentGroup.getName(),
                        mCurrentGroup.getTotalBookCount());
                dialogGroup.show(getSupportFragmentManager(), "GROUPDIALOG");
            } else {
                RenameDialogFragment dialogRename = new RenameDialogFragment();
                dialogRename.setName(mHeading);
                dialogRename.show(getSupportFragmentManager(), "RENAMEDIALOG");
            }
            return true;
        case R.id.menu_delete:
            new AlertDialog.Builder(this).setTitle(R.string.group_delete_title)
                    .setMultiChoiceItems(new String[] { getString(R.string.group_delete_alt) }, null,
                            new DialogInterface.OnMultiChoiceClickListener() {
                                @Override
                                public void onClick(DialogInterface arg0, int pos, boolean checked) {
                                    mDeleteComics = checked;
                                }
                            })
                    .setPositiveButton(R.string.common_yes, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            getDBHelper().deleteGroup(mGroupId, mDeleteComics);
                            //Backup
                            BackupManager m = new BackupManager(Comics.this);
                            m.dataChanged();
                            //Back to start
                            Intent intent2 = new Intent(Comics.this, Start.class);
                            startActivity(intent2);
                            finish();
                        }
                    }).setNegativeButton(R.string.common_no, new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.cancel();
                        }
                    }).show();
            return true;
        case R.id.menu_editall:
            Intent intent = new Intent(this, Edit.class);
            int[] ids = mAdapter.getComicIds();
            intent.putExtra(Edit.INTENT_COMIC_IDS, ids);
            startActivity(intent);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onDialogPositiveClick(String oldName, String newName) {
        switch (mViewType) {
        case VIEWTYPE_AUTHOR:
            getDBHelper().renameAuthor(oldName, newName);
            break;
        case VIEWTYPE_PUBLISHER:
            getDBHelper().renamePublisher(oldName, newName);
            break;
        case VIEWTYPE_ILLUSTRATOR:
            getDBHelper().renameIllustrator(oldName, newName);
            break;
        }
        mTvHeading.setText(newName);
        //Backup
        BackupManager m = new BackupManager(this);
        m.dataChanged();
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        if (mViewType == VIEWTYPE_GROUP) {
            getMenuInflater().inflate(R.menu.collection_context_menu, menu);
        }
    }

    @Override
    public boolean onContextItemSelected(android.view.MenuItem item) {
        if (item.getItemId() == R.id.menu_collection_setimage) {
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
            if (info.position >= 0) {
                int comicId = mAdapter.getComicId(info.position);
                getDBHelper().setGroupImage(comicId);
            }
        }
        return super.onContextItemSelected(item);
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (buttonView == mCbIsFinished)
            getDBHelper().setGroupIsFinished(mGroupId, isChecked);
        else if (buttonView == mCbIsWatched)
            getDBHelper().setGroupIsWatched(mGroupId, isChecked);
        else if (buttonView == mCbIsComplete)
            getDBHelper().setGroupIsComplete(mGroupId, isChecked);
    }

    public void searchAmazon(View view) {
        //Make sure we have something to search for
        if (mHeading.equalsIgnoreCase(getString(R.string.list_name_na))) {
            Toast.makeText(Comics.this, R.string.amazon_nohits, Toast.LENGTH_LONG).show();
            return;
        }

        String cachePath = getExternalFilesDir(null).toString() + "/amazoncache";
        AmazonSearchTask.AmazonSearchTaskRequest req = new AmazonSearchTask.AmazonSearchTaskRequest();
        req.associateTag = getString(R.string.key_amazon_associate_tag);
        req.awsKey = getString(R.string.key_amazon_api_key);
        req.awsSecret = getString(R.string.key_amazon_api_secret);
        if (mViewType == VIEWTYPE_AUTHOR) {
            req.query = AmazonSearchTask.getAuthorQuery(mHeading);
        } else if (mViewType == VIEWTYPE_GROUP) {
            req.query = AmazonSearchTask.getGroupQuery(mHeading);
        } else if (mViewType == VIEWTYPE_ILLUSTRATOR) {
            req.query = AmazonSearchTask.getIllustratorQuery(mHeading);
        } else if (mViewType == VIEWTYPE_PUBLISHER) {
            req.query = AmazonSearchTask.getPublisherQuery(mHeading);
        }
        req.orderBy = "daterank";
        req.cachePath = cachePath;
        new AmazonSearchTask() {
            @Override
            protected void onPreExecute() {
                mProgress = new ProgressDialog(Comics.this);
                mProgress.setTitle(R.string.amazon_search_progress);
                mProgress.setCancelable(false);
                mProgress.setIndeterminate(true);
                mProgress.show();
            }

            @Override
            protected void onPostExecute(AmazonSearchTask.AmazonSearchTaskResponse result) {
                if (result.books != null && result.books.size() > 0) {
                    if (mAmazonAdapter == null) {
                        mAmazonAdapter = new ExpandableAmazonAdapter(Comics.this, result.books);
                        mElvAmazon.setAdapter(mAmazonAdapter);
                        mElvAmazon.setVisibility(View.VISIBLE);
                    } else {
                        mAmazonAdapter.notifyDataSetChanged();
                    }
                } else {
                    Toast.makeText(Comics.this, R.string.amazon_nohits, Toast.LENGTH_LONG).show();
                }
                if (mProgress != null) {
                    mProgress.dismiss();
                }
            }
        }.execute(req);
    }

    @Override
    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
        //User clicked an amazon book
        Book book = (Book) mAmazonAdapter.getChild(groupPosition, childPosition);
        OpenProductPageRequest request = new OpenProductPageRequest(book.Id);
        try {
            LinkService linkService = AssociatesAPI.getLinkService();
            linkService.openRetailPage(request);
            return true;
        } catch (NotInitializedException e) {
            e.printStackTrace();
        }
        return false;
    }
}