ComicReader/ComicReader/src/com/blogspot/applications4android/comicreader/ActivityComicReader.java

642 lines
22 KiB
Java
Executable File

package com.blogspot.applications4android.comicreader;
import java.io.File;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.blogspot.applications4android.comicreader.core.Cache;
import com.blogspot.applications4android.comicreader.core.Comic;
import com.blogspot.applications4android.comicreader.core.ComicActivity;
import com.blogspot.applications4android.comicreader.core.ComicClass;
import com.blogspot.applications4android.comicreader.core.ComicClassList;
import com.blogspot.applications4android.comicreader.core.FileUtils;
import com.blogspot.applications4android.comicreader.core.IntentGen;
import com.blogspot.applications4android.comicreader.exceptions.ComicNotFoundException;
/**
* Main activity which will displayed to the user.
* This will contain all the comic strips which the user can click to
* browse through them.
*/
public class ActivityComicReader extends ComicActivity {
/** for logging purposes only */
private static String TAG = "ComicReader";
/** location of the listview during the last time it was read */
private static final String ITEM_POSITION_PREF = "myComicsListViewPosPref";
/** pref-key for welcome message */
private static final String WELCOME_KEY = "welcomeMsg_1";
/** pref-key for first run */
private static final String FIRST_RUN = "firstRun_1";
/** pref-key for last update! */
private static final String LAST_UPDATE_NOTICE = "lastUpdateNotice";
/** list of comics */
protected static int[] mComicItems;
/** comic list */
protected static ComicClassList mList;
/** latest activity */
protected static LatestLauncher mLL = null;
/** favorites activity */
protected static FavoriteLauncher mFL = null;
/** prev-session activity */
protected static PrevSessionLauncher mPL = null;
/** unread activity */
protected static UnreadLauncher mUL = null;
/** web page display activity */
protected static ComicMainWebPageDisplay mWP = null;
/** sort type */
protected int mType;
/** to launch the strip viewer activity in latest mode */
private class LatestLauncher implements OnClickListener {
@Override
public void onClick(View v) {
Log.d(TAG, "LatestLauncher getting triggered...");
Intent i = new Intent();
i.setClass(ActivityComicReader.this, ComicStripViewer.class);
i.putExtra("title", (String)v.getTag());
i.putExtra("mode", Comic.TYPE_LATEST);
startActivityForResult(i, 0);
}
}
/** to launch the strip viewer activity in prev-session mode */
private class PrevSessionLauncher implements OnClickListener {
@Override
public void onClick(View v) {
Log.d(TAG, "PrevSessionLauncher getting triggered...");
Intent i = new Intent();
i.setClass(ActivityComicReader.this, ComicStripViewer.class);
i.putExtra("title", (String)v.getTag());
i.putExtra("mode", Comic.TYPE_PREV_SESSION);
startActivityForResult(i, 0);
}
}
/** to launch the strip viewer activity in favorite strips mode */
private class FavoriteLauncher implements OnClickListener {
@Override
public void onClick(View v) {
Log.d(TAG, "FavoriteLauncher getting triggered...");
Intent i = new Intent();
i.setClass(ActivityComicReader.this, ComicStripViewer.class);
i.putExtra("title", (String)v.getTag());
i.putExtra("mode", Comic.TYPE_FAVORITE);
startActivityForResult(i, 0);
}
}
/** to launch the strip viewer activity in unread strips mode */
private class UnreadLauncher implements OnClickListener {
@Override
public void onClick(View v) {
Log.d(TAG, "UnreadLauncher getting triggered...");
Intent i = new Intent();
i.setClass(ActivityComicReader.this, ComicStripViewer.class);
i.putExtra("title", (String)v.getTag());
i.putExtra("mode", Comic.TYPE_UNREAD);
startActivityForResult(i, 0);
}
}
/** to launch the alertdialog for opening the comic in a web page */
private class ComicMainWebPageDisplay implements OnLongClickListener {
public boolean onLongClick(View v) {
String title = (String) v.getTag();
try {
Comic c = mList.getComicFromTitle(title);
if(c == null) {
Log.e(TAG, "no comic found for title="+title);
return false;
}
final String url = c.getComicWebPageUrl();
AlertDialog.Builder alertbox = new AlertDialog.Builder(ActivityComicReader.this);
alertbox.setMessage("Visit website of '" + title + "'?");
alertbox.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
ActivityComicReader.this.startActivity(IntentGen.linkViewIntent(url));
}
});
alertbox.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
}
});
alertbox.show();
return true;
}
catch(Exception e) {
e.printStackTrace();
return false;
}
}
}
/**
* adapter class for efficient traversal of list items displayed in the main activity
*/
private static class EfficientAdapter extends BaseAdapter {
/** Used to inflate the layout */
private LayoutInflater mInflater;
private Context ctx;
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
this.ctx =context;
}
@Override
public int getCount() {
return mComicItems.length;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
//Added a way to get button from settings menu
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(ctx);
int mscType = Integer.parseInt(sp.getString("shortcutButton", Integer.toString(1)));
if (convertView == null) {
convertView = mInflater.inflate(R.layout.main_listview_content, null);
holder = new ViewHolder();
holder.latest = (Button) convertView.findViewById(R.id.comic_item_latest);
holder.latest.setOnClickListener(mLL);
holder.latest.setOnLongClickListener(mWP);
//Switch what shortcut button is to be shown according to the settings.
switch(mscType){
case 1:
holder.favorite = (Button) convertView.findViewById(R.id.comic_item_scb);
holder.favorite.setText("FAV");
holder.favorite.setOnClickListener(mFL);
break;
case 2:
holder.previous = (Button) convertView.findViewById(R.id.comic_item_scb);
holder.previous.setText("PREV");
holder.previous.setOnClickListener(mPL);
break;
case 3:
holder.unread = (Button) convertView.findViewById(R.id.comic_item_scb);
holder.unread.setText("UnR");
holder.unread.setOnClickListener(mUL);
break;
}
convertView.setTag(holder);
convertView.setBackgroundColor(mColor1);
}
else {
holder = (ViewHolder) convertView.getTag();
}
try {
ComicClass cls = mList.getComicClassFromIndex(mComicItems[position]);
String txt = cls.mName;
if(cls.mUnread > 0) {
txt += " (" + cls.mUnread + ")";
}
holder.latest.setText(txt);
holder.latest.setTag(cls.mName);
//TODO: I don't know what this does but it has to be set correctly or android crashes
switch(mscType){
case 1:
holder.favorite.setTag(cls.mName);
break;
case 2:
holder.previous.setTag(cls.mName);
break;
case 3:
holder.unread.setTag(cls.mName);
break;
}
}
catch(ComicNotFoundException e) { // This should never occur!
e.printStackTrace();
}
return convertView;
}
/**
* A private class to hold the view which will be displayed in one row of the listview.
*/
static class ViewHolder {
/** Previous button*/
public Button previous;
/** Favorite button*/
public Button favorite;
/** Latest button*/
public Button latest;
/** Unread button */
public Button unread;
}
}
@Override
protected void onResume() {
Log.d(TAG, "on resume...");
super.onResume();
if(mLL == null) {
mLL = new LatestLauncher();
}
if(mFL == null) {
mFL = new FavoriteLauncher();
}
if(mPL == null) {
mPL = new PrevSessionLauncher();
}
if(mUL == null) {
mUL = new UnreadLauncher();
}
if(mWP == null) {
mWP = new ComicMainWebPageDisplay();
}
GetComicsTask get_task = new GetComicsTask();
get_task.execute((Void[])null);
}
@Override
protected void onPause() {
ListView l1 = (ListView) findViewById(R.id.main_list_view);
if(l1 != null) {
int last = l1.getFirstVisiblePosition();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor ed = sp.edit();
ed.putInt(ITEM_POSITION_PREF, last);
ed.commit();
}
try {
storeComicClassList(mList, true);
}
catch(Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
}
super.onPause();
Log.d(TAG, "on pause...");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inf = getMenuInflater();
inf.inflate(R.menu.comic_reader_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final Resources res = getResources();
Intent i = new Intent();
switch(item.getItemId()) {
case R.id.select:
i.setClass(ActivityComicReader.this, ActivityComicSelector.class);
startActivityForResult(i, 0);
return true;
case R.id.settings:
i.setClass(ActivityComicReader.this, ActivitySettingsPage.class);
startActivityForResult(i, 0);
return true;
case R.id.backup_favs:
{
String msg = "";
try {
mList.storeSelected();
File src = mList.selectedFile();
String zipFilename = FileUtils.getSdcard() + "/backup_favComics.zip";
if (FileUtils.favSave(mList, src.getPath(), zipFilename)) {
msg = "Successfully backed up 'My Comics' list to '" + zipFilename + "'";
}
else {
msg = "Failed to backup 'My Comics' list to '" + zipFilename + "'";
}
}
catch(Exception e) {
e.printStackTrace();
msg = "Failed to backup 'My Comics' list. Reason:" + e.getMessage();
}
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
return true;
case R.id.restore_favs:
{
final File dst = mList.selectedFile();
dst.delete();
AlertDialog.Builder alertbox = new AlertDialog.Builder(ActivityComicReader.this);
alertbox.setMessage(res.getString(R.string.my_comic_restore_confirmation));
alertbox.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(ActivityComicReader.this, res.getString(R.string.my_comic_restore_abort), Toast.LENGTH_LONG).show();
}
});
alertbox.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
String msg;
String zipFilename = FileUtils.getSdcard() + "/backup_favComics.zip";
if (FileUtils.favLoad(zipFilename)) {
msg = "Successfully restored 'My Comics' list from '" + zipFilename + "' to" + FileUtils.getComicRoot();
}
else {
msg = "Failed to restore 'My Comics' list from '" + zipFilename + "'";
}
Toast.makeText(ActivityComicReader.this, msg, Toast.LENGTH_LONG).show();
GetComicsTask get_task = new GetComicsTask();
get_task.execute((Void[])null);
}
});
alertbox.show();
return true;
}
case R.id.sync_now:
_syncNow();
return true;
case R.id.clear_all_cache:
{
AlertDialog.Builder alertbox = new AlertDialog.Builder(ActivityComicReader.this);
alertbox.setMessage(res.getString(R.string.clear_all_cache_confirmation));
alertbox.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(ActivityComicReader.this, res.getString(R.string.clear_all_cache_abort), Toast.LENGTH_LONG).show();
}
});
alertbox.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
FolderDeleteUpdater fdu = new FolderDeleteUpdater();
fdu.setActivity(ActivityComicReader.this);
fdu.setSuccessId(R.string.clear_all_cache_success);
fdu.execute(new File(FileUtils.getComicRoot(), Cache.CACHE),
new File(FileUtils.getComicRoot(), Comic.PROPS));
}
});
alertbox.show();
return true;
}
case R.id.last_synced_time:
{
AlertDialog.Builder alertbox = new AlertDialog.Builder(ActivityComicReader.this);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
String last = sp.getString(ActivitySettingsPage.LAST_SYNC_STRING_PREF, "Never");
String msg = "Last synced on: " + last;
msg += "\n Press 'Sync' to forcefully retrieve the latest strips.";
alertbox.setMessage(msg);
alertbox.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
alertbox.setPositiveButton("Sync", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
_syncNow();
}
});
alertbox.show();
return true;
}
case R.id.disclaimer:
i.putExtra("page", "file:///android_asset/Disclaimer.html");
i.setClass(ActivityComicReader.this, ActivityPageViewer.class);
startActivityForResult(i, 0);
return true;
case R.id.about:
i.putExtra("page", "file:///android_asset/About.html");
i.setClass(ActivityComicReader.this, ActivityPageViewer.class);
startActivityForResult(i, 0);
return true;
case R.id.help:
i.putExtra("page", "file:///android_asset/Help.html");
i.setClass(ActivityComicReader.this, ActivityPageViewer.class);
startActivityForResult(i, 0);
return true;
case R.id.share:
ActivityComicReader.this.startActivity(
IntentGen.shareLinkChooserIntent(res.getString(R.string.share_header),
res.getString(R.string.app_blog_url),
"Share this app..."));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Helper function to initialize the list view containing all comics
* which the user wants to see. This will read the preferences set by
* the user in the settings activity.
* Also updates the callbacks for various UI elements in the activity
*/
protected void initListView() {
_showWelcomeMessage();
_lastUpdateNotice();
if((mComicItems == null) || (mComicItems.length == 0)) {
setContentView(R.layout.comic_reader_empty_list);
return;
}
setContentView(R.layout.comic_reader);
ListView l1 = (ListView) findViewById(R.id.main_list_view);
if(l1.getAdapter() == null) {
l1.setAdapter(new EfficientAdapter(this));
}
else {
EfficientAdapter ea = (EfficientAdapter) l1.getAdapter();
ea.notifyDataSetChanged();
}
ColorDrawable divcolor = new ColorDrawable(Color.WHITE);
l1.setDivider(divcolor);
l1.setDividerHeight(1);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
int last = sp.getInt(ITEM_POSITION_PREF, 0);
l1.setSelection(last);
if(ActivitySettingsPage.checkForLastSynced(getApplicationContext())) {
_syncNow();
}
}
/**
* Things to be performed when running for the first time
*/
private void _firstRun() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if(!sp.getBoolean(FIRST_RUN, true)) {
return;
}
Log.d(TAG, "Running this app for the first time!");
ActivitySettingsPage.setupDefaults(this);
SharedPreferences.Editor e = sp.edit();
e.putBoolean(FIRST_RUN, false);
e.commit();
}
/**
* Showing that we are not going to support this app for long! Need all your help in keeping ComicReader alive!
*/
private void _lastUpdateNotice() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
final SharedPreferences.Editor e = sp.edit();
ActivitySettingsPage.launchRepeatedCaching(this, true);
if(!sp.getBoolean(LAST_UPDATE_NOTICE, true)) {
return;
}
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
alertbox.setTitle(getResources().getString(R.string.last_update_title));
alertbox.setMessage(getResources().getString(R.string.last_update_msg));
alertbox.setPositiveButton("I'm ready to help!", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
e.putBoolean(LAST_UPDATE_NOTICE, false);
e.commit();
Resources res = ActivityComicReader.this.getResources();
String[] email = new String[] { res.getString(R.string.dev_email) };
String subj = res.getString(R.string.last_update_volunteer_subj);
String body = res.getString(R.string.last_update_volunteer_body);
ActivityComicReader.this.startActivity(IntentGen.emailChooserIntent(email, subj, body, false, "Send Report..."));
}
});
alertbox.setNeutralButton("Go to github", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
e.putBoolean(LAST_UPDATE_NOTICE, false);
e.commit();
String url = ActivityComicReader.this.getString(R.string.github_link);
ActivityComicReader.this.startActivity(IntentGen.linkViewIntent(url));
}
});
alertbox.setNegativeButton("Not interested", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
e.putBoolean(LAST_UPDATE_NOTICE, false);
e.commit();
}
});
alertbox.show();
}
/**
* Display a welcome message for the first time users!
*/
private void _showWelcomeMessage() {
_firstRun();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
final SharedPreferences.Editor e = sp.edit();
ActivitySettingsPage.launchRepeatedCaching(this, true);
if(!sp.getBoolean(WELCOME_KEY, true)) {
return;
}
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
alertbox.setTitle(getResources().getString(R.string.help_title));
alertbox.setMessage(getResources().getString(R.string.help_msg));
alertbox.setPositiveButton("Show Again", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
e.putBoolean(FIRST_RUN, false);
e.putBoolean(WELCOME_KEY, true);
e.commit();
}
});
alertbox.setNeutralButton("Go to FAQs", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface arg0, int arg1) {
String url = ActivityComicReader.this.getResources().getString(R.string.faq_url);
ActivityComicReader.this.startActivity(IntentGen.linkViewIntent(url));
}
});
alertbox.setNegativeButton("Don't Show", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
e.putBoolean(FIRST_RUN, false);
e.putBoolean(WELCOME_KEY, false);
e.commit();
}
});
alertbox.show();
}
/**
* Sync now
*/
private void _syncNow() {
Log.d(TAG, "Syncing starting now...");
Intent i = new Intent();
i.setClass(this, SyncNowReciever.class);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);
AlarmManager mgr = (AlarmManager) getSystemService(ALARM_SERVICE);
mgr.set(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis(), pi);
}
/**
* Asynctask responsible for getting the list of comics
*/
private class GetComicsTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog m_pdia;
private Exception mExp = null;
@Override
protected void onPreExecute() {
m_pdia = new ProgressDialog(ActivityComicReader.this);
m_pdia.setCancelable(true);
m_pdia.setMessage(getResources().getString(R.string.my_comics_setup_msg));
m_pdia.show();
}
@Override
protected Void doInBackground(Void... params) {
try {
mList = setupComicsList("mySortPref");
mComicItems = mList.getSelectedComicList();
}
catch(Exception e) {
mExp = e;
}
return null;
}
@Override
protected void onProgressUpdate(Void... arg0) {
}
@Override
protected void onPostExecute(Void arg0) {
if(mExp != null) {
mExp.printStackTrace();
Toast.makeText(getApplicationContext(), "Failed to 'setupComicsList'! Reason: "+mExp.getMessage(), Toast.LENGTH_LONG).show();
}
initListView();
m_pdia.dismiss();
}
};
}