summaryrefslogtreecommitdiff
path: root/org.fox.ttcomics
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2015-06-10 23:26:31 +0300
committerAndrew Dolgov <[email protected]>2015-06-10 23:26:31 +0300
commit5c7f7588af2e56f37f14d011fd4fd12711baca0d (patch)
tree82a438bd186da34a28b4849dea39a340f9d07118 /org.fox.ttcomics
parent19efd282e57b870c98471f6c96f0d46f89074468 (diff)
implement directory sync properly using a service
move all database-related crap to databasehelper which is now a singleton
Diffstat (limited to 'org.fox.ttcomics')
-rwxr-xr-xorg.fox.ttcomics/src/main/AndroidManifest.xml5
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java182
-rwxr-xr-xorg.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java2
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java254
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/DatabaseHelper.java338
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java136
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PositionGetService.java119
-rw-r--r--org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java6
8 files changed, 572 insertions, 470 deletions
diff --git a/org.fox.ttcomics/src/main/AndroidManifest.xml b/org.fox.ttcomics/src/main/AndroidManifest.xml
index 9c7265b..fa2eb12 100755
--- a/org.fox.ttcomics/src/main/AndroidManifest.xml
+++ b/org.fox.ttcomics/src/main/AndroidManifest.xml
@@ -24,7 +24,6 @@
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
-
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
@@ -63,6 +62,10 @@
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true" />
+ <service
+ android:name=".PositionGetService"
+ android:exported="false"/>
+
</application>
</manifest> \ No newline at end of file
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java
index ceb0d9b..5d58a5b 100644
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicListFragment.java
@@ -4,9 +4,7 @@ import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
-import android.database.SQLException;
import android.graphics.Bitmap;
-import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
@@ -37,16 +35,13 @@ import com.nostra13.universalimageloader.core.process.BitmapProcessor;
import com.shamanland.fab.FloatingActionButton;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
import jp.co.recruit_mp.android.widget.HeaderFooterGridView;
public class ComicListFragment extends Fragment implements OnItemClickListener {
private final String TAG = this.getClass().getSimpleName();
- private final static int SIZE_DIR = -100;
+ protected final static int SIZE_DIR = -100;
// corresponds to tab indexes
private final static int MODE_ALL = 0;
@@ -222,7 +217,7 @@ public class ComicListFragment extends Fragment implements OnItemClickListener {
}
}
- File thumbnailFile = new File(m_activity.getCacheFileName(firstChild != null ? firstChild : filePath + "/" + fileBaseName));
+ File thumbnailFile = new File(CommonActivity.getCacheFileName(m_activity, firstChild != null ? firstChild : filePath + "/" + fileBaseName));
if (holder.thumbnail != null && thumbnailFile != null && thumbnailFile.exists()) {
@@ -354,17 +349,19 @@ public class ComicListFragment extends Fragment implements OnItemClickListener {
case R.id.menu_reset_progress:
if (fileName != null) {
m_activity.resetProgress(fileName);
- m_adapter.notifyDataSetChanged();
}
return true;
case R.id.menu_mark_as_read:
if (fileName != null) {
- m_activity.setLastPosition(fileName, m_activity.getSize(fileName)-1);
- m_adapter.notifyDataSetChanged();
+
+ m_activity.m_databaseHelper.setLastPosition(fileName,
+ m_activity.m_databaseHelper.getSize(fileName) - 1);
+
+ updateWithoutRescan();
}
- return true;
+ return true;
default:
Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId());
return super.onContextItemSelected(item);
@@ -372,160 +369,71 @@ public class ComicListFragment extends Fragment implements OnItemClickListener {
}
private Cursor createCursor() {
- String baseDir = m_baseDirectory.length() == 0 ? m_prefs.getString("comics_directory", "") : m_baseDirectory;
-
String selection;
String selectionArgs[];
-
+
switch (m_mode) {
case MODE_READ:
selection = "path = ? AND position = size - 1";
- selectionArgs = new String[] { baseDir };
+ selectionArgs = new String[] { m_baseDirectory };
break;
case MODE_UNFINISHED:
selection = "path = ? AND position < size AND position > 0 AND position != size - 1";
- selectionArgs = new String[] { baseDir };
+ selectionArgs = new String[] { m_baseDirectory };
break;
case MODE_UNREAD:
selection = "path = ? AND position = 0 AND size != ?";
- selectionArgs = new String[] { baseDir, String.valueOf(SIZE_DIR) };
+ selectionArgs = new String[] { m_baseDirectory, String.valueOf(SIZE_DIR) };
break;
default:
selection = "path = ?";
- selectionArgs = new String[] { baseDir };
+ selectionArgs = new String[] { m_baseDirectory };
}
- return m_activity.getReadableDb().query("comics_cache", new String[] { BaseColumns._ID, "filename", "path", "position", "size",
- "(SELECT path || '/' || filename FROM comics_cache AS t2 WHERE t2.path = comics_cache.path || '/' || comics_cache.filename AND filename != '' ORDER BY filename LIMIT 1) AS firstchild" },
- selection, selectionArgs, null, null, "size != " + SIZE_DIR + ", filename, size = " + SIZE_DIR + ", filename");
+ return m_activity
+ .m_databaseHelper
+ .getReadableDatabase()
+ .query("comics_cache", new String[]{BaseColumns._ID, "filename", "path", "position", "size",
+ "(SELECT path || '/' || filename FROM comics_cache AS t2 WHERE t2.path = comics_cache.path || '/' " +
+ "|| comics_cache.filename AND filename != '' ORDER BY filename LIMIT 1) AS firstchild"},
+ selection, selectionArgs, null, null, "size != " + SIZE_DIR + ", filename, size = " + SIZE_DIR + ", filename");
}
-
+
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
-
+
m_activity = (MainActivity)activity;
-
+
m_prefs = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
}
-
+
protected void rescan(final boolean fullRescan) {
- AsyncTask<String, Integer, Integer> rescanTask = new AsyncTask<String, Integer, Integer>() {
+ if (m_swipeLayout != null) m_swipeLayout.setRefreshing(true);
+
+ m_activity.m_databaseHelper.rescanDirectory(m_baseDirectory, fullRescan, new DatabaseHelper.DirectoryScanListener() {
@Override
- protected void onProgressUpdate(Integer... progress) {
- if (isAdded()) {
- m_activity.setProgress(Math.round(((float)progress[0] / (float)progress[1]) * 10000));
- }
- }
-
- @Override
- protected Integer doInBackground(String... params) {
- String comicsDir = params[0];
-
- File dir = new File(comicsDir);
-
- int fileIndex = 0;
-
- if (dir.isDirectory()) {
- File archives[] = dir.listFiles();
-
- java.util.Arrays.sort(archives);
-
- for (File archive : archives) {
- String filePath = archive.getAbsolutePath();
-
- if (archive.isDirectory()) {
- m_activity.setSize(filePath, SIZE_DIR);
-
- } else if (archive.getName().toLowerCase().matches(".*\\.(cbz|zip)") && isAdded() && m_activity != null &&
- m_activity.getWritableDb() != null && m_activity.getWritableDb().isOpen()) {
- try {
- int size = m_activity.getSize(filePath);
-
- if (size == -1 || fullRescan) {
-
- ComicArchive cba = null;
-
- if (archive.getName().toLowerCase().matches(".*\\.(cbz|zip)")) {
- cba = new CbzComicArchive(filePath);
- }
-
- if (cba != null && cba.getCount() > 0) {
- // Get cover
-
- try {
- File thumbnailFile = new File(m_activity.getCacheFileName(filePath));
-
- if (m_activity.isStorageWritable() && (!thumbnailFile.exists() || fullRescan)) {
- InputStream is = cba.getItem(0);
-
- if (is != null) {
- FileOutputStream fos = new FileOutputStream(thumbnailFile);
-
- byte[] buffer = new byte[1024];
- int len;
- while ((len = is.read(buffer)) != -1) {
- fos.write(buffer, 0, len);
- }
-
- fos.close();
- is.close();
- }
- }
-
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- size = cba.getCount();
-
- m_activity.setSize(filePath, size);
- }
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- ++fileIndex;
-
- publishProgress(Integer.valueOf(fileIndex), Integer.valueOf(archives.length));
- }
- }
-
- if (isAdded() && m_activity != null) {
- m_activity.cleanupCache(false);
- m_activity.cleanupSqliteCache(comicsDir);
- }
-
- return fileIndex; //m_files.size();
+ public void onProgressUpdate(int progress, int max) {
+ //
}
-
+
@Override
- protected void onPostExecute(Integer result) {
- if (isAdded() && m_adapter != null) {
- m_adapter.changeCursor(createCursor());
- //m_animationAdapter.reset();
- m_adapter.notifyDataSetChanged();
+ public void onPostExecute(int result) {
+ try {
+ m_activity.cleanupCache(false);
- if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false);
- }
- }
- };
-
- String comicsDir = m_prefs.getString("comics_directory", null);
+ if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false);
- if (comicsDir != null && m_activity.isStorageAvailable()) {
- if (m_swipeLayout != null) m_swipeLayout.setRefreshing(true);
+ updateWithoutRescan();
- rescanTask.execute(m_baseDirectory.length() > 0 ? m_baseDirectory : comicsDir);
- }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
}
-
+
@Override
public void onResume() {
super.onResume();
@@ -535,10 +443,10 @@ public class ComicListFragment extends Fragment implements OnItemClickListener {
}
String comicsDir = m_prefs.getString("comics_directory", "");
-
- if (m_activity.getCachedItemCount(m_baseDirectory.length() > 0 ? m_baseDirectory : comicsDir) == 0) {
- rescan(false);
- } else {
+
+ if (m_activity.m_databaseHelper.getCachedItemCount(m_baseDirectory) == 0) {
+ rescan(false);
+ } else {
updateWithoutRescan();
}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java
index e0e3e68..11f0d33 100755
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ComicPager.java
@@ -128,7 +128,7 @@ public class ComicPager extends Fragment {
m_archive = new CbzComicArchive(m_fileName);
}
- final int position = m_activity.getLastPosition(m_fileName);
+ final int position = m_activity.m_databaseHelper.getLastPosition(m_fileName);
m_currentPage = (TextView) view.findViewById(R.id.comics_page);
m_totalPages = (TextView) view.findViewById(R.id.comics_total_pages);
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java
index c268590..cc63307 100644
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/CommonActivity.java
@@ -3,15 +3,12 @@ package org.fox.ttcomics2;
import android.accounts.Account;
import android.accounts.AccountManager;
+import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteStatement;
import android.os.Bundle;
import android.os.Environment;
import android.preference.PreferenceManager;
-import android.provider.BaseColumns;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MenuItem;
@@ -39,17 +36,15 @@ public class CommonActivity extends AppCompatActivity {
protected SharedPreferences m_prefs;
protected SyncClient m_syncClient = new SyncClient();
- private boolean m_storageAvailable;
- private boolean m_storageWritable;
+ protected DatabaseHelper m_databaseHelper;
- private SQLiteDatabase m_readableDb;
- private SQLiteDatabase m_writableDb;
-
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (!ImageLoader.getInstance().isInited()) {
+ m_databaseHelper = DatabaseHelper.getInstance(this);
+
+ if (!ImageLoader.getInstance().isInited()) {
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
@@ -67,33 +62,19 @@ public class CommonActivity extends AppCompatActivity {
m_prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
- initDatabase();
initSync();
}
@Override
public void onResume() {
super.onResume();
-
- String state = Environment.getExternalStorageState();
-
- if (Environment.MEDIA_MOUNTED.equals(state)) {
- m_storageAvailable = true;
- m_storageWritable = true;
- } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
- m_storageAvailable = true;
- m_storageWritable = false;
- } else {
- m_storageAvailable = false;
- m_storageWritable = false;
- }
-
+
initSync();
}
private void initSync() {
if (m_prefs.getBoolean("use_position_sync", false)) {
- String googleAccount = getGoogleAccount();
+ String googleAccount = getGoogleAccount(this);
if (googleAccount != null) {
m_syncClient.setOwner(googleAccount);
@@ -120,167 +101,9 @@ public class CommonActivity extends AppCompatActivity {
//
}
- public Cursor findComicByFileName(String fileName) {
- File file = new File(fileName);
-
- Cursor c = getReadableDb().query("comics_cache", null,
- "filename = ? AND path = ?",
- new String[]{file.getName(), file.getParentFile().getAbsolutePath()}, null, null, null);
-
- if (c.moveToFirst()) {
- return c;
- } else {
- c.close();
-
- SQLiteStatement stmt = getWritableDb().compileStatement("INSERT INTO comics_cache " +
- "(filename, path, position, max_position, size, checksum) VALUES (?, ?, 0, 0, -1, '')");
- stmt.bindString(1, file.getName());
- stmt.bindString(2, file.getParentFile().getAbsolutePath());
- stmt.execute();
-
- c = getReadableDb().query("comics_cache", null,
- "filename = ? AND path = ?",
- new String[] { file.getName(), file.getParentFile().getAbsolutePath() }, null, null, null);
-
- if (c.moveToFirst()) {
- return c;
- } else {
- c.close();
- }
- }
-
- return null;
- }
-
- public void setSize(String fileName, int size) {
- Cursor c = findComicByFileName(fileName);
-
- if (c != null) {
- c.close();
-
- File file = new File(fileName);
-
- SQLiteStatement stmt = getWritableDb().compileStatement("UPDATE comics_cache SET size = ? WHERE filename = ? AND path = ?");
- stmt.bindLong(1, size);
- stmt.bindString(2, file.getName());
- stmt.bindString(3, file.getParentFile().getAbsolutePath());
- stmt.execute();
- stmt.close();
- }
- }
-
- public void setLastPosition(String fileName, int position) {
- int lastPosition = getLastPosition(fileName);
-
- Cursor c = findComicByFileName(fileName);
-
- if (c != null) {
- c.close();
-
- File file = new File(fileName);
-
- SQLiteStatement stmt = getWritableDb().compileStatement("UPDATE comics_cache SET position = ?, max_position = ? WHERE filename = ? AND path = ?");
- stmt.bindLong(1, position);
- stmt.bindLong(2, Math.max(position, lastPosition));
- stmt.bindString(3, file.getName());
- stmt.bindString(4, file.getParentFile().getAbsolutePath());
- stmt.execute();
- stmt.close();
- }
-
- }
-
- public void setLastMaxPosition(String fileName, int position) {
-
- Cursor c = findComicByFileName(fileName);
-
- if (c != null) {
- c.close();
-
- File file = new File(fileName);
-
- SQLiteStatement stmt = getWritableDb().compileStatement("UPDATE comics_cache SET max_position = ? WHERE filename = ? AND path = ?");
- stmt.bindLong(1, position);
- stmt.bindString(2, file.getName());
- stmt.bindString(3, file.getParentFile().getAbsolutePath());
- stmt.execute();
- stmt.close();
- }
- }
-
- public int getLastPosition(String fileName) {
- int position = 0;
-
- File file = new File(fileName);
-
- Cursor c = getReadableDb().query("comics_cache", new String[]{"position"},
- "filename = ? AND path = ?",
- new String[]{file.getName(), file.getParentFile().getAbsolutePath()}, null, null, null);
-
- if (c.moveToFirst()) {
- position = c.getInt(c.getColumnIndex("position"));
- }
-
- c.close();
-
- return position;
-
- }
-
- public int getCachedItemCount(String baseDir) {
- Cursor c = getReadableDb().query("comics_cache", new String[] { "COUNT(*)" },
- "path = ?",
- new String[] { baseDir }, null, null, null);
-
- c.moveToFirst();
- int count = c.getInt(0);
- c.close();
-
- //Log.d(TAG, "getCachedItemCount:" + baseDir + "=" + count);
-
- return count;
- }
-
- public int getMaxPosition(String fileName) {
- int position = 0;
-
- File file = new File(fileName);
-
- Cursor c = getReadableDb().query("comics_cache", new String[] { "max_position" },
- "filename = ? AND path = ?",
- new String[] { file.getName(), file.getParentFile().getAbsolutePath() }, null, null, null);
-
- if (c.moveToFirst()) {
- position = c.getInt(c.getColumnIndex("max_position"));
- }
-
- c.close();
-
- return position;
- }
-
- public int getSize(String fileName) {
- int size = -1;
-
- File file = new File(fileName);
-
- Cursor c = getReadableDb().query("comics_cache", new String[] { "size" },
- "filename = ? AND path = ?",
- new String[] { file.getName(), file.getParentFile().getAbsolutePath() }, null, null, null);
-
- if (c.moveToFirst()) {
- size = c.getInt(c.getColumnIndex("size"));
- }
-
- c.close();
-
- //Log.d(TAG, "getSize:" + fileName + "=" + size);
-
- return size;
- }
public void onComicSelected(String fileName, int position) {
- setLastPosition(fileName, position);
+ m_databaseHelper.setLastPosition(fileName, position);
}
public boolean onOptionsItemSelected(MenuItem item) {
@@ -337,16 +160,16 @@ public class CommonActivity extends AppCompatActivity {
return null;
}
- public String getCacheFileName(String fileName) {
+ public static String getCacheFileName(Context ctx, String fileName) {
String hash = md5(fileName);
- File file = new File(getExternalCacheDir().getAbsolutePath() + "/" + hash + ".png");
+ File file = new File(ctx.getExternalCacheDir().getAbsolutePath() + "/" + hash + ".png");
return file.getAbsolutePath();
}
- public String getGoogleAccount() {
- AccountManager manager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
+ public static String getGoogleAccount(Context ctx) {
+ AccountManager manager = (AccountManager) ctx.getSystemService(ACCOUNT_SERVICE);
Account[] list = manager.getAccounts();
for (Account account: list) {
@@ -376,7 +199,7 @@ public class CommonActivity extends AppCompatActivity {
}
public void cleanupCache(boolean deleteAll) {
- if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
+ if (isStorageWritable()) {
File cachePath = getExternalCacheDir();
long now = new Date().getTime();
@@ -391,35 +214,33 @@ public class CommonActivity extends AppCompatActivity {
}
}
- public boolean isStorageAvailable() {
- return m_storageAvailable;
- }
-
- public boolean isStorageWritable() {
- return m_storageWritable;
+ public static boolean isStorageAvailable() {
+
+ String state = Environment.getExternalStorageState();
+
+ return Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state);
}
- private void initDatabase() {
- DatabaseHelper dh = new DatabaseHelper(getApplicationContext());
-
- m_writableDb = dh.getWritableDatabase();
- m_readableDb = dh.getReadableDatabase();
+ public static boolean isStorageWritable() {
+
+ String state = Environment.getExternalStorageState();
+ return Environment.MEDIA_MOUNTED.equals(state);
}
- public synchronized SQLiteDatabase getReadableDb() {
+ /*public synchronized SQLiteDatabase getReadableDb() {
return m_readableDb;
}
public synchronized SQLiteDatabase getWritableDb() {
return m_writableDb;
- }
+ } */
@Override
public void onDestroy() {
super.onDestroy();
- m_readableDb.close();
- m_writableDb.close();
+// m_readableDb.close();
+// m_writableDb.close();
}
public void selectPreviousComic() {
@@ -438,29 +259,6 @@ public class CommonActivity extends AppCompatActivity {
}
}
- public void cleanupSqliteCache(String baseDir) {
- Cursor c = getReadableDb().query("comics_cache", null,
- null, null, null, null, null);
-
- if (c.moveToFirst()) {
- while (!c.isAfterLast()) {
- int id = c.getInt(c.getColumnIndex(BaseColumns._ID));
- String fileName = c.getString(c.getColumnIndex("path")) + "/" + c.getString(c.getColumnIndex("filename"));
-
- File file = new File(fileName);
-
- if (!file.exists()) {
- SQLiteStatement stmt = getWritableDb().compileStatement("DELETE FROM comics_cache WHERE " + BaseColumns._ID + " = ?");
- stmt.bindLong(1, id);
- stmt.execute();
- }
-
- c.moveToNext();
- }
- }
-
- c.close();
- }
public void hideSystemUI(boolean hide) {
View decorView = getWindow().getDecorView();
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/DatabaseHelper.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/DatabaseHelper.java
index bf66fec..e1976e3 100644
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/DatabaseHelper.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/DatabaseHelper.java
@@ -1,37 +1,58 @@
package org.fox.ttcomics2;
-import java.io.File;
-
import android.content.Context;
import android.database.Cursor;
+import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
+import android.os.AsyncTask;
import android.provider.BaseColumns;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "ComicsCache.db";
public static final int DATABASE_VERSION = 2;
-
- public DatabaseHelper(Context context) {
+ private Context m_context;
+ private static DatabaseHelper m_instance;
+
+ public static synchronized DatabaseHelper getInstance(Context context) {
+
+ if (m_instance == null) {
+ m_instance = new DatabaseHelper(context.getApplicationContext());
+ }
+
+ return m_instance;
+ }
+
+ public interface DirectoryScanListener {
+ void onProgressUpdate(int progress, int max);
+ void onPostExecute(int result);
+ }
+
+ private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ m_context = context;
}
-
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("DROP TABLE IF EXISTS comics_cache;");
db.execSQL("CREATE TABLE IF NOT EXISTS comics_cache (" +
- BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
- "filename TEXT, " +
- "path TEXT, " + //v2
- "checksum TEXT, " + //v2
- "size INTEGER, " +
- "position INTEGER, " +
- "max_position INTEGER" +
- ");");
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
+ "filename TEXT, " +
+ "path TEXT, " + //v2
+ "checksum TEXT, " + //v2
+ "size INTEGER, " +
+ "position INTEGER, " +
+ "max_position INTEGER" +
+ ");");
}
@Override
@@ -65,4 +86,295 @@ public class DatabaseHelper extends SQLiteOpenHelper {
}
}
+ public Cursor findComicByFileName(String fileName) {
+ File file = new File(fileName);
+
+ if (getWritableDatabase() == null)
+ return null;
+
+ Cursor c = getWritableDatabase().query("comics_cache", null,
+ "filename = ? AND path = ?",
+ new String[]{file.getName(), file.getParentFile().getAbsolutePath()}, null, null, null);
+
+ if (c.moveToFirst()) {
+ return c;
+ } else {
+ c.close();
+
+ SQLiteStatement stmt = getWritableDatabase().compileStatement("INSERT INTO comics_cache " +
+ "(filename, path, position, max_position, size, checksum) VALUES (?, ?, 0, 0, -1, '')");
+ stmt.bindString(1, file.getName());
+ stmt.bindString(2, file.getParentFile().getAbsolutePath());
+ stmt.execute();
+
+ c = getWritableDatabase().query("comics_cache", null,
+ "filename = ? AND path = ?",
+ new String[] { file.getName(), file.getParentFile().getAbsolutePath() }, null, null, null);
+
+ if (c.moveToFirst()) {
+ return c;
+ } else {
+ c.close();
+ }
+ }
+
+ return null;
+ }
+
+ public void setSize(String fileName, int size) {
+ Cursor c = findComicByFileName(fileName);
+
+ if (c != null) {
+ c.close();
+
+ File file = new File(fileName);
+
+ SQLiteStatement stmt = getWritableDatabase().compileStatement("UPDATE comics_cache SET size = ? WHERE filename = ? AND path = ?");
+ stmt.bindLong(1, size);
+ stmt.bindString(2, file.getName());
+ stmt.bindString(3, file.getParentFile().getAbsolutePath());
+ stmt.execute();
+ stmt.close();
+ }
+ }
+
+ public void setLastPosition(String fileName, int position) {
+ int lastPosition = getLastPosition(fileName);
+
+ Cursor c = findComicByFileName(fileName);
+
+ if (c != null) {
+ c.close();
+
+ File file = new File(fileName);
+
+ SQLiteStatement stmt = getWritableDatabase().compileStatement("UPDATE comics_cache SET position = ?, max_position = ? WHERE filename = ? AND path = ?");
+ stmt.bindLong(1, position);
+ stmt.bindLong(2, Math.max(position, lastPosition));
+ stmt.bindString(3, file.getName());
+ stmt.bindString(4, file.getParentFile().getAbsolutePath());
+ stmt.execute();
+ stmt.close();
+ }
+
+ }
+
+ public void setLastMaxPosition(String fileName, int position) {
+
+ Cursor c = findComicByFileName(fileName);
+
+ if (c != null) {
+ c.close();
+
+ File file = new File(fileName);
+
+ SQLiteStatement stmt = getWritableDatabase().compileStatement("UPDATE comics_cache SET max_position = ? WHERE filename = ? AND path = ?");
+ stmt.bindLong(1, position);
+ stmt.bindString(2, file.getName());
+ stmt.bindString(3, file.getParentFile().getAbsolutePath());
+ stmt.execute();
+ stmt.close();
+ }
+ }
+
+ public int getLastPosition(String fileName) {
+ int position = 0;
+
+ File file = new File(fileName);
+
+ Cursor c = getWritableDatabase().query("comics_cache", new String[]{"position"},
+ "filename = ? AND path = ?",
+ new String[]{file.getName(), file.getParentFile().getAbsolutePath()}, null, null, null);
+
+ if (c.moveToFirst()) {
+ position = c.getInt(c.getColumnIndex("position"));
+ }
+
+ c.close();
+
+ return position;
+
+ }
+
+ public int getCachedItemCount(String baseDir) {
+ Cursor c = getWritableDatabase().query("comics_cache", new String[] { "COUNT(*)" },
+ "path = ?",
+ new String[] { baseDir }, null, null, null);
+
+ c.moveToFirst();
+ int count = c.getInt(0);
+ c.close();
+
+ //Log.d(TAG, "getCachedItemCount:" + baseDir + "=" + count);
+
+ return count;
+ }
+
+ public int getMaxPosition(String fileName) {
+ int position = 0;
+
+ File file = new File(fileName);
+
+ Cursor c = getWritableDatabase().query("comics_cache", new String[]{"max_position"},
+ "filename = ? AND path = ?",
+ new String[]{file.getName(), file.getParentFile().getAbsolutePath()}, null, null, null);
+
+ if (c.moveToFirst()) {
+ position = c.getInt(c.getColumnIndex("max_position"));
+ }
+
+ c.close();
+
+ return position;
+ }
+
+ public int getSize(String fileName) {
+ int size = -1;
+
+ File file = new File(fileName);
+
+ Cursor c = getWritableDatabase().query("comics_cache", new String[] { "size" },
+ "filename = ? AND path = ?",
+ new String[] { file.getName(), file.getParentFile().getAbsolutePath() }, null, null, null);
+
+ if (c.moveToFirst()) {
+ size = c.getInt(c.getColumnIndex("size"));
+ }
+
+ c.close();
+
+ //Log.d(TAG, "getSize:" + fileName + "=" + size);
+
+ return size;
+ }
+
+ public void cleanupSqliteCache(String baseDir) {
+ Cursor c = getWritableDatabase().query("comics_cache", null,
+ null, null, null, null, null);
+
+ if (c.moveToFirst()) {
+ while (!c.isAfterLast()) {
+ int id = c.getInt(c.getColumnIndex(BaseColumns._ID));
+ String fileName = c.getString(c.getColumnIndex("path")) + "/" + c.getString(c.getColumnIndex("filename"));
+
+ File file = new File(fileName);
+
+ if (!file.exists()) {
+ SQLiteStatement stmt = getWritableDatabase().compileStatement("DELETE FROM comics_cache WHERE " + BaseColumns._ID + " = ?");
+ stmt.bindLong(1, id);
+ stmt.execute();
+ }
+
+ c.moveToNext();
+ }
+ }
+
+ c.close();
+ }
+
+ public void rescanDirectory(String comicsDir, final boolean fullRescan, final DirectoryScanListener listener) {
+
+ AsyncTask<String, Integer, Integer> task = new AsyncTask<String, Integer, Integer>() {
+
+ @Override
+ protected void onProgressUpdate(Integer... progress) {
+ listener.onProgressUpdate(progress[0], progress[1]);
+ }
+
+ @Override
+ protected void onPostExecute(Integer result) {
+ listener.onPostExecute(result);
+ }
+
+ @Override
+ protected Integer doInBackground(String... params) {
+ try {
+
+ String comicsDir = params[0];
+ File dir = new File(comicsDir);
+
+ int fileIndex = 0;
+
+ if (dir.isDirectory()) {
+ File archives[] = dir.listFiles();
+
+ java.util.Arrays.sort(archives);
+
+ for (File archive : archives) {
+ String filePath = archive.getAbsolutePath();
+
+ if (archive.isDirectory()) {
+ setSize(filePath, ComicListFragment.SIZE_DIR);
+
+ } else if (archive.getName().toLowerCase().matches(".*\\.(cbz|zip)")) {
+ try {
+ int size = getSize(filePath);
+
+ if (size == -1 || fullRescan) {
+
+ ComicArchive cba = null;
+
+ if (archive.getName().toLowerCase().matches(".*\\.(cbz|zip)")) {
+ cba = new CbzComicArchive(filePath);
+ }
+
+ if (cba != null && cba.getCount() > 0) {
+ // Get cover
+
+ try {
+ File thumbnailFile = new File(CommonActivity.getCacheFileName(m_context, filePath));
+
+ if (CommonActivity.isStorageWritable() && (!thumbnailFile.exists() || fullRescan)) {
+ InputStream is = cba.getItem(0);
+
+ if (is != null) {
+ FileOutputStream fos = new FileOutputStream(thumbnailFile);
+
+ byte[] buffer = new byte[1024];
+ int len;
+ while ((len = is.read(buffer)) != -1) {
+ fos.write(buffer, 0, len);
+ }
+
+ fos.close();
+ is.close();
+ }
+ }
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ size = cba.getCount();
+
+ setSize(filePath, size);
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ ++fileIndex;
+
+ publishProgress(Integer.valueOf(fileIndex), Integer.valueOf(archives.length));
+ }
+ }
+
+ cleanupSqliteCache(comicsDir);
+
+ return fileIndex;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return 0;
+ }
+ };
+
+ task.execute(comicsDir);
+ }
}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java
index 9d986d0..a58259e 100644
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/MainActivity.java
@@ -5,9 +5,11 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
-import android.os.AsyncTask;
+import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
@@ -17,8 +19,6 @@ import android.view.Menu;
import android.view.MenuItem;
import java.io.File;
-import java.io.IOException;
-import java.net.HttpURLConnection;
import it.neokree.materialtabs.MaterialTab;
import it.neokree.materialtabs.MaterialTabHost;
@@ -32,8 +32,31 @@ public class MainActivity extends CommonActivity implements MaterialTabListener
private String m_rootDirectory = "";
private MaterialTabHost tabHost;
private boolean m_useSync;
+ private ProgressDialog m_progressDialog;
- @SuppressLint("NewApi")
+ private BroadcastReceiver m_serviceReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (PositionGetService.INTENT_ACTION_FILE_PROCESSED.equals(intent.getAction())) {
+
+ int count = intent.getExtras().getInt("count");
+ int index = intent.getExtras().getInt("index");
+
+ m_progressDialog.setCancelable(false);
+ m_progressDialog.setTitle("Synchronizing...");
+ m_progressDialog.setMessage("File " + index + " of " + count);
+ m_progressDialog.show();
+ }
+
+ if (PositionGetService.INTENT_ACTION_SCAN_COMPLETE.equals(intent.getAction())) {
+ m_progressDialog.dismiss();
+ updateComicsList();
+ }
+
+ }
+ };
+
+ @SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -45,7 +68,9 @@ public class MainActivity extends CommonActivity implements MaterialTabListener
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
setTitle(R.string.app_name);
- tabHost = (MaterialTabHost) this.findViewById(R.id.materialTabHost);
+ m_progressDialog = new ProgressDialog(this);
+
+ tabHost = (MaterialTabHost) this.findViewById(R.id.materialTabHost);
if (savedInstanceState == null) {
m_selectedTab = 0; //getIntent().getIntExtra("selectedTab", 0);
@@ -130,6 +155,13 @@ public class MainActivity extends CommonActivity implements MaterialTabListener
public void onResume() {
super.onResume();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(PositionGetService.INTENT_ACTION_FILE_PROCESSED);
+ filter.addAction(PositionGetService.INTENT_ACTION_SCAN_COMPLETE);
+ filter.addCategory(Intent.CATEGORY_DEFAULT);
+
+ registerReceiver(m_serviceReceiver, filter);
+
if (!m_rootDirectory.equals(m_prefs.getString("comics_directory", ""))) {
Log.d(TAG, "root directory changed, restarting");
@@ -207,85 +239,9 @@ public class MainActivity extends CommonActivity implements MaterialTabListener
}
private void updateLastRead(String baseDir) {
- final ProgressDialog progressDialog = new ProgressDialog(this);
-
- progressDialog.setIndeterminate(false);
- //progressDialog.setCancelable(false);
- progressDialog.setMessage("Synchronizing...");
- progressDialog.show();
-
- AsyncTask<String, Integer, Integer> task = new AsyncTask<String, Integer, Integer>() {
- @Override
- protected Integer doInBackground(String... params) {
- File dir = new File(params[0]);
-
- if (dir.exists() && dir.isDirectory()) {
- int fileCount = dir.listFiles().length;
- int fileIndex = 0;
-
- for (File file : dir.listFiles()) {
- ++fileIndex;
-
- if (file.isFile()) {
- //Log.d(TAG, "F=" + file.getName());
-
- HttpURLConnection conn = m_syncClient.doSyncHttpRequest("get", sha1(file.getName()));
-
- try {
- if (conn != null && conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
- String result = m_syncClient.readHttpResponse(conn);
-
- if (result != null) {
- //Log.d(TAG, "GOT=" + result);
-
- int position = Integer.valueOf(result);
-
- if (position > getLastPosition(file.getAbsolutePath())) {
- setLastPosition(file.getAbsolutePath(), position);
- }
- }
-
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- publishProgress(fileIndex, fileCount);
-
- try {
- Thread.sleep(250);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- return null;
- }
-
- @Override
- protected void onProgressUpdate(Integer... progress) {
- if (progressDialog != null) {
- progressDialog.setProgress(progress[0]);
- progressDialog.setMax(progress[1]);
- progressDialog.setMessage("File " + progress[0] + " of " + progress[1]);
- }
- }
-
- @Override
- protected void onPostExecute(Integer result) {
- if (progressDialog != null) {
- progressDialog.dismiss();
- }
-
- updateComicsList();
-
- }
-
- };
-
- task.execute(baseDir);
+ Intent serviceIntent = new Intent(MainActivity.this, PositionGetService.class);
+ serviceIntent.putExtra("baseDir", baseDir);
+ startService(serviceIntent);
}
@Override
@@ -330,7 +286,7 @@ public class MainActivity extends CommonActivity implements MaterialTabListener
if (m_prefs.getBoolean("use_position_sync", false) && m_syncClient.hasOwner()) {
toast(R.string.sync_uploading);
- m_syncClient.setPosition(sha1(new File(fileName).getName()), getLastPosition(fileName));
+ m_syncClient.setPosition(sha1(new File(fileName).getName()), m_databaseHelper.getLastPosition(fileName));
}
updateComicsList();
@@ -384,8 +340,8 @@ public class MainActivity extends CommonActivity implements MaterialTabListener
public void resetProgress(final String fileName) {
if (m_prefs.getBoolean("use_position_sync", false) && m_syncClient.hasOwner()) {
- setLastPosition(fileName, 0);
- setLastMaxPosition(fileName, 0);
+ m_databaseHelper.setLastPosition(fileName, 0);
+ m_databaseHelper.setLastMaxPosition(fileName, 0);
updateComicsList();
if (m_prefs.getBoolean("use_position_sync", false) && m_syncClient.hasOwner()) {
@@ -415,4 +371,10 @@ public class MainActivity extends CommonActivity implements MaterialTabListener
}
+ @Override
+ public void onPause() {
+ super.onPause();
+
+ unregisterReceiver(m_serviceReceiver);
+ }
}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PositionGetService.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PositionGetService.java
new file mode 100644
index 0000000..d94e4ac
--- /dev/null
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/PositionGetService.java
@@ -0,0 +1,119 @@
+package org.fox.ttcomics2;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Binder;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+
+public class PositionGetService extends Service {
+ private final String TAG = this.getClass().getSimpleName();
+
+ public final static String INTENT_ACTION_FILE_PROCESSED = "org.fox.ttcomics2.intent.action.FileProcessed";
+ public final static String INTENT_ACTION_SCAN_COMPLETE = "org.fox.ttcomics2.intent.action.ScanComplete";
+
+ private DatabaseHelper m_databaseHelper;
+ private final IBinder m_binder = new LocalBinder();
+
+ public class LocalBinder extends Binder {
+ PositionGetService getService() {
+ return PositionGetService.this;
+ }
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ m_databaseHelper = DatabaseHelper.getInstance(this);
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return m_binder;
+ }
+
+ @Override
+ public void onStart(Intent intent, int startId) {
+ String baseDir = intent.getExtras().getString("baseDir");
+
+ AsyncTask<String, Integer, Integer> task = new AsyncTask<String, Integer, Integer>() {
+ @Override
+ protected Integer doInBackground(String... params) {
+ File rootDir = new File(params[0]);
+
+ if (rootDir.exists() && rootDir.isDirectory()) {
+
+ int index = 0;
+ int count = rootDir.listFiles().length;
+
+ for (File file : rootDir.listFiles()) {
+ ++index;
+
+ Log.d(TAG, "file=" + file.getAbsolutePath());
+
+ SyncClient m_syncClient = new SyncClient();
+
+ String googleAccount = CommonActivity.getGoogleAccount(getApplicationContext());
+
+ if (googleAccount != null) {
+ m_syncClient.setOwner(googleAccount);
+ } else if (BuildConfig.DEBUG) {
+ m_syncClient.setOwner("TEST-ACCOUNT");
+ }
+
+ HttpURLConnection conn = m_syncClient.doSyncHttpRequest("get", CommonActivity.sha1(file.getName()));
+
+ try {
+ if (conn != null && conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
+ String result = m_syncClient.readHttpResponse(conn);
+
+ if (result != null) {
+ //Log.d(TAG, "GOT=" + result);
+
+ int position = Integer.valueOf(result);
+
+ if (position > 0) {
+
+ if (position > m_databaseHelper.getLastPosition(file.getAbsolutePath())) {
+ m_databaseHelper.setLastPosition(file.getAbsolutePath(), position);
+ }
+ }
+
+ }
+
+ Thread.sleep(250);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Intent broadcast = new Intent();
+ broadcast.setAction(INTENT_ACTION_FILE_PROCESSED);
+ broadcast.putExtra("index", index);
+ broadcast.putExtra("count", count);
+ broadcast.addCategory(Intent.CATEGORY_DEFAULT);
+ sendBroadcast(broadcast);
+ }
+ }
+
+ Intent broadcast = new Intent();
+ broadcast.setAction(INTENT_ACTION_SCAN_COMPLETE);
+ broadcast.addCategory(Intent.CATEGORY_DEFAULT);
+ sendBroadcast(broadcast);
+
+ return null;
+ }
+ };
+
+ task.execute(baseDir);
+ }
+
+}
diff --git a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java
index 56fd182..61a6f41 100644
--- a/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java
+++ b/org.fox.ttcomics/src/main/java/org/fox/ttcomics2/ViewComicActivity.java
@@ -108,7 +108,7 @@ public class ViewComicActivity extends CommonActivity {
// upload progress
if (m_prefs.getBoolean("use_position_sync", false) && m_syncClient.hasOwner()) {
//toast(R.string.sync_uploading);
- m_syncClient.setPosition(sha1(new File(m_fileName).getName()), getLastPosition(m_fileName));
+ m_syncClient.setPosition(sha1(new File(m_fileName).getName()), m_databaseHelper.getLastPosition(m_fileName));
}
}
@@ -258,7 +258,7 @@ public class ViewComicActivity extends CommonActivity {
cp.setCurrentItem(0);
break;
case 1:
- cp.setCurrentItem(getMaxPosition(m_fileName));
+ cp.setCurrentItem(m_databaseHelper.getMaxPosition(m_fileName));
break;
case 2:
if (true) {
@@ -268,7 +268,7 @@ public class ViewComicActivity extends CommonActivity {
final NumberPicker picker = (NumberPicker) contentView.findViewById(R.id.number_picker);
picker.setMinValue(1);
- picker.setMaxValue(getSize(m_fileName));
+ picker.setMaxValue(m_databaseHelper.getSize(m_fileName));
picker.setValue(cp.getPosition() + 1);
Dialog seekDialog = new Dialog(ViewComicActivity.this);