diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 619f77359..f994355ab 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2,7 +2,7 @@ + android:versionName="0.4.0" > + android:versionName="0.4.0" > 非预期的响应码:%d 太多重定向 主机错误 + 无效的请求 + 未挂载 SD卡 刷新 diff --git a/res/values/strings.xml b/res/values/strings.xml index b2d8e8683..5e41292cf 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -121,6 +121,8 @@ Unexpected response code : %d Too many redirects Host error + Invalid request + SD card is Unmounted Refresh diff --git a/src/com/hippo/ehviewer/UpdateHelper.java b/src/com/hippo/ehviewer/UpdateHelper.java index 44e4521ee..06b407f18 100644 --- a/src/com/hippo/ehviewer/UpdateHelper.java +++ b/src/com/hippo/ehviewer/UpdateHelper.java @@ -1,10 +1,10 @@ package com.hippo.ehviewer; import java.io.File; -import java.net.MalformedURLException; -import android.annotation.SuppressLint; -import android.app.Activity; -import android.app.AlertDialog; + +import org.json.JSONException; +import org.json.JSONObject; + import android.app.NotificationManager; import android.content.Context; import android.content.Intent; @@ -15,19 +15,16 @@ import android.net.Uri; import android.os.Handler; import android.os.Message; import android.support.v4.app.NotificationCompat; -import android.view.View; + import com.hippo.ehviewer.network.Downloader; import com.hippo.ehviewer.network.HttpHelper; import com.hippo.ehviewer.util.Config; -import com.hippo.ehviewer.util.EhClient; import com.hippo.ehviewer.util.Future; import com.hippo.ehviewer.util.FutureListener; import com.hippo.ehviewer.util.ThreadPool; import com.hippo.ehviewer.util.Util; import com.hippo.ehviewer.util.ThreadPool.Job; import com.hippo.ehviewer.util.ThreadPool.JobContext; -import com.hippo.ehviewer.view.AlertButton; -import com.hippo.ehviewer.widget.DialogBuilder; // TODO return onFailure when downloading update or check update // TODO add disable to achieve @@ -43,17 +40,22 @@ public class UpdateHelper { private static final int GOOGLE = 0; private static final int QINIU = 1; - private static boolean isWorking = false; - - private Activity mActivity; + private AppContext mAppContext; private String updateFileName; private OnCheckUpdateListener mListener; + private static boolean mEnabled = true; private int downloadHost = QINIU; - public UpdateHelper(Activity activity) { - mActivity = activity; + public interface OnCheckUpdateListener { + public void onSuccess(String version, long size, String url, String info); + public void onNoUpdate(); + public void onFailure(String eMsg); + } + + public UpdateHelper(AppContext appContext) { + mAppContext = appContext; } public UpdateHelper SetOnCheckUpdateListener(OnCheckUpdateListener listener) { @@ -66,46 +68,62 @@ public class UpdateHelper { checkUpdate(); } + public static void setEnabled(boolean enabled) { + mEnabled = enabled; + } + class CheckUpdatePackage { public OnCheckUpdateListener listener; - public Activity activity; + public AppContext appContext; public String pageContext; public HttpHelper hp; } public void checkUpdate() { - if (isWorking) { - if (mListener != null) - mListener.onFailure("正在检查更新"); // TODO - return; - } else { - isWorking = true; - } - - final AppContext appContext = (AppContext)(mActivity.getApplicationContext()); - final HttpHelper hp = new HttpHelper(mActivity.getApplicationContext()); - ThreadPool threadPool = appContext.getNetworkThreadPool(); + final HttpHelper hp = new HttpHelper(mAppContext); + ThreadPool threadPool = mAppContext.getNetworkThreadPool(); threadPool.submit(new Job() { @Override public String run(JobContext jc) { - PackageManager pm = appContext.getPackageManager(); + if (!mEnabled) { + return "working"; + } + + mEnabled = false; + + PackageManager pm = mAppContext.getPackageManager(); PackageInfo pi = null; try { - pi = pm.getPackageInfo(appContext.getPackageName(), PackageManager.GET_ACTIVITIES); + pi = pm.getPackageInfo(mAppContext.getPackageName(), PackageManager.GET_ACTIVITIES); + + JSONObject jo = new JSONObject(); + jo.put("method", "update"); + + JSONObject detailJO = new JSONObject(); + detailJO.put("version", pi.versionName); + + // TODO switch server + detailJO.put("server", "qiniu"); + + jo.put("detail", detailJO); + + return hp.postJson(UPDATE_API, jo.toString()); } catch (NameNotFoundException e) { e.printStackTrace(); return "NameNotFound"; + } catch (JSONException e) { + e.printStackTrace(); + return "JSONException"; } - return hp.post(UPDATE_API, "last\n" + pi.versionName); } }, new FutureListener() { @Override public void onFutureDone(Future future) { String pageContext = future.get(); CheckUpdatePackage checkUpdatePackage = new CheckUpdatePackage(); + checkUpdatePackage.appContext = mAppContext; checkUpdatePackage.listener = mListener; - checkUpdatePackage.activity = mActivity; checkUpdatePackage.pageContext = pageContext; checkUpdatePackage.hp = hp; Message msg = new Message(); @@ -117,111 +135,98 @@ public class UpdateHelper { } // TODO move dialog into listener - - // TODO - @SuppressLint("HandlerLeak") - private Handler mHandler = new Handler() { + private static Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { CheckUpdatePackage checkUpdatePackage = (CheckUpdatePackage)msg.obj; OnCheckUpdateListener listener = checkUpdatePackage.listener; - Activity activity = checkUpdatePackage.activity; + AppContext appContext = checkUpdatePackage.appContext; String pageContext = checkUpdatePackage.pageContext; if (pageContext != null) { Config.setUpdateDate(); - String[] items = pageContext.split("\n"); - if (items.length > 3) { - - String newVer = items[0]; - String tempUrl = ""; - switch (downloadHost) { - case GOOGLE: - tempUrl = EhClient.UPDATE_URL + items[1]; - break; - case QINIU: - tempUrl = EhClient.UPDATE_URI_QINIU + Util.getFileForUrl(items[1]); - break; - } - final String url = tempUrl; - final String name = url.substring(url.lastIndexOf('/')+1); - updateFileName = name; - String size = items[2]; - String info = items[3]; - - AlertDialog dialog = new DialogBuilder(activity).setTitle(R.string.update) - .setMessage(String.format(activity.getString(R.string.update_message), newVer, size, info)) - .setNegativeButton(android.R.string.cancel, new View.OnClickListener() { - @Override - public void onClick(View v) { - ((AlertButton)v).dialog.dismiss(); - } - }).setPositiveButton(android.R.string.ok, new View.OnClickListener() { - @Override - public void onClick(View v) { - ((AlertButton)v).dialog.dismiss(); - Downloader d = new Downloader(); - try { - d.resetData(Config.getDownloadPath(), name, url); - d.setOnDownloadListener(new UpdateListener()); - new Thread(d).start(); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } - }).create(); - dialog.show(); - + + if (pageContext.equals("working")) { if (listener != null) - listener.onSuccess(pageContext); + listener.onFailure("正在检查更新或者下载更新"); // TODO + + } + else if (pageContext.equals("NameNotFound")) { + if (listener != null) + listener.onFailure("NameNotFound"); // TODO + + } else if (pageContext.equals("JSONException")) { + if (listener != null) + listener.onFailure("JSONException"); // TODO + } else { - if(pageContext.equals("none")) { + try { + + JSONObject jo = new JSONObject(pageContext); + JSONObject updateJO = jo.getJSONObject("update"); + + String version = updateJO.getString("version"); + + if (version.equals("error")) { + if (listener != null) + listener.onFailure(appContext.getString(R.string.em_invalid_request)); + } else if (version.equals("none")) { + if (listener != null) + listener.onNoUpdate(); + } else { + long size = updateJO.getLong("size"); + String url = updateJO.getString("url"); + String info = updateJO.getString("info"); + + if (listener != null) + listener.onSuccess(version, size, url, info); + } + } catch (JSONException e) { + e.printStackTrace(); if (listener != null) - listener.onNoUpdate(); - } else if(pageContext.equals("error")){ - if (listener != null) - listener.onFailure(activity.getString(R.string.em_request_error)); - } else if (pageContext.equals("NameNotFound")){ - if (listener != null) - listener.onFailure("NameNotFound"); // TODO - }else { - if (listener != null) - listener.onFailure(activity.getString(R.string.em_host_error)); + listener.onFailure(appContext.getString(R.string.em_host_error)); } } } else { if (listener != null) listener.onFailure(checkUpdatePackage.hp.getEMsg()); } - - isWorking = false; } }; - public interface OnCheckUpdateListener { - public void onSuccess(String pageContext); - public void onNoUpdate(); - public void onFailure(String eMsg); - } - - private class UpdateListener implements Downloader.OnDownloadListener { + public static class UpdateListener implements Downloader.OnDownloadListener { + private Context mContext; + private String mFileName; + private NotificationManager mNotifyManager; private NotificationCompat.Builder mBuilder; - public UpdateListener() { + + + public UpdateListener(Context context, String fileName) { + mContext = context; + mFileName = fileName; mNotifyManager = (NotificationManager) - mActivity.getSystemService(Context.NOTIFICATION_SERVICE); - mBuilder = new NotificationCompat.Builder(mActivity.getApplicationContext()); + mContext.getSystemService(Context.NOTIFICATION_SERVICE); + mBuilder = new NotificationCompat.Builder(mContext); mBuilder.setSmallIcon(R.drawable.ic_launcher); } @Override - public void onDownloadStart(int totalSize) { - mBuilder.setContentTitle("正在下载更新") // TODO + public void onDownloadStartConnect() { + mBuilder.setContentTitle("开始下载更新") // TODO .setContentText(null) .setProgress(0, 0, true).setOngoing(true); mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); } + + @Override + public void onDownloadStartDownload(int totalSize) { + mBuilder.setContentTitle("正在下载更新") + .setContentText(String.format("%.2f / %.2f KB", 0/1024.0f, totalSize/1024.0f)) + .setProgress(totalSize, 0, false).setOngoing(true); + mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); + } @Override public void onDownloadStatusUpdate( int downloadSize, int totalSize) { @@ -232,20 +237,22 @@ public class UpdateHelper { } @Override - public void onDownloadOver(boolean ok, int eMesgId) { - if (ok) { + public void onDownloadOver(int status) { + if (status == Downloader.COMPLETED) { mNotifyManager.cancel(NOTIFICATION_ID); Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(new File(Config.getDownloadPath(), updateFileName)), + intent.setDataAndType(Uri.fromFile(new File(Config.getDownloadPath(), mFileName)), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mActivity.getApplicationContext().startActivity(intent); + mContext.startActivity(intent); } else { mBuilder.setContentTitle("下载更新失败") .setContentText(null) .setProgress(0, 0, false).setOngoing(false); mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build()); } + + setEnabled(true); } } } diff --git a/src/com/hippo/ehviewer/activity/MangaActivity.java b/src/com/hippo/ehviewer/activity/MangaActivity.java index 10a7e0288..3cee4bda6 100644 --- a/src/com/hippo/ehviewer/activity/MangaActivity.java +++ b/src/com/hippo/ehviewer/activity/MangaActivity.java @@ -120,7 +120,7 @@ public class MangaActivity extends Activity { final String imageName = String.format("%05d", index + 1) + "." + Util.getExtension(imageUrl); - final Downloader downloader = new Downloader(); + final Downloader downloader = new Downloader(MangaActivity.this); try { downloader.resetData(mFolder.getPath(), imageName, diff --git a/src/com/hippo/ehviewer/activity/MangaListActivity.java b/src/com/hippo/ehviewer/activity/MangaListActivity.java index 7b29e01cd..8144fa447 100644 --- a/src/com/hippo/ehviewer/activity/MangaListActivity.java +++ b/src/com/hippo/ehviewer/activity/MangaListActivity.java @@ -1,5 +1,6 @@ package com.hippo.ehviewer.activity; +import java.net.MalformedURLException; import java.util.ArrayList; import com.hippo.ehviewer.AppContext; @@ -9,6 +10,7 @@ import com.hippo.ehviewer.ListMangaDetail; import com.hippo.ehviewer.ListUrls; import com.hippo.ehviewer.R; import com.hippo.ehviewer.UpdateHelper; +import com.hippo.ehviewer.network.Downloader; import com.hippo.ehviewer.service.DownloadService; import com.hippo.ehviewer.service.DownloadServiceConnection; import com.hippo.ehviewer.util.Cache; @@ -17,6 +19,7 @@ import com.hippo.ehviewer.util.EhClient; import com.hippo.ehviewer.util.Favourite; import com.hippo.ehviewer.util.Tag; import com.hippo.ehviewer.util.Ui; +import com.hippo.ehviewer.util.Util; import com.hippo.ehviewer.view.AlertButton; import com.hippo.ehviewer.view.CheckImage; import com.hippo.ehviewer.view.GetPaddingRelativeLayout; @@ -1414,7 +1417,50 @@ public class MangaListActivity extends Activity { } private void checkUpdate() { - new UpdateHelper(this).autoCheckUpdate(); + new UpdateHelper((AppContext)getApplication()) + .SetOnCheckUpdateListener(new UpdateHelper.OnCheckUpdateListener() { + @Override + public void onSuccess(String version, long size, + final String url, String info) { + String sizeStr = Util.sizeToString(size); + AlertDialog dialog = SuperDialogUtil.createUpdateDialog(MangaListActivity.this, + version, sizeStr, info, + new View.OnClickListener() { + @Override + public void onClick(View v) { + ((AlertButton)v).dialog.dismiss(); + // TODO + try { + Downloader downloader = new Downloader(MangaListActivity.this); + String fileName = Util.getFileForUrl(url); + downloader.resetData(Config.getDownloadPath(), fileName, url); + downloader.setOnDownloadListener( + new UpdateHelper.UpdateListener(MangaListActivity.this, + fileName)); + new Thread(downloader).start(); + } catch (MalformedURLException e) { + UpdateHelper.setEnabled(true); + } + } + }, new View.OnClickListener() { + @Override + public void onClick(View v) { + ((AlertButton)v).dialog.dismiss(); + UpdateHelper.setEnabled(true); + } + }); + if (!MangaListActivity.this.isFinishing()) + dialog.show(); + } + @Override + public void onNoUpdate() { + UpdateHelper.setEnabled(true); + } + @Override + public void onFailure(String eMsg) { + UpdateHelper.setEnabled(true); + } + }).autoCheckUpdate(); } private void checkLogin(boolean force) { diff --git a/src/com/hippo/ehviewer/activity/SettingsActivity.java b/src/com/hippo/ehviewer/activity/SettingsActivity.java index 0bf924ef6..737746aa7 100644 --- a/src/com/hippo/ehviewer/activity/SettingsActivity.java +++ b/src/com/hippo/ehviewer/activity/SettingsActivity.java @@ -1,7 +1,9 @@ package com.hippo.ehviewer.activity; import java.io.InputStream; +import java.net.MalformedURLException; +import com.hippo.ehviewer.AppContext; import com.hippo.ehviewer.BeautifyScreen; import com.hippo.ehviewer.DiskCache; import com.hippo.ehviewer.R; @@ -9,10 +11,14 @@ import com.hippo.ehviewer.UpdateHelper; import com.hippo.ehviewer.util.Cache; import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.util.Util; +import com.hippo.ehviewer.view.AlertButton; import com.hippo.ehviewer.widget.DialogBuilder; +import com.hippo.ehviewer.widget.SuperDialogUtil; +import com.hippo.ehviewer.network.Downloader; import com.hippo.ehviewer.preference.AutoListPreference; import android.annotation.SuppressLint; +import android.app.AlertDialog; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; @@ -28,9 +34,14 @@ import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceActivity; import android.preference.PreferenceScreen; import android.support.v4.util.LruCache; +import android.util.Log; +import android.view.View; import android.webkit.WebView; import android.widget.Toast; + +// TODO 添加服务器选择 + public class SettingsActivity extends PreferenceActivity { @SuppressWarnings("unused") private static String TAG = "Settings"; @@ -41,7 +52,6 @@ public class SettingsActivity extends PreferenceActivity { private static final String CP_CACHE = "preference_cp_cache"; private static final String CLEAR_CP_CACHE = "preference_clear_cp_cache"; - private static final String PAGE_SCALING = "preference_page_scaling"; private static final String AUTHOR = "preference_author"; private static final String SCREEN_ORI = "preference_screen_ori"; private static final String CHANGELOG = "preference_changelog"; @@ -51,9 +61,6 @@ public class SettingsActivity extends PreferenceActivity { private EditTextPreference cpCachePre; private Preference clearCpCachePre; - private EditTextPreference pageCachePre; - private Preference clearPageCachePre; - private AutoListPreference pageScalingListPre; private Preference authorPer; private AutoListPreference screenOriPer; private Preference changelogPer; @@ -213,24 +220,60 @@ public class SettingsActivity extends PreferenceActivity { @Override public boolean onPreferenceClick(Preference preference) { update.setSummary(R.string.checking_update); - new UpdateHelper(SettingsActivity.this) + new UpdateHelper((AppContext)SettingsActivity.this.getApplication()) .SetOnCheckUpdateListener(new UpdateHelper.OnCheckUpdateListener() { @Override - public void onSuccess(String pageContext) { + public void onSuccess(String version, long size, + final String url, String info) { update.setSummary(R.string.found_update); - update.setEnabled(true); + + String sizeStr = Util.sizeToString(size); + AlertDialog dialog = SuperDialogUtil.createUpdateDialog(SettingsActivity.this, + version, sizeStr, info, + new View.OnClickListener() { + @Override + public void onClick(View v) { + ((AlertButton)v).dialog.dismiss(); + // TODO + try { + Downloader downloader = new Downloader(SettingsActivity.this); + String fileName = Util.getFileForUrl(url); + downloader.resetData(Config.getDownloadPath(), fileName, url); + downloader.setOnDownloadListener( + new UpdateHelper.UpdateListener(SettingsActivity.this, + fileName)); + new Thread(downloader).start(); + } catch (MalformedURLException e) { + update.setSummary(R.string.em_url_format_error); + UpdateHelper.setEnabled(true); + } + update.setEnabled(true); + } + }, new View.OnClickListener() { + @Override + public void onClick(View v) { + ((AlertButton)v).dialog.dismiss(); + update.setEnabled(true); + UpdateHelper.setEnabled(true); + } + }); + if (!SettingsActivity.this.isFinishing()) + dialog.show(); } @Override public void onNoUpdate() { update.setSummary(R.string.up_to_date); update.setEnabled(true); + UpdateHelper.setEnabled(true); } @Override public void onFailure(String eMsg) { update.setSummary(eMsg); update.setEnabled(true); + UpdateHelper.setEnabled(true); } }).checkUpdate(); + update.setEnabled(false); return true; } diff --git a/src/com/hippo/ehviewer/network/RedirectionException.java b/src/com/hippo/ehviewer/exception/RedirectionException.java similarity index 65% rename from src/com/hippo/ehviewer/network/RedirectionException.java rename to src/com/hippo/ehviewer/exception/RedirectionException.java index abfe835cf..26fe0b0fb 100644 --- a/src/com/hippo/ehviewer/network/RedirectionException.java +++ b/src/com/hippo/ehviewer/exception/RedirectionException.java @@ -1,8 +1,5 @@ -package com.hippo.ehviewer.network; +package com.hippo.ehviewer.exception; public class RedirectionException extends Exception { - private static final long serialVersionUID = 1L; - - } diff --git a/src/com/hippo/ehviewer/network/ResponseCodeException.java b/src/com/hippo/ehviewer/exception/ResponseCodeException.java similarity index 89% rename from src/com/hippo/ehviewer/network/ResponseCodeException.java rename to src/com/hippo/ehviewer/exception/ResponseCodeException.java index d7fdabe2e..2080dd3b4 100644 --- a/src/com/hippo/ehviewer/network/ResponseCodeException.java +++ b/src/com/hippo/ehviewer/exception/ResponseCodeException.java @@ -1,4 +1,4 @@ -package com.hippo.ehviewer.network; +package com.hippo.ehviewer.exception; public class ResponseCodeException extends Exception { diff --git a/src/com/hippo/ehviewer/exception/StopRequestException.java b/src/com/hippo/ehviewer/exception/StopRequestException.java new file mode 100644 index 000000000..46b477004 --- /dev/null +++ b/src/com/hippo/ehviewer/exception/StopRequestException.java @@ -0,0 +1,5 @@ +package com.hippo.ehviewer.exception; + +public class StopRequestException extends Exception { + private static final long serialVersionUID = 1L; +} diff --git a/src/com/hippo/ehviewer/network/Downloader.java b/src/com/hippo/ehviewer/network/Downloader.java index 686e5cfba..9cec66240 100644 --- a/src/com/hippo/ehviewer/network/Downloader.java +++ b/src/com/hippo/ehviewer/network/Downloader.java @@ -7,14 +7,25 @@ import java.io.OutputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.MalformedURLException; +import java.net.SocketException; +import java.net.SocketTimeoutException; import java.net.URL; +import java.net.UnknownHostException; +import org.apache.http.conn.ConnectTimeoutException; + +import android.content.Context; import android.util.Log; +import com.hippo.ehviewer.R; +import com.hippo.ehviewer.exception.FileException; +import com.hippo.ehviewer.exception.NoSdCardException; +import com.hippo.ehviewer.exception.RedirectionException; +import com.hippo.ehviewer.exception.ResponseCodeException; +import com.hippo.ehviewer.exception.StopRequestException; import com.hippo.ehviewer.util.Cache; import com.hippo.ehviewer.util.Util; -// TODO 添加断点续传 // TODO 添加检查次磁盘空间 /** @@ -26,21 +37,19 @@ import com.hippo.ehviewer.util.Util; public class Downloader implements Runnable { private static final String TAG = "Downloader"; - public static final int HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; - public static final int HTTP_TEMP_REDIRECT = 307; - public static final int COMPLETED = 0; - public static final int STOP = -1; - public static final int NO_SDCARD = -2; - public static final int STATUS_HTTP_DATA_ERROR = -3; - public static final int STATUS_TOO_MANY_REDIRECTS = -4; - public static final int STATUS_FILE_ERROR = -5; + public static final int NONE = 0x0; + public static final int READY = 0x1; + public static final int CONNECTING = 0x2; + public static final int DOWNLOADING = 0x3; + public static final int FAILED = 0x4; + public static final int COMPLETED = 0x5; + public static final int STOPED = 0x6; - private static final int BUFFER_SIZE = 4096; + private static final int MAX_RETRY = 3; - private static final int MAX_REDIRECTS = 5; - private static final int MAX_RETRY = 5; - private static final int DEFAULT_TIMEOUT = 5 * 1000; + private Context mContext; + private File mFolder; private String mPath; private String mFileName; private URL mUrl; @@ -51,13 +60,16 @@ public class Downloader implements Runnable { private int mDownloadSize = 0; private int mRedirectionCount = 0; - private int status; + private int status = NONE; private OnDownloadListener mListener; + private Exception mException; + public interface OnDownloadListener { - public void onDownloadStart(int totalSize); + public void onDownloadStartConnect(); + public void onDownloadStartDownload(int totalSize); public void onDownloadStatusUpdate(int downloadSize, int totalSize); - public void onDownloadOver(boolean ok, int eMesgId); + public void onDownloadOver(int status); } public class Controlor { @@ -80,10 +92,11 @@ public class Downloader implements Runnable { mPath = path; mFileName = fileName; mUrl = new URL(urlStr); + mException = null; mDownloadSize = 0; mRedirectionCount = 0; - status = COMPLETED; + status = READY; mContorlor.reset(); return mContorlor; @@ -93,86 +106,151 @@ public class Downloader implements Runnable { mListener = listener; } - public Downloader() { + public Downloader(Context context) { + mContext = context; mContorlor = new Controlor(); } + + public String getEMsg() { + if (mException == null) + return mContext.getString(R.string.em_unknown_error); + + else if (mException instanceof MalformedURLException) + return mContext.getString(R.string.em_url_format_error); + + else if (mException instanceof ConnectTimeoutException || + mException instanceof SocketTimeoutException) + return mContext.getString(R.string.em_timeout); + + else if (mException instanceof UnknownHostException) + return mContext.getString(R.string.em_unknown_host); + + else if (mException instanceof ResponseCodeException) + return String.format(mContext.getString(R.string.em_unexpected_response_code), + ((ResponseCodeException)mException).getResponseCode()); + + else if (mException instanceof RedirectionException) + return mContext.getString(R.string.em_redirection_error); + + else if (mException instanceof SocketException) + return "SocketException : " + mException.getMessage(); + + else if (mException instanceof NoSdCardException) + return mContext.getString(R.string.em_no_sdcard); + + else + return mException.getMessage(); + } + @Override public void run() { - boolean ok = false; int retryTimes = 0; - if (Cache.hasSdCard()) - while(true) { + if (Cache.hasSdCard()) { + + boolean checkFolder = false; + + try { + initFolder(); + checkFolder = true; + } catch (Exception e) { + mException = e; + e.printStackTrace(); + } + + while(checkFolder) { try { if (mContorlor.isStop()) - throw new StopRequestException(STOP, "Download is stopped"); + throw new StopRequestException(); mRedirectionCount = 0; - status = COMPLETED; + status = READY; executeDownload(); - ok = true; + status = COMPLETED; break; - } catch (StopRequestException e) { + } catch (Exception e) { + mException = e; e.printStackTrace(); - status = e.getFinalStatus(); - if (status == STOP || retryTimes > MAX_RETRY) + if (mContorlor.isStop() || retryTimes > MAX_RETRY) { + status = FAILED; break; + } retryTimes++; } } - else - status = NO_SDCARD; + } else + mException = new NoSdCardException(); + + if (mContorlor.isStop()) + status = STOPED; if (mListener != null) - mListener.onDownloadOver(ok, status); + mListener.onDownloadOver(status); } public int getStatus() { return status; } - private void executeDownload() throws StopRequestException { - while (mRedirectionCount++ < MAX_REDIRECTS) { + private void initFolder() throws Exception { + mFolder = new File(mPath); + + if (!mFolder.exists()) { + if (!mFolder.mkdirs()) + throw new FileException(FileException.MKDIR_ERROR); + } else if (!mFolder.isDirectory()){ + throw new FileException(FileException.NOT_DIR); + } + + if (!mFolder.canWrite()) + throw new FileException(FileException.CANNOT_WRITE); + } + + private void executeDownload() throws Exception { + while (mRedirectionCount++ < Constant.MAX_REDIRECTS) { HttpURLConnection conn = null; try { Log.d(TAG, "Get file " + mUrl.toString()); + + status = CONNECTING; + if (mListener != null) + mListener.onDownloadStartConnect(); + conn = (HttpURLConnection)mUrl.openConnection(); conn.setInstanceFollowRedirects(false); - conn.addRequestProperty("Range", "bytes=" + mDownloadSize + "-"); // TODO - conn.setConnectTimeout(DEFAULT_TIMEOUT); - conn.setReadTimeout(DEFAULT_TIMEOUT); + conn.addRequestProperty("Range", "bytes=" + mDownloadSize + "-"); + conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT); + conn.setReadTimeout(Constant.DEFAULT_TIMEOUT); conn.connect(); final int responseCode = conn.getResponseCode(); switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: processResponseHeaders(conn); + status = DOWNLOADING; if (mListener != null) - mListener.onDownloadStart(mTotalSize); + mListener.onDownloadStartDownload(mTotalSize); transferData(conn); return; case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: case HttpURLConnection.HTTP_SEE_OTHER: - case HTTP_TEMP_REDIRECT: + case Constant.HTTP_TEMP_REDIRECT: final String location = conn.getHeaderField("Location"); mUrl = new URL(mUrl, location); continue; default: - StopRequestException.throwUnhandledHttpError( - responseCode, conn.getResponseMessage()); + throw new ResponseCodeException(responseCode); } - } catch (IOException e) { - // Trouble with low-level sockets - throw new StopRequestException(STATUS_HTTP_DATA_ERROR, e); - + } catch (Exception e) { + throw e; } finally { - if (conn != null) conn.disconnect(); + if (conn != null) + conn.disconnect(); } } - - throw new StopRequestException(STATUS_TOO_MANY_REDIRECTS, "Too many redirects"); + throw new RedirectionException(); } /** @@ -220,20 +298,19 @@ public class Downloader implements Runnable { /** * Transfer data from the given connection to the destination file. */ - private void transferData(HttpURLConnection conn) throws StopRequestException { + private void transferData(HttpURLConnection conn) throws Exception { InputStream in = null; RandomAccessFile raf = null; File file = null; if (mContorlor.isStop()) - throw new StopRequestException(STOP, - "Download is stopped"); + throw new StopRequestException(); try { try { in = conn.getInputStream(); } catch (IOException e) { - throw new StopRequestException(STATUS_HTTP_DATA_ERROR, e); + throw e; // TODO } try { @@ -241,14 +318,15 @@ public class Downloader implements Runnable { raf = new RandomAccessFile(file, "rw"); raf.seek(mDownloadSize); } catch (IOException e) { - throw new StopRequestException(STATUS_FILE_ERROR, e); + throw new FileException(FileException.CREATE_FILE_ERROR); } // Start streaming data, periodically watch for pause/cancel // commands and checking disk space as needed. transferData(in, raf); } finally { - Util.closeStreamQuietly(in); + if (in != null) + Util.closeStreamQuietly(in); if (raf != null) try { raf.close(); @@ -265,9 +343,13 @@ public class Downloader implements Runnable { */ @SuppressWarnings("unused") private void transferData(InputStream in, OutputStream out) - throws StopRequestException { - final byte data[] = new byte[BUFFER_SIZE]; - for (;;) { + throws Exception { + final byte data[] = new byte[Constant.BUFFER_SIZE]; + while (true) { + + if (mContorlor.isStop()) + throw new StopRequestException(); + int bytesRead = readFromResponse(data, in); if (bytesRead == -1) { // success, end of stream already reached return; @@ -277,10 +359,7 @@ public class Downloader implements Runnable { mDownloadSize += bytesRead; if (mListener != null) mListener.onDownloadStatusUpdate(mDownloadSize, mTotalSize); - - if (mContorlor.isStop()) - throw new StopRequestException(STOP, - "Download is stopped"); + } } @@ -289,9 +368,12 @@ public class Downloader implements Runnable { * destination file. */ private void transferData(InputStream in, RandomAccessFile raf) - throws StopRequestException { - final byte data[] = new byte[BUFFER_SIZE]; - for (;;) { + throws Exception { + final byte data[] = new byte[Constant.BUFFER_SIZE]; + while (true) { + if (mContorlor.isStop()) + throw new StopRequestException(); + int bytesRead = readFromResponse(data, in); if (bytesRead == -1) { // success, end of stream already reached return; @@ -301,10 +383,6 @@ public class Downloader implements Runnable { mDownloadSize += bytesRead; if (mListener != null) mListener.onDownloadStatusUpdate(mDownloadSize, mTotalSize); - - if (mContorlor.isStop()) - throw new StopRequestException(STOP, - "Download is stopped"); } } @@ -315,13 +393,12 @@ public class Downloader implements Runnable { * @return the number of bytes actually read or -1 if the end of the stream has been reached */ private int readFromResponse(byte[] data, InputStream entityStream) - throws StopRequestException { + throws Exception { try { return entityStream.read(data); - } catch (IOException ex) { + } catch (IOException e) { // TODO: handle stream errors the same as other retries - throw new StopRequestException(STATUS_HTTP_DATA_ERROR, - "Failed reading response: " + ex, ex); + throw e; } } @@ -332,15 +409,14 @@ public class Downloader implements Runnable { * @param bytesRead how many bytes to write from the buffer */ private void writeDataToDestination(byte[] data, int bytesRead, OutputStream out) - throws StopRequestException { + throws Exception { try { out.write(data, 0, bytesRead); return; - } catch (IOException ex) { + } catch (IOException e) { // TODO: better differentiate between DRM and disk failures // TODO: check disk is full - throw new StopRequestException(STATUS_FILE_ERROR, - "Failed to write data: " + ex); + throw e; } } @@ -350,15 +426,14 @@ public class Downloader implements Runnable { * @param bytesRead how many bytes to write from the buffer */ private void writeDataToDestination(byte[] data, int bytesRead, RandomAccessFile raf) - throws StopRequestException { + throws Exception { try { raf.write(data, 0, bytesRead); return; - } catch (IOException ex) { + } catch (IOException e) { // TODO: better differentiate between DRM and disk failures // TODO: check disk is full - throw new StopRequestException(STATUS_FILE_ERROR, - "Failed to write data: " + ex); + throw e; } } } diff --git a/src/com/hippo/ehviewer/network/HttpHelper.java b/src/com/hippo/ehviewer/network/HttpHelper.java index b6467317e..435f6a26f 100644 --- a/src/com/hippo/ehviewer/network/HttpHelper.java +++ b/src/com/hippo/ehviewer/network/HttpHelper.java @@ -18,6 +18,8 @@ import org.apache.http.conn.ConnectTimeoutException; import com.hippo.ehviewer.DiskCache; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.exception.RedirectionException; +import com.hippo.ehviewer.exception.ResponseCodeException; import com.hippo.ehviewer.util.Ui; import com.hippo.ehviewer.util.Util; @@ -36,15 +38,7 @@ import android.util.Log; public class HttpHelper { private static final String TAG = "HttpHelper"; - public static final int HTTP_TEMP_REDIRECT = 307; - - private static String defaultUserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36"; - private static String userAgent = System.getProperty("http.agent", defaultUserAgent); - private static final int DEFAULT_TIMEOUT = 5 * 1000; - private static final int MAX_REDIRECTS = 5; - private Context mContext; - private int responseCode; private Exception mException; public HttpHelper(Context context) { @@ -70,7 +64,8 @@ public class HttpHelper { return mContext.getString(R.string.em_unknown_host); else if (mException instanceof ResponseCodeException) - return String.format(mContext.getString(R.string.em_unexpected_response_code), responseCode); + return String.format(mContext.getString(R.string.em_unexpected_response_code), + ((ResponseCodeException)mException).getResponseCode()); else if (mException instanceof RedirectionException) return mContext.getString(R.string.em_redirection_error); @@ -79,7 +74,7 @@ public class HttpHelper { return "SocketException : " + mException.getMessage(); else - return mContext.getString(R.string.em_unknown_error) + " : " + mException.getMessage(); + return mException.getMessage(); } private String getPageContext(HttpURLConnection conn) @@ -93,7 +88,7 @@ public class HttpHelper { if (encoding != null && encoding.equals("gzip")) is = new GZIPInputStream(is); baos = new ByteArrayOutputStream(); - Util.copy(is, baos, 1024); + Util.copy(is, baos, Constant.BUFFER_SIZE); // TODO charset pageContext = baos.toString("utf-8"); } catch (IOException e) { @@ -113,16 +108,19 @@ public class HttpHelper { HttpURLConnection conn = null; try { + + Log.d(TAG, "Http get " + urlStr); + url = new URL(urlStr); - while (redirectionCount++ < MAX_REDIRECTS) { + while (redirectionCount++ < Constant.MAX_REDIRECTS) { conn = (HttpURLConnection) url.openConnection(); conn.addRequestProperty("Accept-Encoding", "gzip"); - conn.setRequestProperty("User-Agent", userAgent); - conn.setConnectTimeout(DEFAULT_TIMEOUT); - conn.setReadTimeout(DEFAULT_TIMEOUT); + conn.setRequestProperty("User-Agent", Constant.userAgent); + conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT); + conn.setReadTimeout(Constant.DEFAULT_TIMEOUT); conn.connect(); - responseCode = conn.getResponseCode(); + final int responseCode = conn.getResponseCode(); switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: @@ -131,7 +129,7 @@ public class HttpHelper { case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: case HttpURLConnection.HTTP_SEE_OTHER: - case HTTP_TEMP_REDIRECT: + case Constant.HTTP_TEMP_REDIRECT: final String location = conn.getHeaderField("Location"); url = new URL(url, location); continue; @@ -140,16 +138,16 @@ public class HttpHelper { throw new ResponseCodeException(responseCode); } } - if (redirectionCount > MAX_REDIRECTS) - throw new RedirectionException(); } catch (Exception e) { mException = e; e.printStackTrace(); + return null; } finally { if (conn != null) conn.disconnect(); } + mException = new RedirectionException(); return null; } @@ -161,13 +159,16 @@ public class HttpHelper { HttpURLConnection conn = null; try { + + Log.d(TAG, "Http post " + urlStr); + url = new URL(urlStr); - while (redirectionCount++ < MAX_REDIRECTS) { + while (redirectionCount++ < Constant.MAX_REDIRECTS) { conn = (HttpURLConnection) url.openConnection(); conn.addRequestProperty("Accept-Encoding", "gzip"); - conn.setRequestProperty("User-Agent", userAgent); - conn.setConnectTimeout(DEFAULT_TIMEOUT); - conn.setReadTimeout(DEFAULT_TIMEOUT); + conn.setRequestProperty("User-Agent", Constant.userAgent); + conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT); + conn.setReadTimeout(Constant.DEFAULT_TIMEOUT); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); @@ -193,7 +194,7 @@ public class HttpHelper { conn.connect(); - responseCode = conn.getResponseCode(); + final int responseCode = conn.getResponseCode(); switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: @@ -202,7 +203,7 @@ public class HttpHelper { case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: case HttpURLConnection.HTTP_SEE_OTHER: - case HTTP_TEMP_REDIRECT: + case Constant.HTTP_TEMP_REDIRECT: final String location = conn.getHeaderField("Location"); url = new URL(url, location); continue; @@ -211,16 +212,16 @@ public class HttpHelper { throw new ResponseCodeException(responseCode); } } - if (redirectionCount > MAX_REDIRECTS) - throw new RedirectionException(); } catch (Exception e) { mException = e; e.printStackTrace(); + return null; } finally { if (conn != null) conn.disconnect(); } + mException = new RedirectionException(); return null; } @@ -232,13 +233,16 @@ public class HttpHelper { HttpURLConnection conn = null; try { + + Log.d(TAG, "Http post " + urlStr); + url = new URL(urlStr); - while (redirectionCount++ < MAX_REDIRECTS) { + while (redirectionCount++ < Constant.MAX_REDIRECTS) { conn = (HttpURLConnection) url.openConnection(); conn.addRequestProperty("Accept-Encoding", "gzip"); - conn.setRequestProperty("User-Agent", userAgent); - conn.setConnectTimeout(DEFAULT_TIMEOUT); - conn.setReadTimeout(DEFAULT_TIMEOUT); + conn.setRequestProperty("User-Agent", Constant.userAgent); + conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT); + conn.setReadTimeout(Constant.DEFAULT_TIMEOUT); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); @@ -252,7 +256,7 @@ public class HttpHelper { conn.connect(); - responseCode = conn.getResponseCode(); + final int responseCode = conn.getResponseCode(); switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: @@ -261,7 +265,7 @@ public class HttpHelper { case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: case HttpURLConnection.HTTP_SEE_OTHER: - case HTTP_TEMP_REDIRECT: + case Constant.HTTP_TEMP_REDIRECT: final String location = conn.getHeaderField("Location"); url = new URL(url, location); continue; @@ -270,16 +274,16 @@ public class HttpHelper { throw new ResponseCodeException(responseCode); } } - if (redirectionCount > MAX_REDIRECTS) - throw new RedirectionException(); } catch (Exception e) { mException = e; e.printStackTrace(); + return null; } finally { if (conn != null) conn.disconnect(); } + mException = new RedirectionException(); return null; } @@ -292,13 +296,16 @@ public class HttpHelper { HttpURLConnection conn = null; try { + + Log.d(TAG, "Http post " + urlStr); + url = new URL(urlStr); - while (redirectionCount++ < MAX_REDIRECTS) { + while (redirectionCount++ < Constant.MAX_REDIRECTS) { conn = (HttpURLConnection) url.openConnection(); conn.addRequestProperty("Accept-Encoding", "gzip"); - conn.setRequestProperty("User-Agent", userAgent); - conn.setConnectTimeout(DEFAULT_TIMEOUT); - conn.setReadTimeout(DEFAULT_TIMEOUT); + conn.setRequestProperty("User-Agent", Constant.userAgent); + conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT); + conn.setReadTimeout(Constant.DEFAULT_TIMEOUT); conn.setDoOutput(true); conn.setDoInput(true); conn.setRequestMethod("POST"); @@ -314,7 +321,7 @@ public class HttpHelper { conn.connect(); - responseCode = conn.getResponseCode(); + final int responseCode = conn.getResponseCode(); switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: @@ -323,7 +330,7 @@ public class HttpHelper { case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: case HttpURLConnection.HTTP_SEE_OTHER: - case HTTP_TEMP_REDIRECT: + case Constant.HTTP_TEMP_REDIRECT: final String location = conn.getHeaderField("Location"); url = new URL(url, location); continue; @@ -332,16 +339,16 @@ public class HttpHelper { throw new ResponseCodeException(responseCode); } } - if (redirectionCount > MAX_REDIRECTS) - throw new RedirectionException(); } catch (Exception e) { mException = e; e.printStackTrace(); + return null; } finally { if (conn != null) conn.disconnect(); } + mException = new RedirectionException(); return null; } @@ -358,15 +365,18 @@ public class HttpHelper { InputStream is = null; try { + + Log.d(TAG, "Http get bitmap " + urlStr); + url = new URL(urlStr); - while (redirectionCount++ < MAX_REDIRECTS) { + while (redirectionCount++ < Constant.MAX_REDIRECTS) { conn = (HttpURLConnection)url.openConnection(); - conn.setRequestProperty("User-Agent", userAgent); - conn.setConnectTimeout(DEFAULT_TIMEOUT); - conn.setReadTimeout(DEFAULT_TIMEOUT); + conn.setRequestProperty("User-Agent", Constant.userAgent); + conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT); + conn.setReadTimeout(Constant.DEFAULT_TIMEOUT); conn.connect(); - responseCode = conn.getResponseCode(); + final int responseCode = conn.getResponseCode(); switch (responseCode) { case HttpURLConnection.HTTP_OK: case HttpURLConnection.HTTP_PARTIAL: @@ -408,7 +418,7 @@ public class HttpHelper { case HttpURLConnection.HTTP_MOVED_PERM: case HttpURLConnection.HTTP_MOVED_TEMP: case HttpURLConnection.HTTP_SEE_OTHER: - case HTTP_TEMP_REDIRECT: + case Constant.HTTP_TEMP_REDIRECT: final String location = conn.getHeaderField("Location"); url = new URL(url, location); continue; @@ -417,11 +427,10 @@ public class HttpHelper { throw new ResponseCodeException(responseCode); } } - if (redirectionCount > MAX_REDIRECTS) - throw new RedirectionException(); } catch (Exception e) { mException = e; e.printStackTrace(); + return null; } finally { if (baos != null) Util.closeStreamQuietly(baos); @@ -430,6 +439,7 @@ public class HttpHelper { if (conn != null) conn.disconnect(); } + mException = new RedirectionException(); return null; } } diff --git a/src/com/hippo/ehviewer/network/StopRequestException.java b/src/com/hippo/ehviewer/network/StopRequestException.java deleted file mode 100644 index 85299a64d..000000000 --- a/src/com/hippo/ehviewer/network/StopRequestException.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.hippo.ehviewer.network; - -class StopRequestException extends Exception { - - private final int mFinalStatus; - - public StopRequestException(int finalStatus, String message) { - super(message); - mFinalStatus = finalStatus; - } - - public StopRequestException(int finalStatus, Throwable t) { - super(t); - mFinalStatus = finalStatus; - } - - public StopRequestException(int finalStatus, String message, Throwable t) { - super(message, t); - mFinalStatus = finalStatus; - } - - public int getFinalStatus() { - return mFinalStatus; - } - - public static StopRequestException throwUnhandledHttpError(int code, String message) - throws StopRequestException { - final String error = "Unhandled HTTP response: " + code + " " + message; - throw new StopRequestException(code, error); - } -} diff --git a/src/com/hippo/ehviewer/util/EhClient.java b/src/com/hippo/ehviewer/util/EhClient.java index 115b726b9..a779cd859 100644 --- a/src/com/hippo/ehviewer/util/EhClient.java +++ b/src/com/hippo/ehviewer/util/EhClient.java @@ -1179,10 +1179,16 @@ public class EhClient { listener.onDownloadMangaAllStart(); Parser parser = new Parser(); - Downloader imageDownloader = new Downloader(); + Downloader imageDownloader = new Downloader(mAppContext); imageDownloader.setOnDownloadListener(new Downloader.OnDownloadListener() { @Override - public void onDownloadStart(int totalSize) { + public void onDownloadStartConnect() { + + } + + + @Override + public void onDownloadStartDownload(int totalSize) { if (curDownloadInfo != null) { curDownloadInfo.downloadSize = 0; curDownloadInfo.totalSize = totalSize/1024.0f; @@ -1199,8 +1205,8 @@ public class EhClient { } @Override - public void onDownloadOver(boolean ok, int eMesgId) { - if (ok) + public void onDownloadOver(int status) { + if (status == Downloader.COMPLETED) mService.notifyUpdate(curDownloadInfo.gid, curDownloadInfo.lastStartIndex, ImageSet.STATE_LOADED); else mService.notifyUpdate(curDownloadInfo.gid, curDownloadInfo.lastStartIndex, ImageSet.STATE_FAIL); @@ -1280,7 +1286,7 @@ public class EhClient { curDownloadInfo.totalSize = 0; int downloadStatus = imageDownloader.getStatus(); - if (downloadStatus == Downloader.STOP) { // If stop by user + if (downloadStatus == Downloader.STOPED) { // If stop by user listener.onDownloadMangaStop(curDownloadInfo.gid); mService.notifyUpdate(); Download.notify(String.valueOf(curDownloadInfo.gid)); diff --git a/src/com/hippo/ehviewer/util/Util.java b/src/com/hippo/ehviewer/util/Util.java index b4ba82a55..f03829172 100644 --- a/src/com/hippo/ehviewer/util/Util.java +++ b/src/com/hippo/ehviewer/util/Util.java @@ -1,44 +1,22 @@ package com.hippo.ehviewer.util; -import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; -import java.net.HttpURLConnection; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Locale; -import java.util.zip.GZIPInputStream; -import java.util.zip.Inflater; -import java.util.zip.InflaterInputStream; - -import com.hippo.ehviewer.DiskCache; -import com.hippo.ehviewer.ListUrls; -import com.hippo.ehviewer.R; import android.annotation.SuppressLint; -import android.content.Context; import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.pm.PackageManager.NameNotFoundException; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Movie; -import android.os.Build; -import android.os.Environment; -import android.preference.PreferenceManager; -import android.support.v4.util.LruCache; -import android.util.Log; -import android.view.ViewGroup; -import android.widget.ImageView; public class Util { + @SuppressWarnings("unused") private static String TAG = "Util"; /** @@ -213,4 +191,20 @@ public class Util { } catch (NumberFormatException e) {} return time; } + + + private static String[] SIZE_UNIT = {"%.2f B", "%.2f KB", "%.2f MB", "%.2f GB"}; + + public static String sizeToString(long size) { + int length = SIZE_UNIT.length; + + float sizeFloat = (float)size; + for (int i = 0; i < length; i++) { + if (sizeFloat < 1024 || i == length - 1) { + return String.format(SIZE_UNIT[i], sizeFloat); + } + sizeFloat /= 1024; + } + return null; + } } diff --git a/src/com/hippo/ehviewer/widget/SuperDialogUtil.java b/src/com/hippo/ehviewer/widget/SuperDialogUtil.java index 4b8b74c85..507910013 100644 --- a/src/com/hippo/ehviewer/widget/SuperDialogUtil.java +++ b/src/com/hippo/ehviewer/widget/SuperDialogUtil.java @@ -15,4 +15,15 @@ public class SuperDialogUtil { titleView.setText(title); } + + public static AlertDialog createUpdateDialog(Context context, String version, + String size, String info, View.OnClickListener positiveListener, + View.OnClickListener negativeListener) { + + return new DialogBuilder(context).setTitle(R.string.update).setCancelable(false) + .setMessage(String.format(context.getString(R.string.update_message), version, size, info)) + .setPositiveButton(android.R.string.ok, positiveListener) + .setNegativeButton(android.R.string.cancel, negativeListener) + .create(); + } }