diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 570a897a9..c29722fc7 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -17,7 +17,7 @@ + android:versionName="0.5.4" > + android:value=".ui.GalleryListActivity" /> + android:dividerHeight="0dp" > \ No newline at end of file diff --git a/res/layout/download_item.xml b/res/layout/download_item.xml deleted file mode 100644 index cd1bcebf6..000000000 --- a/res/layout/download_item.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/layout/download_list_item.xml b/res/layout/download_list_item.xml new file mode 100644 index 000000000..9e328281d --- /dev/null +++ b/res/layout/download_list_item.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/layout/gallery_list_detail_item.xml b/res/layout/gallery_list_detail_item.xml index c521a65b0..783331780 100644 --- a/res/layout/gallery_list_detail_item.xml +++ b/res/layout/gallery_list_detail_item.xml @@ -24,7 +24,7 @@ android:id="@+id/thumb" android:layout_width="@dimen/list_thumb_width" android:layout_height="@dimen/list_thumb_height" /> - + + 注意 + 开始 + 停止 无效的输入 不再显示 重试 @@ -393,6 +396,7 @@ 第 %d 页 默认 删除 + 删除(包括图片) 移动 列表 首页 diff --git a/res/values/colors.xml b/res/values/colors.xml index a53d32607..1e0a11c65 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -50,14 +50,14 @@ #ff777777 - - #ff2196f3 #fff0f0f0 #22000000 + #ffe51c23 + #fffafafa #ff212121 #ffe5e5e5 diff --git a/res/values/styles.xml b/res/values/styles.xml index 0ecfc886f..04274fd2d 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -106,7 +106,7 @@ 16dip - @@ -190,4 +190,16 @@ sans-serif-condensed + + + + diff --git a/src/com/hippo/ehviewer/AppContext.java b/src/com/hippo/ehviewer/AppContext.java index 972348d83..6bba4a599 100644 --- a/src/com/hippo/ehviewer/AppContext.java +++ b/src/com/hippo/ehviewer/AppContext.java @@ -31,7 +31,6 @@ import com.hippo.ehviewer.ehclient.ExDownloaderManager; import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.util.Crash; -import com.hippo.ehviewer.util.Download; import com.hippo.ehviewer.util.Favorite; import com.hippo.ehviewer.util.Ui; import com.hippo.ehviewer.widget.MaterialToast; @@ -64,7 +63,6 @@ public void onCreate() { Ui.init(this); Crash.init(this); EhClient.createInstance(this); - Download.init(this); Favorite.init(this); Data.createInstance(this); ExDownloaderManager.createInstance(); diff --git a/src/com/hippo/ehviewer/StartActivity.java b/src/com/hippo/ehviewer/StartActivity.java index 3e6a772f5..1e269d92c 100644 --- a/src/com/hippo/ehviewer/StartActivity.java +++ b/src/com/hippo/ehviewer/StartActivity.java @@ -39,6 +39,7 @@ import com.hippo.ehviewer.widget.DialogBuilder; public class StartActivity extends Activity { + private static final String TAG = StartActivity.class.getSimpleName(); private static final int CHECK_WARING = 0; private static final int CHECK_ANALYTICS = 1; @@ -183,7 +184,6 @@ public void onClick(View v) { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - View wellcome = new View(this); wellcome.setBackgroundDrawable(getResources().getDrawable(R.drawable.welcome)); setContentView(wellcome); diff --git a/src/com/hippo/ehviewer/data/Data.java b/src/com/hippo/ehviewer/data/Data.java index 4506cc631..0f30c9b8b 100644 --- a/src/com/hippo/ehviewer/data/Data.java +++ b/src/com/hippo/ehviewer/data/Data.java @@ -24,24 +24,20 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; import android.util.SparseArray; import com.hippo.ehviewer.Analytics; +import com.hippo.ehviewer.util.Log; +import com.hippo.ehviewer.util.SqlUtils; -/** - * @author Hippo - * - */ public class Data { private static final String TAG = "Data"; - private static final int mVersion = 1; + private static final int VERSION = 2; private static final String DB_NAME = "data"; private static final String TABLE_GALLERY = "gallery"; - private static final String TABLE_READ = "read"; private static final String TABLE_LOCAL_FAVOURITE = "local_favourite"; private static final String TABLE_TAG = "tag"; private static final String TABLE_DOWNLOAD = "download"; @@ -65,17 +61,13 @@ public class Data { private static final String COLUMN_TAG = "tag"; private static final String COLUMN_STATE = "state"; - private static final String COLUMN_PAGES = "pages"; - private static final String COLUMN_DETAIL = "detail"; - private static final String COLUMN_START_PAGE = "start_page"; + private static final String COLUMN_LEGACY = "legacy"; private final SparseArray mGallerys; private long mTagRowNum; private List mTags; private List mLocalFavourites; - private List mReads; - private long mDownloadRowNum; private List mDownloads; private final Context mContext; @@ -101,7 +93,6 @@ public Data(Context context) { mGallerys = new SparseArray(); getTags(); - getReads(); getLocalFavourites(); getDownloads(); } @@ -193,6 +184,9 @@ private void addGallery(GalleryInfo galleryInfo) { reference++; } else { + + Log.e(TAG, "isInsert"); + isInsert = true; reference = 1; } @@ -209,7 +203,8 @@ private void addGallery(GalleryInfo galleryInfo) { values.put(COLUMN_REFERENCE, reference); if (isInsert) { // Set - mDatabase.insert(TABLE_GALLERY, null, values); + long id = mDatabase.insert(TABLE_GALLERY, null, values); + Log.e(TAG, "id = " + id); } else { // Update mDatabase.update(TABLE_GALLERY, values, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); } @@ -263,29 +258,46 @@ private boolean deleteGallery(int gid) { /****** download ******/ private synchronized void getDownloads() { mDownloads = new ArrayList(); - mDownloadRowNum = 0; - Cursor cursor = mDatabase.rawQuery("select * from " + TABLE_DOWNLOAD - + " order by " + COLUMN_ID + " asc", null); + Cursor cursor = mDatabase.rawQuery("select * from " + + TABLE_DOWNLOAD, null); if (cursor.moveToFirst()) { while (!cursor.isAfterLast()) { - int gid = cursor.getInt(1); + + int gid = cursor.getInt(0); GalleryInfo galleryInfo = getGallery(gid); + if (galleryInfo == null) { + cursor.moveToNext(); + continue; + } + int mode = cursor.getInt(1); int state = cursor.getInt(2); - int pages = cursor.getInt(3); - byte[] detail = cursor.getBlob(4); - int startPage = cursor.getInt(5); + int legacy = cursor.getInt(3); + if (state == DownloadInfo.STATE_WAIT || state == DownloadInfo.STATE_DOWNLOAD) + state = DownloadInfo.STATE_NONE; + DownloadInfo downloadInfo = new DownloadInfo( - galleryInfo, state, pages, detail, startPage); + galleryInfo, mode, state, legacy); mDownloads.add(downloadInfo); cursor.moveToNext(); - mDownloadRowNum++; } } cursor.close(); } + /** + * Return null if not found + * @return + */ + public synchronized DownloadInfo getFirstWaitDownloadInfo() { + for (DownloadInfo di : mDownloads) { + if (di.state == DownloadInfo.STATE_WAIT) + return di; + } + return null; + } + /** * True if contain this item * @@ -304,27 +316,31 @@ public synchronized boolean containsDownload(int gid) { } public synchronized boolean addDownload(DownloadInfo downloadInfo) { - GalleryInfo galleryInfo = downloadInfo.getGalleryInfo(); + GalleryInfo galleryInfo = downloadInfo.galleryInfo; int gid = galleryInfo.gid; - // Delete from read - deleteRead(gid); + // Add to download + boolean update; if (containsDownload(gid)) { - updateGallery(galleryInfo); - return false; + update = true; } else { + update = false; addGallery(galleryInfo); + } - // add to sql - ContentValues values = new ContentValues(); - values.put(COLUMN_ID, mDownloadRowNum); - values.put(COLUMN_GID, gid); - values.put(COLUMN_STATE, downloadInfo.getState()); - values.put(COLUMN_DETAIL, downloadInfo.getDetail()); - values.put(COLUMN_START_PAGE, downloadInfo.getStartPage()); + ContentValues values = new ContentValues(); + values.put(COLUMN_GID, gid); + values.put(COLUMN_MODE, downloadInfo.mode); + values.put(COLUMN_STATE, downloadInfo.state); + values.put(COLUMN_LEGACY, downloadInfo.legacy); + + if (update) { + mDatabase.update(TABLE_DOWNLOAD, values, + COLUMN_GID + "=?", new String[]{String.valueOf(galleryInfo.gid)}); + return false; + } else { if (mDatabase.insert(TABLE_DOWNLOAD, null, values) != -1) { // If add ok - mDownloadRowNum++; mDownloads.add(downloadInfo); return true; } else { // If add fail @@ -334,35 +350,24 @@ public synchronized boolean addDownload(DownloadInfo downloadInfo) { } } - public synchronized boolean deleteDownload(int id) { - int deleteNum = mDatabase.delete(TABLE_DOWNLOAD, COLUMN_ID + "=?", new String[]{String.valueOf(id)}); + public synchronized boolean deleteDownload(int gid) { + int deleteNum = mDatabase.delete(TABLE_DOWNLOAD, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); if (deleteNum > 1) - Log.e(TAG, "WTF? more than one id is " + id); + Log.w(TAG, "WTF? more than one gid is " + gid); if (deleteNum == 0) return false; - if (id < 0 || id >= mDownloads.size()) { - Log.e(TAG, "id is out of bounds, id is " + id + ", mDownloads.size() is " + mDownloads.size()); - return false; - } - - // delete from sql - ContentValues values = new ContentValues(); - for (int i = id + 1; i < mDownloadRowNum; i++) { - values.put(COLUMN_ID, i - 1); - mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(i)}); - } - mDownloadRowNum -= deleteNum; // delete from list - DownloadInfo downloadInfo = mDownloads.remove(id); + for (DownloadInfo di : mDownloads) { + if (gid == di.galleryInfo.gid) { + mDownloads.remove(di); + break; + } + } // sub reference - if (downloadInfo != null) { - deleteGallery(downloadInfo.getGalleryInfo().gid); - } else { - Log.e(TAG, id + " of mDownloads is null"); - } + deleteGallery(gid); return true; } @@ -371,140 +376,18 @@ public synchronized List getAllDownloads() { return mDownloads; } - public synchronized DownloadInfo getDownload(int location) { - return mDownloads.get(location); - } - - public synchronized void setDownload(int location, DownloadInfo downloadInfo) { - if (location == mDownloadRowNum) { - addDownload(downloadInfo); - } else { - // Update list - mDownloads.set(location, downloadInfo); - - // Update sql - GalleryInfo galleryInfo = downloadInfo.getGalleryInfo(); - ContentValues values = new ContentValues(); - values.put(COLUMN_ID, mDownloadRowNum); - values.put(COLUMN_GID, galleryInfo.gid); - values.put(COLUMN_STATE, downloadInfo.getState()); - values.put(COLUMN_DETAIL, downloadInfo.getDetail()); - values.put(COLUMN_START_PAGE, downloadInfo.getStartPage()); - mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(location)}); - - // Update gallery - updateGallery(galleryInfo); - } - } - - public synchronized void notifyDownloadChange(int location) { - setDownload(location, mDownloads.get(location)); - } - - public synchronized boolean swapDownload(int indexOne, int indexTwo) { - if (indexOne < 0 || indexOne > mDownloadRowNum - || indexTwo < 0 || indexTwo > mDownloadRowNum) - return false; - - if (indexOne == indexTwo) - return true; - - // Update list - DownloadInfo temp = mDownloads.get(indexOne); - mDownloads.set(indexOne, mDownloads.get(indexTwo)); - mDownloads.set(indexTwo, temp); - // Update sql - ContentValues values = new ContentValues(); - values.put(COLUMN_ID, -1); - mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(indexOne)}); - values.put(COLUMN_ID, indexOne); - mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(indexTwo)}); - values.put(COLUMN_ID, indexTwo); - mDatabase.update(TABLE_DOWNLOAD, values, COLUMN_ID + "=?", new String[]{String.valueOf(-1)}); - return true; - } - - /****** read ******/ - private synchronized void getReads() { - mReads = new ArrayList(); - Cursor cursor = mDatabase.rawQuery("select * from " - + TABLE_READ, null); - - if (cursor.moveToFirst()) { - while (!cursor.isAfterLast()) { - int gid = cursor.getInt(0); - GalleryInfo galleryInfo = getGallery(gid); - mReads.add(galleryInfo); - cursor.moveToNext(); - } - } - cursor.close(); - } - - public synchronized List getAllReads() { - return mReads; - } - - public synchronized boolean containsRead(int gid) { - boolean re = false; - Cursor cursor = mDatabase.rawQuery("select * from " - + TABLE_READ + " where " + COLUMN_GID + "=?", - new String[]{String.valueOf(gid)}); - if (cursor.moveToFirst()) - re = true; - cursor.close(); - return re; - } - - public synchronized void addRead(GalleryInfo galleryInfo) { - int gid = galleryInfo.gid; - // Do not add to read if it in download - if (containsDownload(gid)) - return; - - if (containsRead(gid)) { - updateGallery(galleryInfo); - } else { - addGallery(galleryInfo); - // add to sql - ContentValues values = new ContentValues(); - values.put(COLUMN_GID, galleryInfo.gid); - mDatabase.insert(TABLE_READ, null, values); - // add to list - mReads.add(galleryInfo); - } - } - - public synchronized void deleteRead(int gid) { - // delete from list - for (GalleryInfo galleryInfo : mReads) { - if (galleryInfo.gid == gid) { - mReads.remove(galleryInfo); - break; - } - } - - // delete from sql - mDatabase.delete(TABLE_READ, COLUMN_GID + "=?", new String[]{String.valueOf(gid)}); - deleteGallery(gid); - } - - public synchronized void deleteAllReads() { - // delete from list - mReads.clear(); - - // delete from sql - Cursor cursor = mDatabase.rawQuery("select * from " - + TABLE_READ, null); - if (cursor.moveToFirst()) { - while (!cursor.isAfterLast()) { - int gid = cursor.getInt(0); - deleteGallery(gid); - cursor.moveToNext(); - } + /** + * Return null if not found + * + * @param gid + * @return + */ + public synchronized DownloadInfo getDownload(int gid) { + for (DownloadInfo di : mDownloads) { + if (gid == di.galleryInfo.gid) + return di; } - cursor.close(); - mDatabase.delete(TABLE_READ, null, null); + return null; } /****** local favourite ******/ @@ -717,7 +600,7 @@ public synchronized boolean swapTag(int indexOne, int indexTwo) { public class DBHelper extends SQLiteOpenHelper { public DBHelper(Context context) { - super(context, DB_NAME, null, mVersion); + super(context, DB_NAME, null, VERSION); } @Override @@ -735,13 +618,6 @@ public void onCreate(SQLiteDatabase db) { + COLUMN_REFERENCE + " integer);"; db.execSQL(CreateGallery); - // read - String CreateRead = "create table " - + TABLE_READ + "(" - + COLUMN_GID + " integer primary key," - + "foreign key(" + COLUMN_GID + ") references " + TABLE_GALLERY + "(" + COLUMN_GID + "));"; - db.execSQL(CreateRead); - // local favourite String CreateLocalFavourite = "create table " + TABLE_LOCAL_FAVOURITE + "(" @@ -763,22 +639,36 @@ public void onCreate(SQLiteDatabase db) { db.execSQL(CreateTag); // download + createDownloadTable(db); + } + + private void createDownloadTable(SQLiteDatabase db) { String CreateDownload = "create table " + TABLE_DOWNLOAD + "(" - + COLUMN_ID + " integer primary key," - + COLUMN_GID + " integer unique," + + COLUMN_GID + " integer primary key," + + COLUMN_MODE + " integer," + COLUMN_STATE + " integer," - + COLUMN_PAGES + " integer," - + COLUMN_DETAIL + " blob," - + COLUMN_START_PAGE + " integer," + + COLUMN_LEGACY + " integer," + "foreign key(" + COLUMN_GID + ") references " + TABLE_GALLERY + "(" + COLUMN_GID + "));"; - db.execSQL(CreateDownload); + + SqlUtils.exeSQLSafely(db, CreateDownload); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - db.execSQL("drop table if exists " + TABLE_GALLERY); - onCreate(db); + switch (oldVersion) { + case 1: + SqlUtils.dropTable(db, TABLE_DOWNLOAD); + SqlUtils.dropTable(db, "read"); + createDownloadTable(db); + break; + case VERSION: + break; + default: + SqlUtils.dropAllTable(db); + onCreate(db); + break; + } } } } diff --git a/src/com/hippo/ehviewer/data/DownloadInfo.java b/src/com/hippo/ehviewer/data/DownloadInfo.java index e0b3434a2..86922ce5a 100644 --- a/src/com/hippo/ehviewer/data/DownloadInfo.java +++ b/src/com/hippo/ehviewer/data/DownloadInfo.java @@ -16,142 +16,36 @@ package com.hippo.ehviewer.data; -/** - * - * Use byte[] to store download detail, - * each bit for each page, 0 for uncompleted, - * 1 for completed. - * - * @author Hippo - * - */ - -// TODO get downloadMode public class DownloadInfo { - public static final int UNCOMPLETED = 0x0; - public static final int FAILED = 0x1; - public static final int COMPLETED = 0x2; - - public static final int NONE = 0x0; - public static final int WAITING = 0x1; - public static final int DOWNLOADING = 0x2; - - // TODO delete it use EhClient - public static final int G = 0x0; - public static final int EX = 0x1; - public static final int LOFI_460x = 0x2; - public static final int LOFI_780x = 0x3; - public static final int LOFI_980x = 0x4; - - private GalleryInfo mGalleryInfo; - private int mState; - private int mDownloadState; - private int mPages; - private byte[] mDetail; - private int mStartPage; - private int mMode; - - public DownloadInfo(GalleryInfo galleryInfo) { - mGalleryInfo = galleryInfo; - mState = UNCOMPLETED; - mDownloadState = NONE; - mPages = 0; - mDetail = null; - mStartPage = 0; - } - - public DownloadInfo(GalleryInfo galleryInfo, int pages) { - mGalleryInfo = galleryInfo; - mState = UNCOMPLETED; - mDownloadState = NONE; - mPages = pages; - mDetail = new byte[(mPages + 7)/8]; - mStartPage = 0; - } - - public DownloadInfo(GalleryInfo galleryInfo, int state, int pages, byte[] detail, int startPage) { - mGalleryInfo = galleryInfo; - mState = state; - mDownloadState = NONE; - mPages = pages; - mDetail = detail; - mStartPage = startPage; - } - - public boolean finishPage(int index) { - int position; // byte index - int offset; // bit offset - if (mDetail == null) - return false; - - position = index / 8; - - if (position >= mDetail.length) - return false; - - offset = index % 8; - int mask = 0x80 >> offset; - mDetail[position] |= mask; - return true; - } - - public GalleryInfo getGalleryInfo() { - return mGalleryInfo; - } - - public int getMode() { - return mMode; - } - - public int getState() { - return mState; - } - - public int getDownloadState() { - return mDownloadState; - } - - public byte[] getDetail() { - return mDetail; - } - - public int getStartPage() { - return mStartPage; - } - - /** - * If you pass detail in constructor return true, - * if you have called it setPages return true. - * @return - */ - public boolean isInit() { - return mDetail != null; - } - - /** - * If you pass detail in constructor return false, - * if you call it before return false. - * @param pages - * @return - */ - public boolean setPages(int pages) { - if (mDetail == null) - return false; - mPages = pages; - mDetail = new byte[(pages + 7) / 8]; - return true; - } - - public void setState(int state) { - mState = state; - } - - public void setDownloadState(int downloadState) { - mDownloadState = downloadState; + @SuppressWarnings("unused") + private static final String TAG = DownloadInfo.class.getSimpleName(); + + public static final int STATE_NONE = 0x0; + public static final int STATE_WAIT = 0x1; + public static final int STATE_DOWNLOAD = 0x2; + public static final int STATE_FINISH = 0x3; + + public final GalleryInfo galleryInfo; + public final int mode; + public volatile int state = STATE_NONE; + /** byte/second **/ + public volatile int speed; + public volatile int download = -1; + public volatile int total = -1; + public volatile int legacy; + + public boolean selected = false; + + public DownloadInfo(GalleryInfo gi, int mode) { + this.galleryInfo = gi; + this.mode = mode; } - - public void setStartPage(int startPage) { - mStartPage = startPage; + + public DownloadInfo(GalleryInfo gi, int mode, int state, int legacy) { + this.galleryInfo = gi; + this.mode = mode; + this.state = state; + this.legacy = legacy; } } diff --git a/src/com/hippo/ehviewer/ehclient/AddToFavoriteParser.java b/src/com/hippo/ehviewer/ehclient/AddToFavoriteParser.java index bf32c09b9..4b81bd403 100644 --- a/src/com/hippo/ehviewer/ehclient/AddToFavoriteParser.java +++ b/src/com/hippo/ehviewer/ehclient/AddToFavoriteParser.java @@ -17,12 +17,15 @@ package com.hippo.ehviewer.ehclient; public class AddToFavoriteParser { - - public boolean parser(String pageContent) { - if (pageContent.contains("Close Window")) + + public boolean parser(String body) { + if (body == null) + return false; + + if (body.contains("Close Window")) return true; else return false; } - + } diff --git a/src/com/hippo/ehviewer/ehclient/DetailParser.java b/src/com/hippo/ehviewer/ehclient/DetailParser.java index 5847996fd..eb63e9acd 100644 --- a/src/com/hippo/ehviewer/ehclient/DetailParser.java +++ b/src/com/hippo/ehviewer/ehclient/DetailParser.java @@ -101,6 +101,9 @@ public int parser(String body, int mode) { Pattern p; Matcher m; + if (body == null) + return 0; + if (!body.contains("<")) { eMesg = body; return ERROR; @@ -228,7 +231,7 @@ public int parser(String body, int mode) { // Get comment if ((mode & COMMENT) != 0) { p = Pattern - .compile("
Posted on ([^<>]+) by ]+>([^<>]+).*?
(.*?)
"); + .compile("
Posted on ([^<>]+) by ]+>([^<>]+).+?
]*>(.+?)
(); while (m.find()) { diff --git a/src/com/hippo/ehviewer/ehclient/DetailUrlParser.java b/src/com/hippo/ehviewer/ehclient/DetailUrlParser.java index 964b82a56..99393e335 100644 --- a/src/com/hippo/ehviewer/ehclient/DetailUrlParser.java +++ b/src/com/hippo/ehviewer/ehclient/DetailUrlParser.java @@ -25,6 +25,9 @@ public class DetailUrlParser { public String token; public boolean parser(String url) { + if (url == null) + return false; + Pattern p = Pattern.compile("/(\\d+)/(\\w+)"); Matcher m = p.matcher(url); if (m.find()) { diff --git a/src/com/hippo/ehviewer/ehclient/EdDetailParser.java b/src/com/hippo/ehviewer/ehclient/EdDetailParser.java index c9697117e..c735df765 100644 --- a/src/com/hippo/ehviewer/ehclient/EdDetailParser.java +++ b/src/com/hippo/ehviewer/ehclient/EdDetailParser.java @@ -34,6 +34,9 @@ public boolean parser(String body, int mode, boolean needPreviewInfo) { Pattern p; Matcher m; + if (body == null) + return false; + if (!body.contains("<")) emsg = body; diff --git a/src/com/hippo/ehviewer/ehclient/ExDownloader.java b/src/com/hippo/ehviewer/ehclient/ExDownloader.java index 237a7be98..f85d3efa3 100644 --- a/src/com/hippo/ehviewer/ehclient/ExDownloader.java +++ b/src/com/hippo/ehviewer/ehclient/ExDownloader.java @@ -43,6 +43,7 @@ public class ExDownloader implements Runnable { private static final String TAG = ExDownloader.class.getSimpleName(); + private static final int IO_BUFFER_SIZE = 8 * 1024; private static final int WORKER_NUM = 3; private final Context mContext; @@ -80,14 +81,24 @@ public class ExDownloader implements Runnable { private final Object mWorkerLock = new Object(); private final Object mWorkerGetIndexLock = new Object(); + private volatile boolean mDownloadMode = false; private volatile boolean mPauseWork = false; private volatile boolean mStopWork = false; private final File mDir; private ListenerForImageSet mLfis; + private ListenerForDownload mLfd; - private static final int IO_BUFFER_SIZE = 8 * 1024; + private static final long UPDATE_SPEED_INTERVAL = 500; + private volatile long mLastUpdateSpeedTime = 0; + private volatile long mAccumulateSize; + private volatile HashSet mDownloadIndexSet; + private volatile Object mDownloadLock = new Object(); + /** + * Do no work in UI thread + * @author Hippo + */ public interface ListenerForImageSet { public void onDownloadStart(int index); public void onDownloading(int index, float percent); @@ -95,8 +106,15 @@ public interface ListenerForImageSet { public void onDownloadFail(int index); } + /** + * Do no work in UI thread + * @author Hippo + */ public interface ListenerForDownload { - public void onDownloading(int index); + public void onStart(int gid); + public void onDownload(int gid, int downloadSize, int totalSize); + public void onUpdateSpeed(int gid, int speed); + public void onDownloadOver(int gid, int legacy); } ExDownloader(int gid, String token, String title, int mode) { @@ -110,12 +128,21 @@ public interface ListenerForDownload { // Make sure dir mDir = EhUtils.getGalleryDir(mGid, mTitle); Utils.ensureDir(mDir, true); + // Create mark file + File makeFile = new File(mDir, EhUtils.EH_DOWNLOAD_FILENAME); + try { + makeFile.createNewFile(); + } catch (IOException e) {} } public void setListenerForImageSet(ListenerForImageSet l) { mLfis = l; } + public void setListenerDownload(ListenerForDownload l) { + mLfd = l; + } + void occupy() { mOwnerNum++; } @@ -142,7 +169,10 @@ void stop() { synchronized(mWorkerLock) {mWorkerLock.notifyAll();} } - void pause(boolean pause) { + boolean pause(boolean pause) { + if (mOwnerNum > 1) + return false; + mPauseWork = pause; if (mPauseWork) { // Stop download @@ -159,6 +189,7 @@ void pause(boolean pause) { ensureStart(); ensureWorkers(); } + return true; } public int getGid() { @@ -169,14 +200,33 @@ public String getToken() { return mToken; } + public void setDownloadMode(boolean downloadMode) { + synchronized (mDownloadLock) { + if (downloadMode) { + setStartIndex(0); + if (mDownloadIndexSet == null) + mDownloadIndexSet = new HashSet(); + if (mLfd != null) + mLfd.onStart(mGid); + } else { + mDownloadIndexSet = null; + } + mDownloadMode = downloadMode; + } + } + public void setStartIndex(int startIndex) { - if (mImageNum != -1 && startIndex >= mImageNum) - mStartIndex = 0; - else - mStartIndex = startIndex; + if (mDownloadMode) { + setTargetIndex(startIndex); + } else { + if (mImageNum != -1 && startIndex >= mImageNum) + mStartIndex = 0; + else + mStartIndex = startIndex; - ensureStart(); - ensureWorkers(); + ensureStart(); + ensureWorkers(); + } } public void setTargetIndex(int index) { @@ -190,7 +240,7 @@ public void setTargetIndex(int index) { public int getMaxEnsureIndex() { if (mImageNum != -1) { - return mImageNum; + return mImageNum - 1; } else { return Math.max(Math.max(Math.max(mStartIndex - 1, Math.max(mCurMaxPreviewPage, mPreviewPageNum - 1) * mPreviewPerPage), @@ -352,18 +402,18 @@ private void writeEdiFile(File ediFile) { } } - private String getDetailInfo(int pageIndex, File ediFile, boolean needPreviewInfo) { + private void getDetailInfo(int pageIndex, File ediFile, boolean needPreviewInfo) throws Exception { HttpHelper hh = new HttpHelper(mContext); EdDetailParser edp = new EdDetailParser(); String url = EhClient.getDetailUrl(mGid, mToken, pageIndex, mMode); hh.setPreviewMode("m"); String body = hh.get(url); if (body == null) - return hh.getEMsg() != null ? hh.getEMsg() : "Http error"; + throw new Exception(hh.getEMsg() != null ? hh.getEMsg() : "Http error"); if (!edp.parser(body, mMode, needPreviewInfo)) - return edp.emsg != null ? edp.emsg : "Parser error"; // TODO + throw new Exception(edp.emsg != null ? edp.emsg : "Parser error"); if (edp.previewStartIndex != pageIndex * mPreviewPerPage) - return "预测与实际不匹配"; // TODO + throw new Exception("预测与实际不匹配"); List pageTokenArray = edp.pageTokenArray; if (needPreviewInfo) @@ -387,11 +437,7 @@ private String getDetailInfo(int pageIndex, File ediFile, boolean needPreviewInf for (int i = 0; i < pageTokenArray.size(); i++) mPageTokeArray.set(i + edp.previewStartIndex, pageTokenArray.get(i)); - if (!needPreviewInfo) - ; // TODO add loader page - writeEdiFile(ediFile); - return null; } private void ensureWorkers() { @@ -410,6 +456,16 @@ private void ensureWorkers() { } } + private void updateDownload(int index) { + synchronized (mDownloadLock) { + if (mDownloadIndexSet != null && !mDownloadIndexSet.contains(index)) { + mDownloadIndexSet.add(index); + if (mDownloadMode && mLfd != null) + mLfd.onDownload(mGid, mDownloadIndexSet.size(), getMaxEnsureIndex() + 1); + } + } + } + // TODO for download , when to claim download completed @Override public void run() { @@ -463,8 +519,17 @@ public void run() { synchronized(mWorkerGetIndexLock) {mWorkerGetIndexLock.notifyAll();} synchronized(mWorkerLock) {mWorkerLock.notifyAll();} } - } catch (Throwable e) { - // TODO handle error here + } catch (Exception e) { + + // TODO get error + + synchronized (mDownloadLock) { + if (mDownloadMode && mLfd != null && mDownloadIndexSet != null) { + mLfd.onDownloadOver(mGid, + getMaxEnsureIndex() + 1 - mDownloadIndexSet.size()); + } + } + } finally { synchronized (this) { mMainThread = null; @@ -567,8 +632,12 @@ public void run() { } } } - if (isAlreadyDownloaded) + + if (isAlreadyDownloaded) { + Log.d(TAG, "isAlreadyDownloaded"); + updateDownload(targetIndex); continue; + } mRequstingIndexSet.add(targetIndex); @@ -640,6 +709,17 @@ public void run() { // Remove from mWorkerArray mWorkerArray[mIndex] = null; mControlorArray[mIndex] = null; + + boolean allNull = true; + for (Worker w : mWorkerArray) + if (w != null) {allNull = false; break;} + + synchronized (mDownloadLock) { + if (allNull && mDownloadMode && mLfd != null && mDownloadIndexSet != null) { + mLfd.onDownloadOver(mGid, + getMaxEnsureIndex() + 1 - mDownloadIndexSet.size()); + } + } } Log.d(TAG, "ExDownloader Worker over"); } @@ -649,10 +729,12 @@ public class HttpDownloadListener implements HttpHelper.OnDownloadListener { public int index; private float lastPercent; + private int lastDownloadSize; @Override public void onDownloadStartConnect() { lastPercent = 0.0f; + lastDownloadSize = 0; if (mLfis != null) mLfis.onDownloadStart(index); @@ -661,6 +743,7 @@ public void onDownloadStartConnect() { @Override public void onDownloadStartDownload(int totalSize) { lastPercent = 0.0f; + lastDownloadSize = 0; } @Override @@ -675,19 +758,36 @@ public void onDownloadStatusUpdate(int downloadSize, int totalSize) { if (mLfis != null) mLfis.onDownloading(index, percent); } + + // Update download size + int accumulateSize = downloadSize - lastDownloadSize; + lastDownloadSize = downloadSize; + mAccumulateSize += accumulateSize; + long curTime = System.currentTimeMillis(); + long interval = curTime - mLastUpdateSpeedTime; + if (interval > UPDATE_SPEED_INTERVAL) { + if (mDownloadMode && mLfd != null) + mLfd.onUpdateSpeed(mGid, (int)(mAccumulateSize * 1000 / interval)); + mLastUpdateSpeedTime = curTime; + mAccumulateSize = 0; + } } @Override public void onDownloadOver(int status, String eMsg) { - if (status == HttpHelper.DOWNLOAD_OK_CODE) + if (status == HttpHelper.DOWNLOAD_OK_CODE) { mRequstingIndexSet.remove(index); + updateDownload(index); + } + if (mLfis != null && status == HttpHelper.DOWNLOAD_OK_CODE) mLfis.onDownloadComplete(index); else if (mLfis != null && status == HttpHelper.DOWNLOAD_FAIL_CODE) mLfis.onDownloadFail(index); lastPercent = 0.0f; + lastDownloadSize = 0; } } } diff --git a/src/com/hippo/ehviewer/ehclient/ImagePageParser.java b/src/com/hippo/ehviewer/ehclient/ImagePageParser.java index 830d17e5d..87fdad4bd 100644 --- a/src/com/hippo/ehviewer/ehclient/ImagePageParser.java +++ b/src/com/hippo/ehviewer/ehclient/ImagePageParser.java @@ -37,6 +37,9 @@ public boolean parser(String body, int mode) { Pattern p; Matcher m; + if (body == null) + return false; + if (mode ==EhClient.MODE_LOFI) { p = Pattern.compile("]+>"); m = p.matcher(body); diff --git a/src/com/hippo/ehviewer/ehclient/ListParser.java b/src/com/hippo/ehviewer/ehclient/ListParser.java index 13f6f04c4..cddd266d5 100644 --- a/src/com/hippo/ehviewer/ehclient/ListParser.java +++ b/src/com/hippo/ehviewer/ehclient/ListParser.java @@ -50,6 +50,9 @@ public int parser(String body, int mode) { Pattern p; Matcher m; + if (body == null) + return 0; + giList = new ArrayList(25); switch (mode) { diff --git a/src/com/hippo/ehviewer/ehclient/LofiDetailParser.java b/src/com/hippo/ehviewer/ehclient/LofiDetailParser.java index 1e8468817..5c9848cb9 100644 --- a/src/com/hippo/ehviewer/ehclient/LofiDetailParser.java +++ b/src/com/hippo/ehviewer/ehclient/LofiDetailParser.java @@ -32,6 +32,9 @@ public boolean parser(String body) { Pattern p; Matcher m; + if (body == null) + return false; + // Get preview p = Pattern.compile("
]+>]+href=\"([^>\"]+)\"[^>]+>]+src=\"([^>\"]+)\"[^>]+>"); m = p.matcher(body); diff --git a/src/com/hippo/ehviewer/ehclient/LoginParser.java b/src/com/hippo/ehviewer/ehclient/LoginParser.java index 4b1626240..8877a310c 100644 --- a/src/com/hippo/ehviewer/ehclient/LoginParser.java +++ b/src/com/hippo/ehviewer/ehclient/LoginParser.java @@ -27,6 +27,9 @@ public boolean parser(String body) { Pattern p; Matcher m; + if (body == null) + return false; + p = Pattern.compile("

You are now logged in as: (.+?)
"); m = p.matcher(body); if (m.find()) { diff --git a/src/com/hippo/ehviewer/ehclient/RateParser.java b/src/com/hippo/ehviewer/ehclient/RateParser.java index 7600a66d0..83a82832a 100644 --- a/src/com/hippo/ehviewer/ehclient/RateParser.java +++ b/src/com/hippo/ehviewer/ehclient/RateParser.java @@ -20,13 +20,16 @@ import org.json.JSONObject; public class RateParser { - + public float mRatingAvg; public int mRatingCnt; - - boolean parser(String pageContext) { + + boolean parser(String body) { + if (body == null) + return false; + try { - JSONObject jsonObject = new JSONObject(pageContext); + JSONObject jsonObject = new JSONObject(body); mRatingAvg = (float)jsonObject.getDouble("rating_avg"); mRatingCnt = jsonObject.getInt("rating_cnt"); return true; diff --git a/src/com/hippo/ehviewer/ehclient/VoteParser.java b/src/com/hippo/ehviewer/ehclient/VoteParser.java index 106972f7d..4de217429 100644 --- a/src/com/hippo/ehviewer/ehclient/VoteParser.java +++ b/src/com/hippo/ehviewer/ehclient/VoteParser.java @@ -20,12 +20,15 @@ import org.json.JSONObject; public class VoteParser { - + public String mTagPane; - - boolean parser(String pageContext) { + + boolean parser(String body) { + if (body == null) + return false; + try { - JSONObject jsonObject = new JSONObject(pageContext); + JSONObject jsonObject = new JSONObject(body); mTagPane = jsonObject.getString("tagpane"); return true; } catch (JSONException e) { diff --git a/src/com/hippo/ehviewer/gallery/GalleryView.java b/src/com/hippo/ehviewer/gallery/GalleryView.java index f7ed48a59..b5bc99d6b 100644 --- a/src/com/hippo/ehviewer/gallery/GalleryView.java +++ b/src/com/hippo/ehviewer/gallery/GalleryView.java @@ -23,14 +23,12 @@ import android.graphics.Rect; import android.graphics.RectF; import android.view.MotionEvent; -import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.OvershootInterpolator; import com.hippo.ehviewer.AppHandler; import com.hippo.ehviewer.R; import com.hippo.ehviewer.gallery.data.ImageSet; import com.hippo.ehviewer.gallery.glrenderer.BitmapTexture; -import com.hippo.ehviewer.gallery.glrenderer.ColorTexture; import com.hippo.ehviewer.gallery.glrenderer.GLCanvas; import com.hippo.ehviewer.gallery.glrenderer.GLPaint; import com.hippo.ehviewer.gallery.glrenderer.MovieTexture; @@ -47,18 +45,11 @@ import com.hippo.ehviewer.util.Utils; import com.hippo.ehviewer.widget.MaterialToast; -// TODO 双击加载该页 -// TODO 长按从该页开始加载 - - -// TODO 手动触屏滑动可能闪烁 public class GalleryView extends GLView implements ImageSet.ImageListener, Runnable { @SuppressWarnings("unused") private static final String TAG = GalleryView.class.getSimpleName(); - private static final AccelerateDecelerateInterpolator SCROLL_INTERPOLATOR = new AccelerateDecelerateInterpolator(); - public static final int INVALID_ID = -1; private static final int STATE_FIRST = 0x1; @@ -113,6 +104,7 @@ public class GalleryView extends GLView private static final int TAP_AREA_MASK_COLOR = 0x88000000; private static final int BACKGROUND_COLOR = 0xff212121; + @SuppressWarnings("unused") private static final int MASK_COLOR = 0x88000000; private final GestureRecognizer mGestureRecognizer; @@ -127,6 +119,7 @@ public class GalleryView extends GLView private int scrollXOffset = 0; private int scrollYOffset = 0; private int stopScrollXOffset = 0; + @SuppressWarnings("unused") private int stopScrollYOffset = 0; private float mScale = 1; @@ -646,7 +639,6 @@ private synchronized void loadImage(int index) { if (obj instanceof Integer) { int state = (Integer)obj; if (state == ImageSet.RESULT_DECODE) { - // TODO maybe i should show a decode text showItems[targetIndex] = null; } else if (state == ImageSet.RESULT_DOWNLOADING) { showItems[targetIndex] = new Text("正在下载"); // TODO @@ -937,8 +929,8 @@ protected void onStart() { return; } image = (Image)showItem; - int width = image.getWidth(); - int height = image.getHeight(); + int width = image.width; + int height = image.height; if (width == -1 || height == -1) { mDoubleTapRunner.cancel(); return; @@ -1066,6 +1058,14 @@ public boolean onSingleTapConfirmed(float x, float y) { @Override public boolean onDoubleTap(float x, float y) { + return false; + } + + @Override + public boolean onDoubleTapConfirmed(float x, float y) { + if (isScale) + return true; + ShowItem curShowItem = showItems[CUR_TARGET_INDEX]; if (curShowItem == null || !(curShowItem instanceof Image)) return true; @@ -1236,6 +1236,9 @@ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, @Override public boolean onScaleBegin(float focusX, float focusY) { + if (mDoubleTapAnimating) + return false; + isScale = true; return true; } @@ -1380,51 +1383,8 @@ public void draw(GLCanvas canvas) { } public abstract void draw(GLCanvas canvas, int xOffset, int yOffset); public abstract void recycle(); - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public void getShowRect(Rect rect) { - rect.left = mRect.left; - rect.top = mRect.top; - rect.right = mRect.right; - rect.bottom = mRect.bottom; - } - - public void setShowRect(Rect rect) { - mRect.left = rect.left; - mRect.top = rect.top; - mRect.right = rect.right; - mRect.bottom = rect.bottom; - } } - private class EmptyItem extends ShowItem{ - - private ColorTexture mTexture; - - public EmptyItem() { - mTexture = new ColorTexture(BACKGROUND_COLOR); - } - - @Override - public void recycle() { - mTexture = null; - } - - @Override - public void draw(GLCanvas canvas, int xOffset, int yOffset) { - if (mTexture != null) - mTexture.draw(canvas, xOffset, yOffset); - } - } - - private abstract class Image extends ShowItem{ private UploadedTexture mTexture; public float imageScale = 1; diff --git a/src/com/hippo/ehviewer/gallery/anim/AlphaAnimation.java b/src/com/hippo/ehviewer/gallery/anim/AlphaAnimation.java deleted file mode 100644 index 56baf5e49..000000000 --- a/src/com/hippo/ehviewer/gallery/anim/AlphaAnimation.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.ehviewer.gallery.anim; - -import com.hippo.ehviewer.gallery.glrenderer.GLCanvas; -import com.hippo.ehviewer.util.MathUtils; - -public class AlphaAnimation extends CanvasAnimation { - private final float mStartAlpha; - private final float mEndAlpha; - private float mCurrentAlpha; - - public AlphaAnimation(float from, float to) { - mStartAlpha = from; - mEndAlpha = to; - mCurrentAlpha = from; - } - - @Override - public void apply(GLCanvas canvas) { - canvas.multiplyAlpha(mCurrentAlpha); - } - - @Override - public int getCanvasSaveFlags() { - return GLCanvas.SAVE_FLAG_ALPHA; - } - - @Override - protected void onCalculate(float progress) { - mCurrentAlpha = MathUtils.clamp(mStartAlpha - + (mEndAlpha - mStartAlpha) * progress, 0f, 1f); - } -} diff --git a/src/com/hippo/ehviewer/gallery/anim/FloatAnimation.java b/src/com/hippo/ehviewer/gallery/anim/FloatAnimation.java deleted file mode 100644 index baeafafc1..000000000 --- a/src/com/hippo/ehviewer/gallery/anim/FloatAnimation.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.ehviewer.gallery.anim; - -public class FloatAnimation extends Animation { - - private final float mFrom; - private final float mTo; - private float mCurrent; - - public FloatAnimation(float from, float to, int duration) { - mFrom = from; - mTo = to; - mCurrent = from; - setDuration(duration); - } - - @Override - protected void onCalculate(float progress) { - mCurrent = mFrom + (mTo - mFrom) * progress; - } - - public float get() { - return mCurrent; - } -} diff --git a/src/com/hippo/ehviewer/gallery/ui/GestureRecognizer.java b/src/com/hippo/ehviewer/gallery/ui/GestureRecognizer.java index fb9a375b2..9bf3c2dcd 100644 --- a/src/com/hippo/ehviewer/gallery/ui/GestureRecognizer.java +++ b/src/com/hippo/ehviewer/gallery/ui/GestureRecognizer.java @@ -31,6 +31,7 @@ public class GestureRecognizer { public interface Listener { boolean onSingleTapConfirmed(float x, float y); boolean onDoubleTap(float x, float y); + boolean onDoubleTapConfirmed(float x, float y); void onLongPress(MotionEvent e); boolean onScrollBegin(float dx, float dy, float totalX, float totalY); boolean onScroll(float dx, float dy, float totalX, float totalY); @@ -47,15 +48,15 @@ public interface Listener { private final ScaleGestureDetector mScaleDetector; private final DownUpDetector mDownUpDetector; private final Listener mListener; - + private boolean mStillScroll = false; public GestureRecognizer(Context context, Listener listener) { mListener = listener; - mGestureDetector = new GestureDetector(context, new MyGestureListener(), - null, true /* ignoreMultitouch */); mScaleDetector = new ScaleGestureDetector( context, new MyScaleListener()); + mGestureDetector = new GestureDetector(context, new MyGestureListener(), + null, true /* ignoreMultitouch */); mDownUpDetector = new DownUpDetector(new MyDownUpListener()); } @@ -90,12 +91,21 @@ public boolean onSingleTapConfirmed(MotionEvent e) { public boolean onDoubleTap(MotionEvent e) { return mListener.onDoubleTap(e.getX(), e.getY()); } - + + @Override + public boolean onDoubleTapEvent(MotionEvent e) { + if (e.getAction() == MotionEvent.ACTION_UP || + e.getAction() == MotionEvent.ACTION_CANCEL) + return mListener.onDoubleTapConfirmed(e.getX(), e.getY()); + else + return super.onDoubleTapEvent(e); + } + @Override public void onLongPress(MotionEvent e) { mListener.onLongPress(e); } - + @Override public boolean onScroll( MotionEvent e1, MotionEvent e2, float dx, float dy) { diff --git a/src/com/hippo/ehviewer/service/DownloadService.java b/src/com/hippo/ehviewer/service/DownloadService.java index 585e4f8cc..f7dfbc1eb 100644 --- a/src/com/hippo/ehviewer/service/DownloadService.java +++ b/src/com/hippo/ehviewer/service/DownloadService.java @@ -18,170 +18,68 @@ import android.app.Notification; import android.app.NotificationManager; +import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.IBinder; -import com.hippo.ehviewer.AppContext; import com.hippo.ehviewer.R; -import com.hippo.ehviewer.ui.DownloadInfo; -import com.hippo.ehviewer.util.Download; -import com.hippo.ehviewer.util.Log; - -public class DownloadService extends Service { +import com.hippo.ehviewer.data.Data; +import com.hippo.ehviewer.data.DownloadInfo; +import com.hippo.ehviewer.data.GalleryInfo; +import com.hippo.ehviewer.ehclient.ExDownloader; +import com.hippo.ehviewer.ehclient.ExDownloaderManager; +import com.hippo.ehviewer.ui.DownloadActivity; +import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.util.Utils; + +public class DownloadService extends Service + implements ExDownloader.ListenerForDownload { + @SuppressWarnings("unused") + private static final String TAG = DownloadService.class.getSimpleName(); private static final int DOWNLOAD_NOTIFY_ID = -1; - private static final String TAG = "DownloadService"; - public static final String ACTION_UPDATE = "com.hippo.ehviewer.service.DownloadService"; - public static final String KEY_GID = "gid"; - public static final String KEY_INDEX = "index"; - public static final String KEY_STATE = "state"; - private AppContext mAppContext; + public static final String ACTION_UPDATE = "com.hippo.ehviewer.service.DownloadService"; + private Context mContext; + private Data mData; + private ExDownloaderManager mEdManager; + private volatile DownloadInfo mCurDownloadInfo = null; + private volatile ExDownloader mCurExDownloader = null; private ServiceBinder mBinder = null; - private NotificationManager mNotifyManager; - //private DownloadMangaManager downloadMangaManager; - @Override public void onCreate() { super.onCreate(); - mAppContext = (AppContext)getApplication(); + mContext = getApplication(); + mData = Data.getInstance(); + mEdManager = ExDownloaderManager.getInstance(); mBinder = new ServiceBinder(); mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - - /* - downloadMangaManager = EhClient.getInstance().new DownloadMangaManager(); - - downloadMangaManager.setDownloadService(this); - downloadMangaManager.setOnDownloadMangaListener(new EhClient.OnDownloadMangaListener() { - @Override - public void onDownloadMangaAllStart() { - Notification.Builder builder = new Notification.Builder(getApplicationContext()); - setNotification(builder); - builder.setContentTitle(getString(R.string.start_download_task)) - .setContentText(null) - .setProgress(0, 0, true).setOngoing(true).setAutoCancel(false); - mNotifyManager.notify(DOWNLOAD_NOTIFY_ID, builder.getNotification()); - } - - @Override - public void onDownloadMangaAllOver() { - mNotifyManager.cancel(DOWNLOAD_NOTIFY_ID); - stopSelf(); - } - - @Override - public void onDownloadMangaStart(String id) { - DownloadInfo di = Download.get(id); - if (di == null) - mNotifyManager.cancel(DOWNLOAD_NOTIFY_ID); - else { - Notification.Builder builder = new Notification.Builder(getApplicationContext()); - setNotification(builder); - builder.setContentTitle(getString(R.string.downloading) - + " " + di.title) - .setContentText(null) - .setProgress(0, 0, true).setOngoing(true).setAutoCancel(false); - mNotifyManager.notify(DOWNLOAD_NOTIFY_ID, builder.getNotification()); - } - } - - @Override - public void onDownloadMangaStart(String id, int pageSum, int startIndex) { - DownloadInfo di = Download.get(id); - if (di == null) - mNotifyManager.cancel(DOWNLOAD_NOTIFY_ID); - else { - Notification.Builder builder = new Notification.Builder(getApplicationContext()); - setNotification(builder); - builder.setContentTitle(getString(R.string.downloading) - + " " + di.title) - .setContentText(startIndex + " / " + pageSum) - .setProgress(pageSum, startIndex, false).setOngoing(true) - .setAutoCancel(false); - mNotifyManager.notify(DOWNLOAD_NOTIFY_ID, builder.getNotification()); - mNotifyManager.cancel(Integer.parseInt(id)); - } - } - - @Override - public void onDownloadMangaStop(String id) { - // TODO Auto-generated method stub - - } - - @Override - public void onDownloadMangaOver(String id, boolean ok) { - String mesg = null; - if (ok) - mesg = getString(R.string.download_successfully) + " "; - else - mesg = getString(R.string.download_unsuccessfully) + " "; - DownloadInfo di = Download.get(id); - if (di != null) - mesg += Download.get(id).title; - Notification.Builder builder = new Notification.Builder(getApplicationContext()); - setNotification(builder); - builder.setContentTitle(mesg); - builder.setContentText(null).setProgress(0, 0, false).setOngoing(false); - mNotifyManager.notify(Integer.parseInt(id), builder.getNotification()); - } - - @Override - public void onDownloadPage(String id, int pageSum, int index) { - DownloadInfo di = Download.get(id); - if (di == null) - mNotifyManager.cancel(DOWNLOAD_NOTIFY_ID); - else { - Notification.Builder builder = new Notification.Builder(getApplicationContext()); - setNotification(builder); - builder.setContentTitle(getString(R.string.downloading) - + " " + di.title) - .setContentText(index + " / " + pageSum) - .setProgress(pageSum, index, false).setOngoing(true) - .setAutoCancel(false); - mNotifyManager.notify(DOWNLOAD_NOTIFY_ID, builder.getNotification()); - } - } - - @Override - public void onDownloadPageProgress(String id, int pageSum, - int index, float totalSize, float downloadSize) { - // TODO Auto-generated method stub - - } - }); - */ } private void setNotification(Notification.Builder builder) { builder.setSmallIcon(R.drawable.ic_launcher); - // TODO - //Intent intent = new Intent(DownloadService.this,DownloadActivity.class); - //PendingIntent pendingIntent = PendingIntent.getActivity(DownloadService.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); - //builder.setContentIntent(pendingIntent); + Intent intent = new Intent(DownloadService.this,DownloadActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(DownloadService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); + builder.setContentIntent(pendingIntent); } @Override public int onStartCommand(Intent intent, int flags, int startId) { - Log.d(TAG, "Service onStartCommand"); - return START_NOT_STICKY; } @Override public IBinder onBind(Intent intent) { - Log.d(TAG, "Service onBind"); - return mBinder; } @@ -189,71 +87,88 @@ public IBinder onBind(Intent intent) { public void onDestroy() { super.onDestroy(); - Log.d(TAG, "Service onDestroy"); mNotifyManager.cancel(DOWNLOAD_NOTIFY_ID); mBinder = null; mNotifyManager = null; } - public void add(String gid, String thumb, String detailUrlStr, String title) { - DownloadInfo di = Download.get(gid); - if (di == null) { - di = new DownloadInfo(); - di.status = DownloadInfo.STOP; - di.gid = gid; - di.thumb = thumb; - di.title = title; - di.type = DownloadInfo.DETAIL_URL; - di.detailUrlStr = detailUrlStr; - Download.add(String.valueOf(gid), di); - notifyUpdate(); - } - add(di); + // Try to start download + public void notifyDownloadInfoChanged() { + if (mCurDownloadInfo != null || mCurExDownloader != null) + return; + + mCurDownloadInfo = mData.getFirstWaitDownloadInfo(); + if (mCurDownloadInfo == null) + return; + + mCurDownloadInfo.state = DownloadInfo.STATE_DOWNLOAD; + mCurDownloadInfo.download = -1; + mCurDownloadInfo.total = -1; + + GalleryInfo gi = mCurDownloadInfo.galleryInfo; + mCurExDownloader = mEdManager.getExDownloader(gi.gid, + gi.token, gi.title, mCurDownloadInfo.mode); + mCurExDownloader.setListenerDownload(this); + mCurExDownloader.setDownloadMode(true); } - public void add(String gid, String thumb, String detailUrlStr, - String pageUrlStr, int pageSum, int lastStartIndex, String title) { - DownloadInfo di = Download.get(gid); - if (di == null) { - di = new DownloadInfo(); - di.status = DownloadInfo.STOP; - di.gid = gid; - di.thumb = thumb; - di.title = title; - di.type = DownloadInfo.PAGE_URL; - di.detailUrlStr = detailUrlStr; - di.pageUrlStr = pageUrlStr; - di.pageSum = pageSum; - di.lastStartIndex = lastStartIndex; - Download.add(String.valueOf(gid), di); + /** + * If task is in list, reture false + * @param galleryInfo + * @return + */ + public boolean add(GalleryInfo galleryInfo) { + int gid = galleryInfo.gid; + DownloadInfo di; + if ((di = mData.getDownload(gid)) != null) { + if (di.state != DownloadInfo.STATE_DOWNLOAD) { + di.state = DownloadInfo.STATE_WAIT; + notifyDownloadInfoChanged(); + notifyUpdate(); + } + return false; + } else { + di = new DownloadInfo(galleryInfo, Config.getMode()); + di.state = DownloadInfo.STATE_WAIT; + mData.addDownload(di); + notifyDownloadInfoChanged(); notifyUpdate(); + return true; } - add(di); } - public void add(DownloadInfo di) { - if (di.status == DownloadInfo.DOWNLOADING - || di.status == DownloadInfo.WAITING) - return; - di.status = DownloadInfo.WAITING; - //downloadMangaManager.add(di); - } + public void stop(DownloadInfo di) { + if (mCurDownloadInfo == di) { + // Cancel download notification + mNotifyManager.cancel(DOWNLOAD_NOTIFY_ID); - public void cancel(String id) { - //downloadMangaManager.cancel(id); + // Target downloadinfo is downloading + mCurDownloadInfo.state = DownloadInfo.STATE_NONE; + mData.addDownload(mCurDownloadInfo); + mCurDownloadInfo = null; + + mCurExDownloader.setListenerDownload(null); + mCurExDownloader.setDownloadMode(false); + mEdManager.freeExDownloader(mCurExDownloader); + mCurExDownloader = null; + + notifyDownloadInfoChanged(); + notifyUpdate(); + } else { + di.state = DownloadInfo.STATE_NONE; + notifyUpdate(); + } } - public void notifyUpdate(){ - Intent it = new Intent(ACTION_UPDATE); - sendBroadcast(it); + public void delete(DownloadInfo di) { + stop(di); + mData.deleteDownload(di.galleryInfo.gid); + notifyUpdate(); } - public void notifyUpdate(String gid, int index, int state){ + private void notifyUpdate() { Intent it = new Intent(ACTION_UPDATE); - it.putExtra(KEY_GID, gid); - it.putExtra(KEY_INDEX, index); - it.putExtra(KEY_STATE, state); sendBroadcast(it); } @@ -262,4 +177,90 @@ public DownloadService getService(){ return DownloadService.this; } } + + private String mSpeedStr = null; + + @Override + @SuppressWarnings("deprecation") + public void onStart(int gid) { + if (mCurDownloadInfo == null) + return; + + mCurDownloadInfo.download = -1; + mCurDownloadInfo.total = -1; + + Notification.Builder builder = new Notification.Builder(mContext); + setNotification(builder); + builder.setContentTitle("开始下载 " + gid) + .setContentText(null) + .setProgress(0, 0, true).setOngoing(true).setAutoCancel(false); + mNotifyManager.notify(DOWNLOAD_NOTIFY_ID, builder.getNotification()); + mNotifyManager.cancel(gid); + + notifyUpdate(); + } + + @Override + public void onDownload(int gid, int downloadSize, int totalSize) { + if (mCurDownloadInfo == null) + return; + + mCurDownloadInfo.download = downloadSize; + mCurDownloadInfo.total = totalSize; + Notification.Builder builder = new Notification.Builder(mContext); + setNotification(builder); + builder.setContentTitle("正在下载 " + gid) + .setContentText(mSpeedStr) + .setProgress(totalSize, downloadSize, false).setOngoing(true).setAutoCancel(false); + mNotifyManager.notify(DOWNLOAD_NOTIFY_ID, builder.getNotification()); + + notifyUpdate(); + } + + @Override + public void onUpdateSpeed(int gid, int speed) { + if (mCurDownloadInfo == null) + return; + + mCurDownloadInfo.speed = speed; + mSpeedStr = Utils.sizeToString(speed) + "/S"; + Notification.Builder builder = new Notification.Builder(mContext); + setNotification(builder); + builder.setContentTitle("正在下载 " + gid) + .setContentText(mSpeedStr) + .setProgress(mCurDownloadInfo.total, mCurDownloadInfo.download, + mCurDownloadInfo.total == -1 ? true :false) + .setOngoing(true).setAutoCancel(false); + mNotifyManager.notify(DOWNLOAD_NOTIFY_ID, builder.getNotification()); + + notifyUpdate(); + } + + @Override + public void onDownloadOver(int gid, int legacy) { + if (mCurDownloadInfo == null) + return; + + mCurDownloadInfo.legacy = legacy; + Notification.Builder builder = new Notification.Builder(mContext); + setNotification(builder); + builder.setContentTitle("完成下载 " + gid) + .setContentText(legacy == 0 ? "已完成" : legacy + " 页未下载") + .setOngoing(false).setAutoCancel(true); + mNotifyManager.notify(gid, builder.getNotification()); + mNotifyManager.cancel(DOWNLOAD_NOTIFY_ID); + + mCurDownloadInfo.legacy = legacy; + mCurDownloadInfo.state = DownloadInfo.STATE_FINISH; + mData.addDownload(mCurDownloadInfo); + mCurDownloadInfo = null; + + mCurExDownloader.setListenerDownload(null); + mCurExDownloader.setDownloadMode(false); + mEdManager.freeExDownloader(mCurExDownloader); + mCurExDownloader = null; + + notifyDownloadInfoChanged(); + notifyUpdate(); + } } diff --git a/src/com/hippo/ehviewer/ui/AbstractActivity.java b/src/com/hippo/ehviewer/ui/AbsActivity.java similarity index 97% rename from src/com/hippo/ehviewer/ui/AbstractActivity.java rename to src/com/hippo/ehviewer/ui/AbsActivity.java index 518fb8330..d5e79a36a 100644 --- a/src/com/hippo/ehviewer/ui/AbstractActivity.java +++ b/src/com/hippo/ehviewer/ui/AbsActivity.java @@ -25,7 +25,7 @@ import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.util.Ui; -public abstract class AbstractActivity extends Activity +public abstract class AbsActivity extends Activity implements OnOrientationChangedListener { private static final int[] padding = new int[2]; diff --git a/src/com/hippo/ehviewer/ui/AbstractGalleryActivity.java b/src/com/hippo/ehviewer/ui/AbsGalleryActivity.java similarity index 98% rename from src/com/hippo/ehviewer/ui/AbstractGalleryActivity.java rename to src/com/hippo/ehviewer/ui/AbsGalleryActivity.java index 9aa059138..55cd5c789 100644 --- a/src/com/hippo/ehviewer/ui/AbstractGalleryActivity.java +++ b/src/com/hippo/ehviewer/ui/AbsGalleryActivity.java @@ -38,11 +38,11 @@ import com.hippo.ehviewer.widget.PullViewGroup; import com.hippo.ehviewer.widget.RefreshTextView; -public abstract class AbstractGalleryActivity extends AbstractSlidingActivity +public abstract class AbsGalleryActivity extends AbsSlidingActivity implements PullViewGroup.OnFooterRefreshListener, PullViewGroup.OnRefreshListener { @SuppressWarnings("unused") - private static final String TAG = AbstractGalleryActivity.class.getSimpleName(); + private static final String TAG = AbsGalleryActivity.class.getSimpleName(); private static final int MODE_REFRESH = 0x0; private static final int MODE_NEXT_PAGE = 0x1; diff --git a/src/com/hippo/ehviewer/ui/AbstractPreferenceActivity.java b/src/com/hippo/ehviewer/ui/AbsPreferenceActivity.java similarity index 96% rename from src/com/hippo/ehviewer/ui/AbstractPreferenceActivity.java rename to src/com/hippo/ehviewer/ui/AbsPreferenceActivity.java index a061ec3fc..a934ca20a 100644 --- a/src/com/hippo/ehviewer/ui/AbstractPreferenceActivity.java +++ b/src/com/hippo/ehviewer/ui/AbsPreferenceActivity.java @@ -24,7 +24,7 @@ import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.util.Ui; -public abstract class AbstractPreferenceActivity extends PreferenceActivity +public abstract class AbsPreferenceActivity extends PreferenceActivity implements OnOrientationChangedListener { private static final int[] padding = new int[2]; diff --git a/src/com/hippo/ehviewer/ui/AbstractSlidingActivity.java b/src/com/hippo/ehviewer/ui/AbsSlidingActivity.java similarity index 96% rename from src/com/hippo/ehviewer/ui/AbstractSlidingActivity.java rename to src/com/hippo/ehviewer/ui/AbsSlidingActivity.java index 61410eff1..302a747ad 100644 --- a/src/com/hippo/ehviewer/ui/AbstractSlidingActivity.java +++ b/src/com/hippo/ehviewer/ui/AbsSlidingActivity.java @@ -25,7 +25,7 @@ import com.hippo.ehviewer.util.Ui; import com.jeremyfeinstein.slidingmenu.lib.app.SlidingActivity; -public abstract class AbstractSlidingActivity extends SlidingActivity +public abstract class AbsSlidingActivity extends SlidingActivity implements OnOrientationChangedListener { private static final int[] padding = new int[2]; diff --git a/src/com/hippo/ehviewer/ui/DownloadActivity.java b/src/com/hippo/ehviewer/ui/DownloadActivity.java new file mode 100644 index 000000000..98a61c687 --- /dev/null +++ b/src/com/hippo/ehviewer/ui/DownloadActivity.java @@ -0,0 +1,366 @@ +/* + * Copyright (C) 2014 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.ui; + +import java.util.List; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; +import android.widget.AdapterView; +import android.widget.BaseAdapter; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.hippo.ehviewer.ImageLoader; +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.cardview.CardViewSalon; +import com.hippo.ehviewer.data.Data; +import com.hippo.ehviewer.data.DownloadInfo; +import com.hippo.ehviewer.data.GalleryInfo; +import com.hippo.ehviewer.service.DownloadService; +import com.hippo.ehviewer.service.DownloadServiceConnection; +import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.util.EhUtils; +import com.hippo.ehviewer.util.Theme; +import com.hippo.ehviewer.util.Ui; +import com.hippo.ehviewer.util.Utils; +import com.hippo.ehviewer.widget.AlertButton; +import com.hippo.ehviewer.widget.DialogBuilder; +import com.hippo.ehviewer.widget.LoadImageView; +import com.hippo.ehviewer.windowsanimate.WindowsAnimate; + +public class DownloadActivity extends AbsActivity implements AbsListView.OnItemClickListener { + + private WindowsAnimate mWindowsAnimate; + private int mThemeColor; + private List mDownloads; + + private ListView mList; + private ListAdapter mAdapter; + + private final DownloadServiceConnection mServiceConn = new DownloadServiceConnection(); + private final BroadcastReceiver mReceiver = new BroadcastReceiver(){ + @Override + public void onReceive(Context context, Intent intent) { + if(intent.getAction().equals(DownloadService.ACTION_UPDATE)) + mAdapter.notifyDataSetChanged(); + } + }; + + @Override + public void onOrientationChanged(int paddingTop, int paddingBottom) { + if (mList != null) { + mList.setPadding(mList.getPaddingLeft(), paddingTop, + mList.getPaddingRight(), paddingBottom); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.download); + + // Init windows animate + mWindowsAnimate = new WindowsAnimate(); + mWindowsAnimate.init(this); + + // Service + Intent it = new Intent(this, DownloadService.class); + bindService(it, mServiceConn, BIND_AUTO_CREATE); + // Receiver + IntentFilter filter = new IntentFilter(); + filter.addAction(DownloadService.ACTION_UPDATE); + registerReceiver(mReceiver, filter); + + mDownloads = Data.getInstance().getAllDownloads(); + for (DownloadInfo di : mDownloads) + di.selected = false; + + mList = (ListView)findViewById(R.id.download); + + mAdapter = new ListAdapter(); + + mList.setAdapter(mAdapter); + mList.setOnItemClickListener(this); + mList.setSelector(new ColorDrawable(Color.TRANSPARENT)); + + mThemeColor = Config.getRandomThemeColor() ? Theme.getRandomDarkColor() : Config.getThemeColor(); + int actionBarColor = mThemeColor & 0x00ffffff | 0xdd000000; + Drawable drawable = new ColorDrawable(actionBarColor); + getActionBar().setBackgroundDrawable(drawable); + Ui.translucent(this, actionBarColor); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(mReceiver); + unbindService(mServiceConn); + mWindowsAnimate.free(); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, + long id) { + DownloadInfo di = mDownloads.get(position); + di.selected = !di.selected; + mAdapter.notifyDataSetChanged(); + } + + public class ListAdapter extends BaseAdapter { + @Override + public int getCount() { + return mDownloads.size(); + } + + @Override + public Object getItem(int position) { + return mDownloads.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + // TODO chinese string + @Override + public View getView(int position, View convertView, ViewGroup parent) { + final DownloadInfo di = mDownloads.get(position); + final GalleryInfo gi = di.galleryInfo; + + if (convertView == null) { + convertView = LayoutInflater.from(DownloadActivity.this) + .inflate(R.layout.download_list_item, parent, false); + CardViewSalon.reformWithShadow(((ViewGroup)convertView).getChildAt(0), + 0xFFFAFAFA, 0, false); // TODO + mWindowsAnimate.addRippleEffect(((ViewGroup)convertView).getChildAt(0), true); + ((TextView)convertView.findViewById(R.id.action)).setTextColor(mThemeColor); + } + LoadImageView thumb = (LoadImageView)convertView.findViewById(R.id.thumb); + if (!String.valueOf(gi.gid).equals(thumb.getKey())) { + // Set margin top 8dp if position is 0, otherwise 4dp + LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) + convertView.findViewById(R.id.card_view).getLayoutParams(); + if (position == 0) + lp.topMargin = Ui.dp2pix(8); + else + lp.topMargin = Ui.dp2pix(4); + + // Set new thumb + thumb.setImageDrawable(null); + thumb.setLoadInfo(gi.thumb, String.valueOf(gi.gid)); + ImageLoader.getInstance(DownloadActivity.this).add(gi.thumb, String.valueOf(gi.gid), + new LoadImageView.SimpleImageGetListener(thumb).setFixScaleType(true)); + } + TextView title = (TextView)convertView.findViewById(R.id.title); + title.setText(gi.title); + View Buttons = convertView.findViewById(R.id.buttons); + if (di.selected) + Buttons.setVisibility(View.VISIBLE); + else + Buttons.setVisibility(View.GONE); + + ProgressBar pb = (ProgressBar)convertView.findViewById(R.id.progress_bar); + TextView leftText = (TextView)convertView.findViewById(R.id.text_left); + TextView rightText = (TextView)convertView.findViewById(R.id.text_right); + + View read = convertView.findViewById(R.id.read); + TextView action = (TextView)convertView.findViewById(R.id.action); + View delete1 = convertView.findViewById(R.id.delete1); + View delete2 = convertView.findViewById(R.id.delete2); + View detail = convertView.findViewById(R.id.detail); + + + read.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(DownloadActivity.this, + GalleryActivity.class); + intent.putExtra(GalleryActivity.KEY_GID, gi.gid); + intent.putExtra(GalleryActivity.KEY_TOKEN, gi.token); + intent.putExtra(GalleryActivity.KEY_TITLE, gi.title); + intent.putExtra(GalleryActivity.KEY_START_INDEX, 0); + startActivity(intent); + } + }); + delete1.setOnClickListener(new Delete1Action(di)); + delete2.setOnClickListener(new Delete2Action(di)); + detail.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(DownloadActivity.this, + GalleryDetailActivity.class); + intent.putExtra(GalleryDetailActivity.KEY_G_INFO, gi); + startActivity(intent); + } + }); + + switch (di.state) { + case DownloadInfo.STATE_NONE: + pb.setVisibility(View.INVISIBLE); + leftText.setText("未启动"); + rightText.setVisibility(View.GONE); + + action.setText(getString(R.string.start)); + action.setOnClickListener(new StartAction(di)); + break; + + case DownloadInfo.STATE_WAIT: + pb.setVisibility(View.INVISIBLE); + leftText.setText("等待中"); + rightText.setVisibility(View.GONE); + + action.setText(getString(R.string.stop)); + action.setOnClickListener(new StopAction(di)); + break; + + case DownloadInfo.STATE_DOWNLOAD: + leftText.setText(Utils.sizeToString(di.speed) + "/S"); + if (di.total == -1) { + pb.setVisibility(View.VISIBLE); + pb.setIndeterminate(true); + rightText.setVisibility(View.GONE); + } else { + pb.setVisibility(View.VISIBLE); + pb.setIndeterminate(false); + pb.setMax(di.total); + pb.setProgress(di.download); + rightText.setVisibility(View.VISIBLE); + rightText.setText(di.download + "/" + di.total); + } + + action.setText(getString(R.string.stop)); + action.setOnClickListener(new StopAction(di)); + break; + + case DownloadInfo.STATE_FINISH: + pb.setVisibility(View.INVISIBLE); + if (di.legacy == 0) + leftText.setText("已完成"); + else + leftText.setText(di.legacy + " 页未下载"); + rightText.setVisibility(View.GONE); + + action.setText(getString(R.string.start)); + action.setOnClickListener(new StartAction(di)); + break; + } + return convertView; + } + } + + private class Delete1Action implements View.OnClickListener { + public DownloadInfo mDownloadInfo; + + public Delete1Action(DownloadInfo di) { + mDownloadInfo = di; + } + + @Override + public void onClick(View v) { + new DialogBuilder(DownloadActivity.this).setTitle(R.string.attention) + .setMessage(R.string.delete).setSimpleNegativeButton() + .setPositiveButton(android.R.string.ok, new View.OnClickListener() { + @Override + public void onClick(View v) { + ((AlertButton)v).dialog.dismiss(); + Intent it = new Intent(DownloadActivity.this, DownloadService.class); + startService(it); + mServiceConn.getService().delete(mDownloadInfo); + } + }).create().show(); + } + } + + private class Delete2Action implements View.OnClickListener { + public DownloadInfo mDownloadInfo; + + public Delete2Action(DownloadInfo di) { + mDownloadInfo = di; + } + + @Override + public void onClick(View v) { + new DialogBuilder(DownloadActivity.this).setTitle(R.string.attention) + .setMessage(R.string.delete2).setSimpleNegativeButton() + .setPositiveButton(android.R.string.ok, new View.OnClickListener() { + @Override + public void onClick(View v) { + ((AlertButton)v).dialog.dismiss(); + Intent it = new Intent(DownloadActivity.this, DownloadService.class); + startService(it); + mServiceConn.getService().delete(mDownloadInfo); + // Delete dir + GalleryInfo gi = mDownloadInfo.galleryInfo; + Utils.deleteDirInThread(EhUtils.getGalleryDir(gi.gid, gi.title)); + } + }).create().show(); + } + } + + private class StartAction implements View.OnClickListener { + public DownloadInfo mDownloadInfo; + + public StartAction(DownloadInfo di) { + mDownloadInfo = di; + } + + @Override + public void onClick(View v) { + if (mDownloadInfo.state == DownloadInfo.STATE_NONE || + mDownloadInfo.state == DownloadInfo.STATE_FINISH) { + mDownloadInfo.state = DownloadInfo.STATE_WAIT; + + Intent it = new Intent(DownloadActivity.this, DownloadService.class); + startService(it); + mServiceConn.getService().notifyDownloadInfoChanged(); + mAdapter.notifyDataSetChanged(); + } + } + } + + + private class StopAction implements View.OnClickListener { + + public DownloadInfo mDownloadInfo; + + public StopAction(DownloadInfo di) { + mDownloadInfo = di; + } + + @Override + public void onClick(View v) { + Intent it = new Intent(DownloadActivity.this, DownloadService.class); + startService(it); + mServiceConn.getService().stop(mDownloadInfo); + mAdapter.notifyDataSetChanged(); + } + } +} diff --git a/src/com/hippo/ehviewer/ui/DownloadInfo.java b/src/com/hippo/ehviewer/ui/DownloadInfo.java deleted file mode 100644 index 311ee1f74..000000000 --- a/src/com/hippo/ehviewer/ui/DownloadInfo.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2014 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.ehviewer.ui; - -public class DownloadInfo { - public static final int STOP = 0x0; - public static final int DOWNLOADING = 0x1; - public static final int WAITING = 0x2; - public static final int COMPLETED = 0x3; - public static final int FAILED = 0x4; - - public static final boolean DETAIL_URL = false; - public static final boolean PAGE_URL = true; - - public String gid; - public String thumb; - public String title; - public int status = STOP; - public boolean type; - - public String detailUrlStr; - - public int pageSum = 0; - public int lastStartIndex = 1; - public String pageUrlStr; - - public float totalSize; - public float downloadSize; -} diff --git a/src/com/hippo/ehviewer/ui/FavouriteActivity.java b/src/com/hippo/ehviewer/ui/FavouriteActivity.java index 9bead238f..eae612411 100644 --- a/src/com/hippo/ehviewer/ui/FavouriteActivity.java +++ b/src/com/hippo/ehviewer/ui/FavouriteActivity.java @@ -73,7 +73,7 @@ import com.hippo.ehviewer.widget.RatingView; import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu; -public class FavouriteActivity extends AbstractGalleryActivity +public class FavouriteActivity extends AbsGalleryActivity implements ListView.MultiChoiceModeListener, View.OnTouchListener { @SuppressWarnings("unused") diff --git a/src/com/hippo/ehviewer/ui/GalleryActivity.java b/src/com/hippo/ehviewer/ui/GalleryActivity.java index 43a65cad3..f6dcac08f 100644 --- a/src/com/hippo/ehviewer/ui/GalleryActivity.java +++ b/src/com/hippo/ehviewer/ui/GalleryActivity.java @@ -42,7 +42,7 @@ import com.hippo.ehviewer.widget.AlertButton; import com.hippo.ehviewer.widget.DialogBuilder; -public class GalleryActivity extends AbstractActivity +public class GalleryActivity extends AbsActivity implements GalleryView.GalleryViewListener, SeekBar.OnSeekBarChangeListener { @SuppressWarnings("unused") private final static String TAG = GalleryActivity.class.getSimpleName(); @@ -232,7 +232,7 @@ public void onClick(View v) { if (Config.getGalleryFirst()) { Config.setGalleryFirst(false); new DialogBuilder(this).setTitle("提示") - .setMessage("长按屏幕,可使下载从当前页面开始") // TODO + .setMessage("长按屏幕,可使下载从当前页面开始。若该项正在下载,则仅优先加载当前页面。") // TODO .setSimpleNegativeButton().create().show(); } } diff --git a/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java b/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java index dd2e7b504..b8476b090 100644 --- a/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java +++ b/src/com/hippo/ehviewer/ui/GalleryDetailActivity.java @@ -97,7 +97,7 @@ import com.hippo.ehviewer.widget.SuperButton; import com.hippo.ehviewer.windowsanimate.WindowsAnimate; -public class GalleryDetailActivity extends AbstractActivity +public class GalleryDetailActivity extends AbsActivity implements View.OnClickListener, ResponedScrollView.OnScrollStateChangedListener, View.OnTouchListener , ViewSwitcher.ViewFactory, @@ -815,9 +815,7 @@ public void onClick(View v) { if (v == mDownloadButton) { Intent it = new Intent(GalleryDetailActivity.this, DownloadService.class); startService(it); - mServiceConn.getService().add(String.valueOf(mGalleryInfo.gid), mGalleryInfo.thumb, - EhClient.getDetailUrl(mGalleryInfo.gid, mGalleryInfo.token, 0, Config.getMode()), - mGalleryInfo.title); + mServiceConn.getService().add(mGalleryInfo); MaterialToast.showToast(R.string.toast_add_download); } else if (v == mReadButton) { //mData.addRead(mGalleryInfo); diff --git a/src/com/hippo/ehviewer/ui/GalleryListActivity.java b/src/com/hippo/ehviewer/ui/GalleryListActivity.java index e9a818bae..a8a63c54d 100644 --- a/src/com/hippo/ehviewer/ui/GalleryListActivity.java +++ b/src/com/hippo/ehviewer/ui/GalleryListActivity.java @@ -121,7 +121,7 @@ * * @author Hippo */ -public class GalleryListActivity extends AbstractGalleryActivity +public class GalleryListActivity extends AbsGalleryActivity implements View.OnClickListener { @SuppressWarnings("unused") @@ -543,8 +543,7 @@ public void onItemClick(AdapterView arg0, View arg1, gi = getGalleryInfo(longClickItemIndex); Intent it = new Intent(GalleryListActivity.this, DownloadService.class); startService(it); - mServiceConn.getService().add(String.valueOf(gi.gid), gi.thumb, - mClient.getDetailUrl(gi.gid, gi.token), gi.title); + mServiceConn.getService().add(gi); MaterialToast.showToast(R.string.toast_add_download); break; default: @@ -1060,9 +1059,8 @@ public void onItemClick(AdapterView parent, View view, break; case 5: // Download - // TODO Download Activity intent = new Intent(GalleryListActivity.this, - GalleryActivity.class); + DownloadActivity.class); startActivity(intent); break; @@ -1143,7 +1141,6 @@ public void onItemClick(AdapterView arg0, View arg1, Intent intent = new Intent(GalleryListActivity.this, GalleryDetailActivity.class); GalleryInfo gi = getGalleryInfo(position); - intent.putExtra("url", mClient.getDetailUrl(gi.gid, gi.token)); intent.putExtra(GalleryDetailActivity.KEY_G_INFO, gi); startActivity(intent); } @@ -1412,7 +1409,6 @@ protected void onDestroy() { e.printStackTrace(); } }*/ - mData.deleteAllReads(); mWindowsAnimate.free(); } diff --git a/src/com/hippo/ehviewer/ui/SettingsActivity.java b/src/com/hippo/ehviewer/ui/SettingsActivity.java index b728247ca..48b907a33 100644 --- a/src/com/hippo/ehviewer/ui/SettingsActivity.java +++ b/src/com/hippo/ehviewer/ui/SettingsActivity.java @@ -67,7 +67,7 @@ import com.hippo.ehviewer.widget.MaterialToast; import com.hippo.ehviewer.widget.SuperDialogUtil; -public class SettingsActivity extends AbstractPreferenceActivity { +public class SettingsActivity extends AbsPreferenceActivity { @SuppressWarnings("unused") private static String TAG = SettingsActivity.class.getSimpleName(); diff --git a/src/com/hippo/ehviewer/util/BgThread.java b/src/com/hippo/ehviewer/util/BgThread.java new file mode 100644 index 000000000..cdefd3187 --- /dev/null +++ b/src/com/hippo/ehviewer/util/BgThread.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2014 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.util; + +import android.os.Process; + +public class BgThread extends Thread { + + public BgThread() { + super(); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } + + public BgThread(Runnable runnable) { + super(runnable); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } + + public BgThread(Runnable runnable, String threadName) { + super(runnable, threadName); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } + + public BgThread(String threadName) { + super(threadName); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } + + public BgThread(ThreadGroup group, Runnable runnable) { + super(group, runnable); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } + + public BgThread(ThreadGroup group, Runnable runnable, String threadName) { + super(group, runnable, threadName); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } + + public BgThread(ThreadGroup group, String threadName) { + super(group, threadName); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } + + public BgThread(ThreadGroup group, Runnable runnable, String threadName, long stackSize) { + super(group, runnable, threadName, stackSize); + setPriority(Process.THREAD_PRIORITY_BACKGROUND); + } +} diff --git a/src/com/hippo/ehviewer/util/Download.java b/src/com/hippo/ehviewer/util/Download.java deleted file mode 100644 index e64590482..000000000 --- a/src/com/hippo/ehviewer/util/Download.java +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2014 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.ehviewer.util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.ArrayList; - -import android.content.Context; -import android.content.SharedPreferences; - -import com.hippo.ehviewer.data.ListUrls; -import com.hippo.ehviewer.ui.DownloadInfo; - -public class Download { - private static final String SHA_PRE_NAME = "download_info"; - private static final String LIST_ORDER = "list_order"; - - private static Context mContext; - private static SharedPreferences mDownloadInfoPre; - private static ArrayList mListOrder = new ArrayList(); - private static ArrayList mDownloadInfos = new ArrayList(); - - private static boolean mInit = false; - - /** - * Init Tag - * - * @param context Application context - */ - public static void init(Context context) { - if (mInit) - return; - mInit = true; - - mContext = context; - mDownloadInfoPre = mContext.getSharedPreferences(SHA_PRE_NAME, 0); - - getDownloadInfo(); - } - - /** - * Is init - * @return True if init - */ - public static boolean isInit() { - return mInit; - } - - private static void getDownloadInfo() { - String[] allOrder = Utils.getStrings(mDownloadInfoPre, LIST_ORDER); - - if (allOrder == null) - return; - - boolean errorFlag = false; - for (String item : allOrder) { - mListOrder.add(item); - String strDownloadInfo = mDownloadInfoPre.getString(item, null); - if (strDownloadInfo == null) { - mListOrder.remove(strDownloadInfo); - errorFlag = true; - continue; - } - DownloadInfo di = decode(strDownloadInfo); - if (di.status == DownloadInfo.DOWNLOADING - || di.status == DownloadInfo.WAITING) - di.status = DownloadInfo.STOP; - - mDownloadInfos.add(di); - } - if (errorFlag) - Utils.putStrings(mDownloadInfoPre, LIST_ORDER, mListOrder); - } - - /** - * Add a new tag item to the end of tag list - * - * @param key - * @param tag - * @return - */ - public static boolean add(String key, DownloadInfo di) { - // Check contain this item or not - if (mListOrder.indexOf(key) == -1) { - mListOrder.add(key); - mDownloadInfos.add(di); - Utils.putStrings(mDownloadInfoPre, LIST_ORDER, mListOrder); - mDownloadInfoPre.edit().putString(key, encode(di)).apply(); - return true; - } else - return false; - } - - /** - * Swap tag list order - * - * @param oldIndex - * @param newIndex - * @return - */ - public static boolean swap(int indexOne, int indexTwo) { - if (indexOne < 0 || indexOne > mListOrder.size() - || indexTwo < 0 || indexTwo > mListOrder.size()) - return false; - - if (indexOne == indexTwo) - return true; - - String temp1 = mListOrder.get(indexOne); - mListOrder.set(indexOne, mListOrder.get(indexTwo)); - mListOrder.set(indexTwo, temp1); - Utils.putStrings(mDownloadInfoPre, LIST_ORDER, mListOrder); - - DownloadInfo temp2 = mDownloadInfos.get(indexOne); - mDownloadInfos.set(indexOne, mDownloadInfos.get(indexTwo)); - mDownloadInfos.set(indexTwo, temp2); - return true; - } - - public static boolean contains(String key) { - return mListOrder.contains(key); - } - - /** - * Remove Tag item - * - * @param index - * @return True if remove successfully - */ - public static boolean remove(String key) { - int index = mListOrder.indexOf(key); - if (index != -1) { - mListOrder.remove(index); - mDownloadInfos.remove(index); - mDownloadInfoPre.edit().remove(key).apply(); - Utils.putStrings(mDownloadInfoPre, LIST_ORDER, mListOrder); - return true; - } else - return false; - } - - /** - * Remove Tag item - * - * @param index - * @return True if remove successfully - */ - public static boolean remove(int index) { - mDownloadInfos.remove(index); - String key = mListOrder.remove(index); - mDownloadInfoPre.edit().remove(key).apply(); - Utils.putStrings(mDownloadInfoPre, LIST_ORDER, mListOrder); - return true; - } - - public static DownloadInfo get(String key) { - int index = mListOrder.indexOf(key); - if (index == -1) - return null; - return mDownloadInfos.get(index); - } - - /** - * You must not modify what you get - * - * @return - */ - public static ArrayList getDownloadInfoList() { - return mDownloadInfos; - } - - public static DownloadInfo get(int position) { - return mDownloadInfos.get(position); - } - - public static String getKey(int position) { - return mListOrder.get(position); - } - - public static ArrayList getKeys() { - return mListOrder; - } - - public static void notify(String key) { - int index = mListOrder.indexOf(key); - if (index != -1) { - mDownloadInfoPre.edit().putString(key, encode(mDownloadInfos.get(index))).apply(); - } - } - - protected static String encode(DownloadInfo di) { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - try { - ObjectOutputStream outputStream = new ObjectOutputStream(os); - writeObject(di, outputStream); - } catch (Exception e) { - e.printStackTrace(); - return null; - } finally { - try { - os.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return Utils.byteArrayToHexString(os.toByteArray()); - } - - protected static DownloadInfo decode(String strDi) { - byte[] bytes = Utils.hexStringToByteArray(strDi); - ByteArrayInputStream is = new ByteArrayInputStream(bytes); - DownloadInfo di = null; - try { - ObjectInputStream ois = new ObjectInputStream(is); - di = readObject(ois); - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - is.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return di; - } - - public static void writeObject(DownloadInfo di, ObjectOutputStream out) throws IOException { - out.writeObject(di.gid); - out.writeObject(di.thumb); - out.writeObject(di.title); - out.writeObject((Integer)di.status); - out.writeObject((Boolean)di.type); - out.writeObject(di.detailUrlStr); - out.writeObject((Integer)di.pageSum); - out.writeObject((Integer)di.lastStartIndex); - out.writeObject(di.pageUrlStr); - } - - public static DownloadInfo readObject(ObjectInputStream in) { - DownloadInfo di = new DownloadInfo(); - try { - di.gid = (String)in.readObject(); - di.thumb = (String)in.readObject(); - di.title = (String)in.readObject(); - di.status = (Integer)in.readObject(); - di.type = (Boolean)in.readObject(); - di.detailUrlStr = (String)in.readObject(); - di.pageSum = (Integer)in.readObject(); - di.lastStartIndex = (Integer)in.readObject(); - di.pageUrlStr = (String)in.readObject(); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - return di; - } -} diff --git a/src/com/hippo/ehviewer/util/EhUtils.java b/src/com/hippo/ehviewer/util/EhUtils.java index f9da08ec1..6bb9d58b5 100644 --- a/src/com/hippo/ehviewer/util/EhUtils.java +++ b/src/com/hippo/ehviewer/util/EhUtils.java @@ -20,6 +20,8 @@ public final class EhUtils { + public static final String EH_DOWNLOAD_FILENAME = ".ehviewer"; + /** * Get gallery for read and download * @param gid diff --git a/src/com/hippo/ehviewer/util/SqlUtils.java b/src/com/hippo/ehviewer/util/SqlUtils.java new file mode 100644 index 000000000..80b20cd9f --- /dev/null +++ b/src/com/hippo/ehviewer/util/SqlUtils.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.util; + +import java.util.ArrayList; +import java.util.List; + +import android.database.Cursor; +import android.database.SQLException; +import android.database.sqlite.SQLiteDatabase; + +public final class SqlUtils { + + public static void exeSQLSafely(SQLiteDatabase db, String sql) { + try { + db.execSQL(sql); + } catch (SQLException e) {} + } + + public static void dropTable(SQLiteDatabase db, String tableName) { + exeSQLSafely(db, "DROP TABLE IF EXISTS " + tableName); + } + + public static void dropAllTable(SQLiteDatabase db) { + List tables = new ArrayList(); + Cursor cursor = db.rawQuery("SELECT * FROM sqlite_master WHERE type='table';", null); + cursor.moveToFirst(); + while (!cursor.isAfterLast()) { + String tableName = cursor.getString(1); + if (!tableName.equals("android_metadata") && + !tableName.equals("sqlite_sequence")) + tables.add(tableName); + cursor.moveToNext(); + } + cursor.close(); + + for(String tableName : tables) { + dropTable(db, tableName); + } + } +} diff --git a/src/com/hippo/ehviewer/util/Theme.java b/src/com/hippo/ehviewer/util/Theme.java index cae30cd71..906e2db7f 100644 --- a/src/com/hippo/ehviewer/util/Theme.java +++ b/src/com/hippo/ehviewer/util/Theme.java @@ -16,8 +16,6 @@ package com.hippo.ehviewer.util; -import java.util.Random; - import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; @@ -26,16 +24,14 @@ public final class Theme { - private static final Random random = - new Random(System.currentTimeMillis()); public static final int GREY_COLOR = 0xffaaaaaa; public static final ColorDrawable GREY_DRAWABLE = new ColorDrawable(0xffaaaaaa); private static final int[] DARK_COLOR_TABLE = { - 0xffe51c23, 0xffe91e63, 0xff9c27b0, - 0xff673ab7, 0xff3f51b5, 0xff5677fc, - 0xff03a9f4, 0xff009688, 0xff259b24 + 0xffe91e63, 0xff9c27b0, 0xff673ab7, + 0xff3f51b5, 0xff5677fc, 0xff03a9f4, + 0xff009688, 0xff259b24 }; /** @@ -43,7 +39,7 @@ public final class Theme { * @return */ public static int getRandomDarkColor() { - return DARK_COLOR_TABLE[Math.abs(random.nextInt()) % DARK_COLOR_TABLE.length]; + return DARK_COLOR_TABLE[Math.abs(MathUtils.random(DARK_COLOR_TABLE.length))]; } /** diff --git a/src/com/hippo/ehviewer/util/Utils.java b/src/com/hippo/ehviewer/util/Utils.java index 4522f0a9a..3f670405b 100644 --- a/src/com/hippo/ehviewer/util/Utils.java +++ b/src/com/hippo/ehviewer/util/Utils.java @@ -68,33 +68,6 @@ public static void copy(InputStream is, OutputStream os, int size) throws IOExce buffer = null; } - public static final int BITMAP = 0x0; - public static final int MOVIE = 0x1; - - public static int getResourcesType(String url) { - int type = BITMAP; - int index = url.lastIndexOf('.'); - if (index != -1 && getExtension(url).equals("gif")) - type = MOVIE; - return type; - } - - public static String getExtension(String url) { - int index = url.lastIndexOf('.'); - if (index != -1) - return url.substring(index + 1).toLowerCase(); - else - return "png"; - } - - public static String getName(String fileName) { - int index = fileName.lastIndexOf('.'); - if (index != -1) - return fileName.substring(0, index).toLowerCase(); - else - return "png"; - } - public static boolean isNumber(String str) { for (int i = 0; i < str.length(); i++) { char ch = str.charAt(i); @@ -147,15 +120,6 @@ public static String InputStream2String(InputStream is, String charset) { return str; } - public static String getFileForUrl(String url) { - String file = null; - int index = url.lastIndexOf("/"); - if (index == -1) - return url; - else - return url.substring(index + 1); - } - public static String[] getStrings(SharedPreferences shaper, String key) { String str = shaper.getString(key, null); if (str == null || str.length() == 0) @@ -184,26 +148,31 @@ public static void closeQuietly (Closeable is) { } /** - * Delete dir and it child file and dir + * Try to delete file, dir and it's children * * @param dir * The dir to deleted - * @throws IOException */ - public static void deleteContents(File dir) throws IOException { - File[] files = dir.listFiles(); - if (files == null) { - throw new IOException("not a readable directory: " + dir); - } - for (File file : files) { - if (file.isDirectory()) { - deleteContents(file); - } - if (!file.delete()) { - throw new IOException("failed to delete file: " + file); - } + public static void deleteFile(File file) { + File[] files = file.listFiles(); + if (files != null) { + for (File f : files) + deleteFile(f); } - } + file.delete(); + } + + /** + * Start a new thread to delete dir + */ + public static void deleteDirInThread(final File file) { + new BgThread() { + @Override + public void run() { + deleteFile(file); + } + }.start(); + } @SuppressLint("SimpleDateFormat") public static int getDate() { diff --git a/src/com/hippo/ehviewer/widget/DownloadItemLayout.java b/src/com/hippo/ehviewer/widget/DownloadItemLayout.java deleted file mode 100644 index 1ed25d55b..000000000 --- a/src/com/hippo/ehviewer/widget/DownloadItemLayout.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2014 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.ehviewer.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.LinearLayout; - -public class DownloadItemLayout extends LinearLayout { - - public String gid; - public int status; - public boolean type; - public int lastStartIndex; - public float downloadSize; - public boolean isWait; - - public DownloadItemLayout(Context context) { - super(context); - } - - public DownloadItemLayout(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public DownloadItemLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } -} diff --git a/src/com/hippo/ehviewer/windowsanimate/RippleSprite.java b/src/com/hippo/ehviewer/windowsanimate/RippleSprite.java index 48ed67dc5..29b36037f 100644 --- a/src/com/hippo/ehviewer/windowsanimate/RippleSprite.java +++ b/src/com/hippo/ehviewer/windowsanimate/RippleSprite.java @@ -23,12 +23,12 @@ import android.annotation.TargetApi; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.PointF; import android.graphics.Rect; import android.os.Build; import android.view.View; import android.view.animation.LinearInterpolator; -import com.hippo.ehviewer.R; import com.hippo.ehviewer.util.MathUtils; import com.hippo.ehviewer.util.Ui; import com.hippo.ehviewer.util.ViewUtils; @@ -39,6 +39,8 @@ * Get lots of code from android.graphics.drawable.Ripple */ public class RippleSprite extends Sprite { + private static final String TAG = RippleSprite.class.getSimpleName(); + private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator(); private static final TimeInterpolator DECEL_INTERPOLATOR = new LogInterpolator(); @@ -110,8 +112,8 @@ public void onBoundsChanged(Rect bounds) { mOuterRadius = ((float) Math.sqrt(halfWidth * halfWidth + halfHeight * halfHeight)); - mStartingX = mBounds.exactCenterX(); - mStartingY = mBounds.exactCenterY(); + //mStartingX = mBounds.exactCenterX(); + //mStartingY = mBounds.exactCenterY(); clampStartingPosition(); } @@ -228,7 +230,6 @@ private void drawSoftware(Canvas c, Paint p) { public void setStartPosition(float x, float y) { mStartingX = x; mStartingY = y; - clampStartingPosition(); } @@ -242,10 +243,10 @@ public void enter() { // If keepBound, set position if (mKeepBound) { - Float x = (Float)mView.getTag(R.id.position_x); - Float y = (Float)mView.getTag(R.id.position_y); - if (x != null && y != null) - setStartPosition(x, y); + Object obj = mView.getTag(); + if (obj != null && obj instanceof PointF) { + setStartPosition(((PointF)obj).x, ((PointF)obj).y); + } } mOuterOpacity = 0.0F; diff --git a/src/com/hippo/ehviewer/windowsanimate/WindowsAnimate.java b/src/com/hippo/ehviewer/windowsanimate/WindowsAnimate.java index 9838ee6df..6e4c73363 100644 --- a/src/com/hippo/ehviewer/windowsanimate/WindowsAnimate.java +++ b/src/com/hippo/ehviewer/windowsanimate/WindowsAnimate.java @@ -22,18 +22,21 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.graphics.PointF; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.animation.AccelerateInterpolator; import android.view.animation.OvershootInterpolator; -import com.hippo.ehviewer.R; import com.hippo.ehviewer.util.Constants; +import com.hippo.ehviewer.util.Log; import com.hippo.ehviewer.util.ViewUtils; public final class WindowsAnimate implements View.OnTouchListener { + private static final String TAG = WindowsAnimate.class.getSimpleName(); + private static final TimeInterpolator ACCELERATE_INTERPOLATOR = new AccelerateInterpolator(); private static final TimeInterpolator OVERSHOOT_INTERPOLATOR = new OvershootInterpolator(); @@ -74,8 +77,18 @@ private void ensureCanvas() { @Override @SuppressLint("ClickableViewAccessibility") public boolean onTouch(View v, MotionEvent event) { - v.setTag(R.id.position_x, event.getX()); - v.setTag(R.id.position_y, event.getY()); + + Log.d(TAG, "onTouch"); + + Object obj = v.getTag(); + if (obj == null) { + PointF p = new PointF(); + p.set(event.getX(), event.getY()); + v.setTag(p); + } else { + PointF p = (PointF)obj; + p.set(event.getX(), event.getY()); + } return false; }