This commit is contained in:
seven332 committed 2014-04-26 15:28:42 +08:00
1 parent abe2189acd
commit b27e02fed1
65 files changed
+7923 -7754

No files matched your search

BIN
View File
Binary file not shown.
+514 -508
View File
File diff suppressed because it is too large. Load diff
BIN
View File
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

BIN
View File
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+1 -1
View File
@@ -7,7 +7,7 @@
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="64dp"
android:background="@color/blue_dark"
android:background="@android:color/holo_blue_dark"
android:orientation="horizontal" >
<TextView
+41 -40
View File
@@ -1,47 +1,48 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@color/bg_white"
android:fitsSystemWindows="true" >
<com.hippo.ehviewer.view.GetPaddingRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_main"
<com.hippo.ehviewer.widget.PullListView
android:id="@+id/list_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true" >
android:layout_height="fill_parent" />
<com.hippo.ehviewer.widget.PullListView
android:id="@+id/list_list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<ProgressBar
android:id="@+id/list_wait_first"
style="@style/ProgressBar.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone" />
<ProgressBar
android:id="@+id/list_wait_first"
style="@style/ProgressBar.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone" />
<Button
android:id="@+id/list_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="buttonRefresh"
android:text="@string/refresh"
android:visibility="gone" />
<Button
android:id="@+id/list_refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:onClick="buttonRefresh"
android:text="@string/refresh"
android:visibility="gone" />
<ImageView
android:id="@+id/sadpanda"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/sadpanda"
android:visibility="gone" />
<ImageView
android:id="@+id/sadpanda"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/sadpanda"
android:visibility="gone" />
<TextView
android:id="@+id/list_no_found"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/no_found"
android:textSize="24sp"
android:visibility="gone" />
<TextView
android:id="@+id/list_no_found"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/no_found"
android:textSize="24sp"
android:visibility="gone" />
</com.hippo.ehviewer.view.GetPaddingRelativeLayout>
</RelativeLayout>
+9 -8
View File
@@ -12,7 +12,7 @@
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_height="fill_parent"
android:layout_margin="8dp"
android:orientation="vertical" >
@@ -23,15 +23,15 @@
android:maxLines="3"
android:ellipsize="end" />
<LinearLayout
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:orientation="horizontal" >
<ImageView
@@ -42,13 +42,14 @@
<LinearLayout
android:id="@+id/rate"
android:layout_width="fill_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:orientation="horizontal" >
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
+1 -1
View File
@@ -4,7 +4,7 @@
android:layout_height="match_parent"
android:layout_gravity="start"
android:clickable="true"
android:background="@color/blue_dark"
android:background="@android:color/holo_blue_dark"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
+1 -1
View File
@@ -4,7 +4,7 @@
android:layout_height="match_parent"
android:layout_gravity="end"
android:clickable="true"
android:background="@color/blue_dark"
android:background="@android:color/holo_blue_dark"
android:orientation="vertical" >
<include
+1 -1
View File
@@ -18,7 +18,7 @@
android:padding="12dp"
android:textSize="14sp"
android:textColor="@android:color/white"
android:background="@color/blue_dark"
android:background="@android:color/holo_blue_dark"
android:clickable="true"
android:onClick="goTo" />
+1 -3
View File
@@ -10,9 +10,7 @@
<ListView
android:id="@+id/list_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" >
android:layout_height="fill_parent" >
</ListView>
</LinearLayout>
+5
View File
@@ -68,6 +68,9 @@
<string name="checking_update">正在检查更新</string>
<string name="up_to_date">已是最新版</string>
<string name="found_update">发现新版本</string>
<string name="start_update">开始下载更新</string>
<string name="download_update">正在下载更新</string>
<string name="update_failed">下载更新失败</string>
<!-- MangaDetialActivity -->
<string name="detail_uploader">上传者:%s</string>
@@ -145,6 +148,7 @@
<string name="preference_auto_page_cache_summary_on">当应用关闭时清除页面缓存</string>
<string name="preference_auto_page_cache_summary_off">啥都不做</string>
<string name="preference_download_path">下载路径</string>
<string name="preference_media_scan">允许媒体扫描</string>
<string name="preference_update_server">更新服务器</string>
@@ -215,6 +219,7 @@
<string name="refresh">刷新</string>
<string name="error">错误</string>
<string name="changelog">日志</string>
<string name="register">注册</string>
<string name="login">登陆</string>
<string name="logout">退出</string>
<string name="wait">请稍后</string>
+2 -2
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="blue_light">#ff33b5e5</color>
<color name="blue_dark">#ff0099cc</color>
<color name="bg_white">#ffeeeeee</color>
<color name="holo_blue_light_light">#ff81d3f7</color>
</resources>
+1 -2
View File
@@ -2,8 +2,7 @@
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="shadow_width">15dp</dimen>
<dimen name="menu_offset">150dp</dimen>
<dimen name="shadow_width">15dp</dimen>
</resources>
+5
View File
@@ -71,6 +71,9 @@
<string name="checking_update">checking updating</string>
<string name="up_to_date">Up to date</string>
<string name="found_update">Found update</string>
<string name="start_update">Start downloading the update</string>
<string name="download_update">Downloading the update</string>
<string name="update_failed">Download the update Failed</string>
<!-- MangaDetialActivity -->
<string name="detail_uploader">Uploader: %s</string>
@@ -149,6 +152,7 @@
<string name="preference_auto_page_cache_summary_on">Clean page cache when the application close</string>
<string name="preference_auto_page_cache_summary_off">Leave page cache alone</string>
<string name="preference_download_path">Download path</string>
<string name="preference_media_scan">Allow media scan</string>
<string name="preference_update_server">Update server</string>
@@ -223,6 +227,7 @@
<string name="refresh">Refresh</string>
<string name="error">Error</string>
<string name="changelog">Changelog</string>
<string name="register">Register</string>
<string name="login">Login</string>
<string name="logout">Logout</string>
<string name="wait">Please wait</string>
+4 -4
View File
@@ -1,9 +1,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="ActionBar" parent="@android:style/Widget.Holo.ActionBar">
<item name="android:background">@color/blue_dark</item>
<item name="android:backgroundStacked">@color/blue_dark</item>
<item name="android:backgroundSplit">@color/blue_dark</item>
<item name="android:background">@android:color/holo_blue_dark</item>
<item name="android:backgroundStacked">@android:color/holo_blue_dark</item>
<item name="android:backgroundSplit">@android:color/holo_blue_dark</item>
<item name="android:titleTextStyle">@style/ActionBarTitleFont</item>
</style>
@@ -29,7 +29,7 @@
</style>
<style name="Button.Blue">
<item name="android:background">@color/blue_dark</item>
<item name="android:background">@android:color/holo_blue_dark</item>
<item name="android:textColor">@android:color/white</item>
</style>
+4
View File
@@ -7,12 +7,16 @@
<item name="@android:actionBarStyle">@style/ActionBar</item>
<item name="@android:actionOverflowButtonStyle">@style/OverFlow</item>
<item name="@android:homeAsUpIndicator">@drawable/ic_navigation_drawer</item>
<item name="android:windowContentOverlay">@null</item>
<!-- Button -->
<item name="@android:buttonStyle">@style/Button.Blue</item>
<!-- Scrollbar attributes -->
<item name="@android:scrollbarThumbVertical">@drawable/scrollbar_blue</item>
<!-- List attributes -->
<item name="@android:listDivider">@drawable/list_divider</item>
</style>
<style name="AppTheme.NoActionBar">
+7 -2
View File
@@ -40,14 +40,19 @@
</PreferenceCategory>
<!--
<PreferenceCategory android:title="@string/download" >
<Preference
android:key="preference_download_path"
android:title="@string/preference_download_path"
android:enabled="false" />
<CheckBoxPreference
android:key="preference_media_scan"
android:title="@string/preference_media_scan"
android:defaultValue="false" />
</PreferenceCategory>
-->
<PreferenceCategory android:title="@string/preference_category_about" >
<Preference
+14
View File
@@ -1,5 +1,7 @@
package com.hippo.ehviewer;
import java.io.File;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import com.hippo.ehviewer.data.Data;
@@ -45,6 +47,18 @@ public class AppContext extends Application implements UncaughtExceptionHandler
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
// Add .nomedia or delete it
File nomedia = new File(Config.getDownloadPath(), ".nomedia");
if (Config.getMediaScan()) {
nomedia.delete();
} else {
try {
nomedia.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public EhClient getEhClient() {
+109 -111
View File
@@ -1,111 +1,109 @@
package com.hippo.ehviewer;
import com.hippo.ehviewer.util.Ui;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.os.Build;
import android.util.DisplayMetrics;
import com.hippo.ehviewer.util.Log;
import android.view.Gravity;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout.LayoutParams;
@SuppressLint("NewApi")
public class BeautifyScreen {
private static final String TAG = "BeautifyScreen";
private static Context mContext;
private static int mStatusBarHeight = 0;
private static int mNavigationBarHeight = 0;
private static int sbbId = 0;
private static int nbbId = 1;
private BeautifyScreen(){}
public static void init(Context context) {
mContext = context;
if (Build.VERSION.SDK_INT >= 19) {
Resources resources = context.getResources();
int sbhResourceId = resources.getIdentifier("status_bar_height",
"dimen", "android");
if (sbhResourceId > 0)
mStatusBarHeight = resources
.getDimensionPixelSize(sbhResourceId);
int nbhResourceId = resources.getIdentifier(
"navigation_bar_height", "dimen", "android");
if (nbhResourceId > 0)
mNavigationBarHeight = resources
.getDimensionPixelSize(nbhResourceId);
}
}
public static void ColourfyScreen(Activity activity) {
if (Build.VERSION.SDK_INT >= 19) {
Resources resources = activity.getResources();
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
winParams.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
win.setAttributes(winParams);
ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
// Add status bar background
if (mStatusBarHeight > 0) {
View statusBarView = new View(mContext);
LayoutParams params1 = new LayoutParams(
LayoutParams.MATCH_PARENT, mStatusBarHeight);
params1.gravity = Gravity.TOP;
statusBarView.setLayoutParams(params1);
statusBarView.setBackgroundColor(resources
.getColor(R.color.blue_dark));
statusBarView.setId(sbbId);
decorViewGroup.addView(statusBarView);
}
// Add navigation bar background
if (Ui.hasNavigationBar() && mNavigationBarHeight > 0 &&
isPortrait(activity)) {
View navigationBarView = new View(mContext);
LayoutParams params2 = new LayoutParams(
LayoutParams.MATCH_PARENT, mNavigationBarHeight);
params2.gravity = Gravity.BOTTOM;
navigationBarView.setLayoutParams(params2);
navigationBarView.setBackgroundColor(resources
.getColor(R.color.blue_dark));
navigationBarView.setId(nbbId);
decorViewGroup.addView(navigationBarView);
}
}
}
private static boolean isPortrait(Activity activity) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
return dm.heightPixels > dm.widthPixels;
}
public static void fixColour(Activity activity) {
if (Build.VERSION.SDK_INT < 19)
return;
Window win = activity.getWindow();
ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
View navigationBarView = decorViewGroup.findViewById(nbbId);
if (navigationBarView == null)
return;
if (!isPortrait(activity))
navigationBarView.setVisibility(View.GONE);
else
navigationBarView.setVisibility(View.VISIBLE);
}
}
package com.hippo.ehviewer;
import com.hippo.ehviewer.util.Ui;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.os.Build;
import android.util.DisplayMetrics;
import com.hippo.ehviewer.util.Log;
import android.view.Gravity;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout.LayoutParams;
@SuppressLint("NewApi")
public class BeautifyScreen {
private static final String TAG = "BeautifyScreen";
private static Context mContext;
private static int mStatusBarHeight = 0;
private static int mNavigationBarHeight = 0;
private static int sbbId = 0;
private static int nbbId = 1;
private BeautifyScreen(){}
public static void init(Context context) {
mContext = context;
if (Build.VERSION.SDK_INT >= 19) {
Resources resources = context.getResources();
int sbhResourceId = resources.getIdentifier("status_bar_height",
"dimen", "android");
if (sbhResourceId > 0)
mStatusBarHeight = resources
.getDimensionPixelSize(sbhResourceId);
int nbhResourceId = resources.getIdentifier(
"navigation_bar_height", "dimen", "android");
if (nbhResourceId > 0)
mNavigationBarHeight = resources
.getDimensionPixelSize(nbhResourceId);
}
}
public static void ColourfyScreen(Activity activity) {
if (Build.VERSION.SDK_INT >= 19) {
Resources resources = activity.getResources();
Window win = activity.getWindow();
WindowManager.LayoutParams winParams = win.getAttributes();
winParams.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
| WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
win.setAttributes(winParams);
ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
// Add status bar background
if (mStatusBarHeight > 0) {
View statusBarView = new View(mContext);
LayoutParams params1 = new LayoutParams(
LayoutParams.MATCH_PARENT, mStatusBarHeight);
params1.gravity = Gravity.TOP;
statusBarView.setLayoutParams(params1);
statusBarView.setBackgroundColor(Ui.HOLO_BLUE_DARK);
statusBarView.setId(sbbId);
decorViewGroup.addView(statusBarView);
}
// Add navigation bar background
if (Ui.hasNavigationBar() && mNavigationBarHeight > 0 &&
isPortrait(activity)) {
View navigationBarView = new View(mContext);
LayoutParams params2 = new LayoutParams(
LayoutParams.MATCH_PARENT, mNavigationBarHeight);
params2.gravity = Gravity.BOTTOM;
navigationBarView.setLayoutParams(params2);
navigationBarView.setBackgroundColor(Ui.HOLO_BLUE_DARK);
navigationBarView.setId(nbbId);
decorViewGroup.addView(navigationBarView);
}
}
}
private static boolean isPortrait(Activity activity) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
return dm.heightPixels > dm.widthPixels;
}
public static void fixColour(Activity activity) {
if (Build.VERSION.SDK_INT < 19)
return;
Window win = activity.getWindow();
ViewGroup decorViewGroup = (ViewGroup) win.getDecorView();
View navigationBarView = decorViewGroup.findViewById(nbbId);
if (navigationBarView == null)
return;
if (!isPortrait(activity))
navigationBarView.setVisibility(View.GONE);
else
navigationBarView.setVisibility(View.VISIBLE);
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,77 @@
package com.hippo.ehviewer;
import java.util.ArrayList;
import java.util.List;
import com.hippo.ehviewer.data.Data;
import com.hippo.ehviewer.data.DownloadInfo;
import com.hippo.ehviewer.data.GalleryInfo;
public class GalleryDownloader {
private AppContext mAppContext;
private Data mData;
private List<DownloadInfo> mDownloadList;
private ArrayList<String> mPageTokes;
private DownloadInfo curDownloadInfo;
private static DownloadInfo emptyDownloadInfo = new DownloadInfo(null);
public GalleryDownloader(AppContext appContext) {
mAppContext = appContext;
mPageTokes = new ArrayList<String>();
mData = mAppContext.getData();
mDownloadList = mData.getAllDownloads();
}
public synchronized void add(GalleryInfo galleryInfo) {
DownloadInfo downloadInfo = new DownloadInfo(galleryInfo);
mData.addDownload(downloadInfo);
downloadInfo.setDownloadState(DownloadInfo.WAITING);
checkDownloadThread();
}
public synchronized boolean start(int index) {
DownloadInfo downloadInfo = mDownloadList.get(index);
if (downloadInfo.getDownloadState() == DownloadInfo.NONE
&& downloadInfo.getState() != DownloadInfo.COMPLETED) {
downloadInfo.setDownloadState(DownloadInfo.WAITING);
checkDownloadThread();
return true;
} else {
return false;
}
}
private synchronized void checkDownloadThread() {
if (curDownloadInfo == null) {
curDownloadInfo = emptyDownloadInfo;
new Thread(new DownloadGallery()).start();
}
}
private synchronized DownloadInfo getFirstWaiting() {
for (DownloadInfo downloadInfo : mDownloadList) {
if (downloadInfo.getDownloadState() == DownloadInfo.WAITING)
return downloadInfo;
}
return null;
}
private class DownloadGallery implements Runnable {
@Override
public void run() {
while ((curDownloadInfo = getFirstWaiting()) != null) {
curDownloadInfo.setDownloadState(DownloadInfo.DOWNLOADING);
// Check need get
}
}
}
}
+1 -1
View File
@@ -77,8 +77,8 @@ public class ImageLoadManager {
liv.setState(LoadImageView.LOADING);
mLoadCacheTask.push(new LoadTask(liv, download));
if (curLoadTask == null) {
new Thread(new LoadFromCacheTask()).start();
curLoadTask = emptyLoadTask;
new Thread(new LoadFromCacheTask()).start();
}
}
@@ -0,0 +1,6 @@
package com.hippo.ehviewer;
public class NotificationId {
public static final int UPDATE_ID = -1;
public static final int DOWNLOAD_ID = -2;
}
+31 -21
View File
@@ -32,7 +32,6 @@ import com.hippo.ehviewer.util.ThreadPool.JobContext;
public class UpdateHelper {
@SuppressWarnings("unused")
private static final String TAG = "UpdateHelper";
private static final int NOTIFICATION_ID = -1;
private static final String UPDATE_API = "http://ehviewersu.appsp0t.com/API";
private static final String HEADER = "Ehviewer-";
@@ -192,57 +191,68 @@ public class UpdateHelper {
private String mFileName;
private NotificationManager mNotifyManager;
private NotificationCompat.Builder mBuilder;
public UpdateListener(Context context, String fileName) {
mContext = context;
mFileName = fileName;
mNotifyManager = (NotificationManager)
mContext.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(mContext);
mBuilder.setSmallIcon(R.drawable.ic_launcher);
}
@Override
public void onDownloadStartConnect() {
mBuilder.setContentTitle("开始下载更新") // TODO
.setContentText(null)
.setProgress(0, 0, true).setOngoing(true);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
NotificationCompat.Builder builder =
new NotificationCompat.Builder(mContext)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle(mContext.getString(R.string.start_update))
.setProgress(0, 0, true)
.setOngoing(true)
.setTicker(mContext.getString(R.string.start_update));
mNotifyManager.notify(NotificationId.UPDATE_ID, builder.build());
}
@Override
public void onDownloadStartDownload(int totalSize) {
mBuilder.setContentTitle("正在下载更新")
NotificationCompat.Builder builder =
new NotificationCompat.Builder(mContext)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle(mContext.getString(R.string.download_update))
.setContentText(String.format("%.2f / %.2f KB", 0/1024.0f, totalSize/1024.0f))
.setProgress(totalSize, 0, false).setOngoing(true);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
.setProgress(totalSize, 0, false)
.setOngoing(true);
mNotifyManager.notify(NotificationId.UPDATE_ID, builder.build());
}
@Override
public void onDownloadStatusUpdate(
int downloadSize, int totalSize) {
mBuilder.setContentTitle("正在下载更新")
NotificationCompat.Builder builder =
new NotificationCompat.Builder(mContext)
.setSmallIcon(android.R.drawable.stat_sys_download)
.setContentTitle(mContext.getString(R.string.download_update))
.setContentText(String.format("%.2f / %.2f KB", downloadSize/1024.0f, totalSize/1024.0f))
.setProgress(totalSize, downloadSize, false).setOngoing(true);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
.setProgress(totalSize, downloadSize, false)
.setOngoing(true);
mNotifyManager.notify(NotificationId.UPDATE_ID, builder.build());
}
@Override
public void onDownloadOver(int status) {
public void onDownloadOver(int status, String eMsg) {
if (status == Downloader.COMPLETED) {
mNotifyManager.cancel(NOTIFICATION_ID);
mNotifyManager.cancel(NotificationId.UPDATE_ID);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(Config.getDownloadPath(), mFileName)),
"application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
} else {
mBuilder.setContentTitle("下载更新失败")
.setContentText(null)
.setProgress(0, 0, false).setOngoing(false);
mNotifyManager.notify(NOTIFICATION_ID, mBuilder.build());
NotificationCompat.Builder builder =
new NotificationCompat.Builder(mContext)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setContentTitle(mContext.getString(R.string.update_failed))
.setContentText(eMsg)
.setOngoing(false);
mNotifyManager.notify(NotificationId.UPDATE_ID, builder.build());
}
setEnabled(true);
}
}
@@ -1,401 +1,400 @@
package com.hippo.ehviewer.activity;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.commons.lang3.StringEscapeUtils;
import com.hippo.ehviewer.BeautifyScreen;
import com.hippo.ehviewer.DownloadInfo;
import com.hippo.ehviewer.EhClient;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.service.DownloadService;
import com.hippo.ehviewer.service.DownloadServiceConnection;
import com.hippo.ehviewer.util.Cache;
import com.hippo.ehviewer.util.Config;
import com.hippo.ehviewer.util.Download;
import com.hippo.ehviewer.util.Util;
import com.hippo.ehviewer.view.AlertButton;
import com.hippo.ehviewer.view.DownloadItemLayout;
import com.hippo.ehviewer.view.OlImageView;
import com.hippo.ehviewer.widget.DialogBuilder;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import com.hippo.ehviewer.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
public class DownloadActivity extends Activity {
private static final String TAG = "DownloadActivity";
private DownloadServiceConnection mServiceConn = new DownloadServiceConnection();
private List<DownloadInfo> mDownloadInfos;
private DlAdapter mDlAdapter;
private int longClickItemIndex;
private AlertDialog longClickDialog;
private AlertDialog setLongClickDialog() {
return new DialogBuilder(this).setTitle(R.string.what_to_do)
.setItems(R.array.download_item_long_click, new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
switch (position) {
case 0: // Remove info item
mServiceConn.getService().cancel(Download.getKey(longClickItemIndex));
Download.remove(longClickItemIndex);
mDlAdapter.notifyDataSetChanged();
break;
case 1: // Remove info item
mServiceConn.getService().cancel(Download.getKey(longClickItemIndex));
mDlAdapter.notifyDataSetChanged();
// TODO 有人反馈 Download.get(longClickItemIndex).title 为空,看来很有必要在正则抓取时检查是否为空
File dir = new File(Config.getDownloadPath(), StringEscapeUtils.escapeHtml4(Download.get(longClickItemIndex).title));
try {
Util.deleteContents(dir);
} catch (IOException e) {
e.printStackTrace();
}
dir.delete();
Download.remove(longClickItemIndex);
break;
case 2:
DownloadInfo di= mDownloadInfos.get(longClickItemIndex);
Intent intent = new Intent(DownloadActivity.this,
MangaDownloadActivity.class);
intent.putExtra(MangaDownloadActivity.KEY_TITLE, di.title);
intent.putExtra(MangaDownloadActivity.KEY_SIZE, di.pageSum);
intent.putExtra(MangaDownloadActivity.KEY_GID, di.gid);
intent.putExtra(MangaDownloadActivity.KEY_END_INDEX, di.lastStartIndex);
startActivity(intent);
default:
break;
}
longClickDialog.cancel();
}
}).setNegativeButton(android.R.string.cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
((AlertButton)v).dialog.dismiss();
}
}).create();
}
private class DlAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public DlAdapter() {
mInflater = LayoutInflater.from(DownloadActivity.this);
}
@Override
public int getCount() {
return mDownloadInfos.size();
}
@Override
public Object getItem(int arg0) {
return mDownloadInfos.get(arg0);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
DownloadInfo di= mDownloadInfos.get(position);
if (convertView != null) {
DownloadItemLayout view = (DownloadItemLayout)convertView;
if (!view.gid.equals(di.gid)) {
view.gid = di.gid;
view.status = di.status;
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
view.isWait = false;
OlImageView thumb = (OlImageView)view
.findViewById(R.id.thumb);
thumb.setUrl(di.thumb);
thumb.setKey(String.valueOf(di.gid));
thumb.setCache(Cache.memoryCache, Cache.cpCache);
thumb.loadImage(true);
TextView title = (TextView)view.findViewById(R.id.title);
title.setText(di.title);
setDownloadInfo(view, di);
} else if (view.status != di.status || view.isWait) {
view.status = di.status;
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
view.isWait = false;
setDownloadInfo(view, di);
} else if (view.status == DownloadInfo.DOWNLOADING &&
(view.type != di.type
|| view.lastStartIndex != di.lastStartIndex
|| view.downloadSize != di.downloadSize)) {
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
ProgressBar pb = (ProgressBar)view.findViewById(R.id.progressBar);
TextView info = (TextView)view.findViewById(R.id.info);
if (di.type == DownloadInfo.DETAIL_URL) {
pb.setIndeterminate(true);
info.setText(R.string.downloading);
} else {
pb.setIndeterminate(false);
pb.setMax(di.pageSum);
pb.setProgress(di.lastStartIndex);
StringBuilder sb = new StringBuilder(getString(R.string.downloading));
sb.append(" ").append(di.lastStartIndex).append(" / ").append(di.pageSum).append("\n");
if (di.totalSize != 0)
sb.append(String.format("%.2f", di.downloadSize))
.append(" / ").append(String.format("%.2f", di.totalSize)).append(" KB");
info.setText(sb.toString());
}
}
return view;
}
DownloadItemLayout view = (DownloadItemLayout)mInflater.inflate(R.layout.download_item, null);
view.gid = di.gid;
view.status = di.status;
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
view.isWait = false;
OlImageView thumb = (OlImageView)view
.findViewById(R.id.thumb);
thumb.setUrl(di.thumb);
thumb.setKey(String.valueOf(di.gid));
thumb.setCache(Cache.memoryCache, Cache.cpCache);
thumb.loadImage(true);
TextView title = (TextView)view.findViewById(R.id.title);
title.setText(di.title);
setDownloadInfo(view, di);
return view;
}
/**
* For clickable button, when click change message to "Please wait", then when action over change message
*
* @param view
* @param di
* @param position
*/
private void setDownloadInfo(final DownloadItemLayout view, final DownloadInfo di) {
final ProgressBar pb = (ProgressBar)view.findViewById(R.id.progressBar);
final TextView info = (TextView)view.findViewById(R.id.info);
final ImageView action = (ImageView)view.findViewById(R.id.action);
if (di.status == DownloadInfo.STOP) {
pb.setVisibility(View.GONE);
String meg = getString(R.string.not_started) + (di.type == DownloadInfo.DETAIL_URL ? ""
: (" " + (di.lastStartIndex) + " / " + di.pageSum));
info.setText(meg);
action.setImageResource(R.drawable.ic_action_start);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
Intent it = new Intent(DownloadActivity.this, DownloadService.class);
startService(it);
mServiceConn.getService().add(di);
}
});
} else if (di.status == DownloadInfo.DOWNLOADING) {
pb.setVisibility(View.VISIBLE);
if (di.type == DownloadInfo.DETAIL_URL) {
pb.setIndeterminate(true);
info.setText(R.string.downloading);
} else {
pb.setIndeterminate(false);
pb.setMax(di.pageSum);
pb.setProgress(di.lastStartIndex);
StringBuilder sb = new StringBuilder(getString(R.string.downloading));
sb.append(" ").append(di.lastStartIndex).append(" / ").append(di.pageSum).append("\n");
if (di.totalSize != 0)
sb.append(String.format("%.2f", di.downloadSize))
.append(" / ").append(String.format("%.2f", di.totalSize)).append(" KB");
info.setText(sb.toString());
}
action.setImageResource(R.drawable.ic_action_pause);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
mServiceConn.getService().cancel(di.gid);
}
});
} else if (di.status == DownloadInfo.WAITING) {
pb.setVisibility(View.GONE);
info.setText(R.string.waiting);
action.setImageResource(R.drawable.ic_action_pause);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
mServiceConn.getService().cancel(di.gid);
}
});
} else if (di.status == DownloadInfo.COMPLETED) {
pb.setVisibility(View.GONE);
info.setText(R.string.download_successfully);
action.setImageResource(R.drawable.ic_action_completed);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DownloadActivity.this,
MangaDownloadActivity.class);
intent.putExtra(MangaDownloadActivity.KEY_TITLE, di.title);
intent.putExtra(MangaDownloadActivity.KEY_SIZE, di.pageSum);
intent.putExtra(MangaDownloadActivity.KEY_GID, di.gid);
intent.putExtra(MangaDownloadActivity.KEY_END_INDEX, di.lastStartIndex);
startActivity(intent);
}
});
} else if (di.status == DownloadInfo.FAILED) {
pb.setVisibility(View.GONE);
String meg = getString(R.string.download_unsuccessfully) + (di.type == DownloadInfo.DETAIL_URL ? ""
: (" " + (di.lastStartIndex) + " / " + di.pageSum));
info.setText(meg);
action.setImageResource(R.drawable.ic_action_start);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
Intent it = new Intent(DownloadActivity.this, DownloadService.class);
startService(it);
mServiceConn.getService().add(di);
}
});
}
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (Build.VERSION.SDK_INT >= 19) {
BeautifyScreen.fixColour(this);
}
}
@Override
protected void onResume() {
super.onResume();
int screenOri = Config.getScreenOriMode();
if (screenOri != getRequestedOrientation())
setRequestedOrientation(screenOri);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
unbindService(mServiceConn);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.download);
int screenOri = Config.getScreenOriMode();
if (screenOri != getRequestedOrientation())
setRequestedOrientation(screenOri);
// Download service
Intent it = new Intent(this, DownloadService.class);
bindService(it, mServiceConn, BIND_AUTO_CREATE);
IntentFilter filter = new IntentFilter();
filter.addAction(DownloadService.ACTION_UPDATE);
registerReceiver(mReceiver, filter);
longClickDialog = setLongClickDialog();
// For colourfy the activity
if (Build.VERSION.SDK_INT >= 19) {
BeautifyScreen.ColourfyScreen(this);
}
mDownloadInfos = Download.getDownloadInfoList();
ListView listView = (ListView)findViewById(R.id.download);
mDlAdapter = new DlAdapter();
listView.setAdapter(mDlAdapter);
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
longClickItemIndex = position;
longClickDialog.show();
return true;
}
});
}
private BroadcastReceiver mReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(DownloadService.ACTION_UPDATE))
mDlAdapter.notifyDataSetChanged();
}
};
}
package com.hippo.ehviewer.activity;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.commons.lang3.StringEscapeUtils;
import com.hippo.ehviewer.BeautifyScreen;
import com.hippo.ehviewer.EhClient;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.service.DownloadService;
import com.hippo.ehviewer.service.DownloadServiceConnection;
import com.hippo.ehviewer.util.Cache;
import com.hippo.ehviewer.util.Config;
import com.hippo.ehviewer.util.Download;
import com.hippo.ehviewer.util.Util;
import com.hippo.ehviewer.view.AlertButton;
import com.hippo.ehviewer.view.DownloadItemLayout;
import com.hippo.ehviewer.view.OlImageView;
import com.hippo.ehviewer.widget.DialogBuilder;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import com.hippo.ehviewer.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
public class DownloadActivity extends Activity {
private static final String TAG = "DownloadActivity";
private DownloadServiceConnection mServiceConn = new DownloadServiceConnection();
private List<DownloadInfo> mDownloadInfos;
private DlAdapter mDlAdapter;
private int longClickItemIndex;
private AlertDialog longClickDialog;
private AlertDialog setLongClickDialog() {
return new DialogBuilder(this).setTitle(R.string.what_to_do)
.setItems(R.array.download_item_long_click, new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
switch (position) {
case 0: // Remove info item
mServiceConn.getService().cancel(Download.getKey(longClickItemIndex));
Download.remove(longClickItemIndex);
mDlAdapter.notifyDataSetChanged();
break;
case 1: // Remove info item
mServiceConn.getService().cancel(Download.getKey(longClickItemIndex));
mDlAdapter.notifyDataSetChanged();
// TODO 有人反馈 Download.get(longClickItemIndex).title 为空,看来很有必要在正则抓取时检查是否为空
File dir = new File(Config.getDownloadPath(), StringEscapeUtils.escapeHtml4(Download.get(longClickItemIndex).title));
try {
Util.deleteContents(dir);
} catch (IOException e) {
e.printStackTrace();
}
dir.delete();
Download.remove(longClickItemIndex);
break;
case 2:
DownloadInfo di= mDownloadInfos.get(longClickItemIndex);
Intent intent = new Intent(DownloadActivity.this,
MangaDownloadActivity.class);
intent.putExtra(MangaDownloadActivity.KEY_TITLE, di.title);
intent.putExtra(MangaDownloadActivity.KEY_SIZE, di.pageSum);
intent.putExtra(MangaDownloadActivity.KEY_GID, di.gid);
intent.putExtra(MangaDownloadActivity.KEY_END_INDEX, di.lastStartIndex);
startActivity(intent);
default:
break;
}
longClickDialog.cancel();
}
}).setNegativeButton(android.R.string.cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
((AlertButton)v).dialog.dismiss();
}
}).create();
}
private class DlAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public DlAdapter() {
mInflater = LayoutInflater.from(DownloadActivity.this);
}
@Override
public int getCount() {
return mDownloadInfos.size();
}
@Override
public Object getItem(int arg0) {
return mDownloadInfos.get(arg0);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
DownloadInfo di= mDownloadInfos.get(position);
if (convertView != null) {
DownloadItemLayout view = (DownloadItemLayout)convertView;
if (!view.gid.equals(di.gid)) {
view.gid = di.gid;
view.status = di.status;
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
view.isWait = false;
OlImageView thumb = (OlImageView)view
.findViewById(R.id.thumb);
thumb.setUrl(di.thumb);
thumb.setKey(String.valueOf(di.gid));
thumb.setCache(Cache.memoryCache, Cache.cpCache);
thumb.loadImage(true);
TextView title = (TextView)view.findViewById(R.id.title);
title.setText(di.title);
setDownloadInfo(view, di);
} else if (view.status != di.status || view.isWait) {
view.status = di.status;
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
view.isWait = false;
setDownloadInfo(view, di);
} else if (view.status == DownloadInfo.DOWNLOADING &&
(view.type != di.type
|| view.lastStartIndex != di.lastStartIndex
|| view.downloadSize != di.downloadSize)) {
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
ProgressBar pb = (ProgressBar)view.findViewById(R.id.progressBar);
TextView info = (TextView)view.findViewById(R.id.info);
if (di.type == DownloadInfo.DETAIL_URL) {
pb.setIndeterminate(true);
info.setText(R.string.downloading);
} else {
pb.setIndeterminate(false);
pb.setMax(di.pageSum);
pb.setProgress(di.lastStartIndex);
StringBuilder sb = new StringBuilder(getString(R.string.downloading));
sb.append(" ").append(di.lastStartIndex).append(" / ").append(di.pageSum).append("\n");
if (di.totalSize != 0)
sb.append(String.format("%.2f", di.downloadSize))
.append(" / ").append(String.format("%.2f", di.totalSize)).append(" KB");
info.setText(sb.toString());
}
}
return view;
}
DownloadItemLayout view = (DownloadItemLayout)mInflater.inflate(R.layout.download_item, null);
view.gid = di.gid;
view.status = di.status;
view.type = di.type;
view.lastStartIndex = di.lastStartIndex;
view.downloadSize = di.downloadSize;
view.isWait = false;
OlImageView thumb = (OlImageView)view
.findViewById(R.id.thumb);
thumb.setUrl(di.thumb);
thumb.setKey(String.valueOf(di.gid));
thumb.setCache(Cache.memoryCache, Cache.cpCache);
thumb.loadImage(true);
TextView title = (TextView)view.findViewById(R.id.title);
title.setText(di.title);
setDownloadInfo(view, di);
return view;
}
/**
* For clickable button, when click change message to "Please wait", then when action over change message
*
* @param view
* @param di
* @param position
*/
private void setDownloadInfo(final DownloadItemLayout view, final DownloadInfo di) {
final ProgressBar pb = (ProgressBar)view.findViewById(R.id.progressBar);
final TextView info = (TextView)view.findViewById(R.id.info);
final ImageView action = (ImageView)view.findViewById(R.id.action);
if (di.status == DownloadInfo.STOP) {
pb.setVisibility(View.GONE);
String meg = getString(R.string.not_started) + (di.type == DownloadInfo.DETAIL_URL ? ""
: (" " + (di.lastStartIndex) + " / " + di.pageSum));
info.setText(meg);
action.setImageResource(R.drawable.ic_action_start);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
Intent it = new Intent(DownloadActivity.this, DownloadService.class);
startService(it);
mServiceConn.getService().add(di);
}
});
} else if (di.status == DownloadInfo.DOWNLOADING) {
pb.setVisibility(View.VISIBLE);
if (di.type == DownloadInfo.DETAIL_URL) {
pb.setIndeterminate(true);
info.setText(R.string.downloading);
} else {
pb.setIndeterminate(false);
pb.setMax(di.pageSum);
pb.setProgress(di.lastStartIndex);
StringBuilder sb = new StringBuilder(getString(R.string.downloading));
sb.append(" ").append(di.lastStartIndex).append(" / ").append(di.pageSum).append("\n");
if (di.totalSize != 0)
sb.append(String.format("%.2f", di.downloadSize))
.append(" / ").append(String.format("%.2f", di.totalSize)).append(" KB");
info.setText(sb.toString());
}
action.setImageResource(R.drawable.ic_action_pause);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
mServiceConn.getService().cancel(di.gid);
}
});
} else if (di.status == DownloadInfo.WAITING) {
pb.setVisibility(View.GONE);
info.setText(R.string.waiting);
action.setImageResource(R.drawable.ic_action_pause);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
mServiceConn.getService().cancel(di.gid);
}
});
} else if (di.status == DownloadInfo.COMPLETED) {
pb.setVisibility(View.GONE);
info.setText(R.string.download_successfully);
action.setImageResource(R.drawable.ic_action_completed);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DownloadActivity.this,
MangaDownloadActivity.class);
intent.putExtra(MangaDownloadActivity.KEY_TITLE, di.title);
intent.putExtra(MangaDownloadActivity.KEY_SIZE, di.pageSum);
intent.putExtra(MangaDownloadActivity.KEY_GID, di.gid);
intent.putExtra(MangaDownloadActivity.KEY_END_INDEX, di.lastStartIndex);
startActivity(intent);
}
});
} else if (di.status == DownloadInfo.FAILED) {
pb.setVisibility(View.GONE);
String meg = getString(R.string.download_unsuccessfully) + (di.type == DownloadInfo.DETAIL_URL ? ""
: (" " + (di.lastStartIndex) + " / " + di.pageSum));
info.setText(meg);
action.setImageResource(R.drawable.ic_action_start);
action.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pb.setVisibility(View.GONE);
info.setText(R.string.wait);
action.setClickable(false);
view.isWait = true;
Intent it = new Intent(DownloadActivity.this, DownloadService.class);
startService(it);
mServiceConn.getService().add(di);
}
});
}
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (Build.VERSION.SDK_INT >= 19) {
BeautifyScreen.fixColour(this);
}
}
@Override
protected void onResume() {
super.onResume();
int screenOri = Config.getScreenOriMode();
if (screenOri != getRequestedOrientation())
setRequestedOrientation(screenOri);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
unbindService(mServiceConn);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.download);
int screenOri = Config.getScreenOriMode();
if (screenOri != getRequestedOrientation())
setRequestedOrientation(screenOri);
// Download service
Intent it = new Intent(this, DownloadService.class);
bindService(it, mServiceConn, BIND_AUTO_CREATE);
IntentFilter filter = new IntentFilter();
filter.addAction(DownloadService.ACTION_UPDATE);
registerReceiver(mReceiver, filter);
longClickDialog = setLongClickDialog();
// For colourfy the activity
if (Build.VERSION.SDK_INT >= 19) {
BeautifyScreen.ColourfyScreen(this);
}
mDownloadInfos = Download.getDownloadInfoList();
ListView listView = (ListView)findViewById(R.id.download);
mDlAdapter = new DlAdapter();
listView.setAdapter(mDlAdapter);
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
longClickItemIndex = position;
longClickDialog.show();
return true;
}
});
}
private BroadcastReceiver mReceiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(DownloadService.ACTION_UPDATE))
mDlAdapter.notifyDataSetChanged();
}
};
}
@@ -1,4 +1,4 @@
package com.hippo.ehviewer;
package com.hippo.ehviewer.activity;
public class DownloadInfo {
public static final int STOP = 0x0;
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -1,5 +1,7 @@
package com.hippo.ehviewer.activity;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -27,6 +29,7 @@ import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
@@ -57,6 +60,7 @@ public class SettingsActivity extends PreferenceActivity {
private static final String THANKS = "preference_thanks";
private static final String UPDATE = "preference_update";
private static final String RAN = "preference_remove_all_noification";
private static final String MEDIA_SCAN = "preference_media_scan";
private EditTextPreference cachePre;
private Preference clearCachePre;
@@ -287,6 +291,26 @@ public class SettingsActivity extends PreferenceActivity {
return true;
}
});
CheckBoxPreference mediaScan = (CheckBoxPreference)screen.findPreference(MEDIA_SCAN);
mediaScan.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
boolean value = (Boolean)newValue;
File nomedia = new File(Config.getDownloadPath(), ".nomedia");
if (value) {
nomedia.delete();
} else {
try {
nomedia.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
}
});
}
private void updateCpCacheSummary() {
File diff suppressed because it is too large. Load diff
+248 -248
View File
@@ -1,248 +1,248 @@
package com.hippo.ehviewer.gallery.data;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Set;
import com.hippo.ehviewer.util.Future;
import com.hippo.ehviewer.util.FutureListener;
import com.hippo.ehviewer.util.ThreadPool;
import com.hippo.ehviewer.util.ThreadPool.Job;
import com.hippo.ehviewer.util.ThreadPool.JobContext;
import com.hippo.ehviewer.util.Util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Movie;
import com.hippo.ehviewer.util.Log;
import android.util.SparseArray;
// TODO 初期建立一个线程检索文件夹中所有文件以寻找到所有图片文件
/**
* @author Hippo
*
* ImageSet 用于记录漫画的下载信息
* 对于已完成下载的则无特殊之处。
* 对于未完成下载的要记录,开始下载之处,目前下载截止之处,
* 以及下载失败之处。
* 同时拥有检查该目录识别图片文件。
*/
public class ImageSet {
@SuppressWarnings("unused")
private static final String TAG = "ImageSet";
private static final String GIF_EXTENSION = "gif";
public static final int TYPE_NONE = 0x0;
public static final int TYPE_BITMAP = 0x1;
public static final int TYPE_MOVIE = 0x2;
public static final int INVALID_ID = -1;
public static final int STATE_NONE = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_LOADED = 2;
public static final int STATE_FAIL = 3;
protected Context mContext;
protected String mGid;
protected File mFolder;
protected int mSize;
private SparseArray<ImageData> mImagesDate;
private ThreadPool mThreadPool;
private OnStateChangeListener mOnStateChangeListener;
public interface OnStateChangeListener {
void onStateChange(int index, int state);
}
public interface OnDecodeOverListener {
/**
* May return Bitmap or Movie
*
* @param res
* @param index
*/
void onDecodeOver(Object res, int index);
}
private class ImageData {
int state;
String fileName;
int type;
public ImageData() {
state = STATE_NONE;
fileName = null;
type = TYPE_NONE;
}
}
// [startIndex, endIndex)
public ImageSet(Context context, String gid, File folder, int size, int startIndex, int endIndex,
Set<Integer> failIndexSet) {
if (folder == null || !folder.isDirectory())
size = 0;
// TODO
/*
if (folder == null)
throw new IllegalArgumentException("Folder is null");
if (!folder.isDirectory())
throw new IllegalArgumentException("Folder is not directory, path is " + folder.getPath());
*/
if (size < 0)
size = 0;
if (endIndex > size)
endIndex = size;
if (startIndex < 0)
startIndex = 0;
if (startIndex > endIndex)
startIndex = endIndex;
// TODO
/*
if (size < 0 || startIndex < 0
|| startIndex > endIndex || endIndex > size)
throw new IllegalArgumentException("size or index value error, size = "
+ size + ", startIndex = " + startIndex
+ ", endIndex = " + endIndex + ", path is " + folder.getPath());
*/
mContext = context;
mGid = gid;
mFolder = folder;
mSize = size;
// TODO sometimes size is too large
mImagesDate = new SparseArray<ImageData>(mSize);
int i = 0;
for (; i < startIndex; i++) {
mImagesDate.append(i, new ImageData());
}
for (; i < endIndex; i++) {
if (failIndexSet != null && failIndexSet.contains(i)) {
ImageData imageData = new ImageData();
imageData.state = STATE_FAIL;
mImagesDate.append(i, imageData);
}
else {
// Get file name only when you need it
ImageData imageData = new ImageData();
imageData.state = STATE_LOADED;
mImagesDate.append(i, imageData);
}
}
for (; i < size; i++) {
mImagesDate.append(i, new ImageData());
}
mThreadPool = new ThreadPool(1, 1);
}
public int getSize() {
return mSize;
}
public void setOnStateChangeListener(OnStateChangeListener l) {
mOnStateChangeListener = l;
}
public int getImage(final int index, final OnDecodeOverListener listener) {
final ImageData imageData = mImagesDate.get(index);
int state;
if (imageData == null)
state = INVALID_ID;
else
state = imageData.state;
if (state == STATE_LOADED && listener != null) {
mThreadPool.submit(new Job<Object>() {
@Override
public Object run(JobContext jc) {
Object res = null;
if (imageData.fileName == null
&& !getFileForName(getFileNameForIndex(index), imageData))
return null;
File file = new File(mFolder, imageData.fileName);
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
if (imageData.type == TYPE_BITMAP) {
BitmapFactory.Options opt = new BitmapFactory.Options();
// TODO why only ARGB_8888 always work well, other may slit image
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
res = BitmapFactory.decodeStream(fis, null, opt);
} else if (imageData.type == TYPE_MOVIE) {
res = Movie.decodeStream(fis);
} else {
// TYPE_NONE or something else, get error
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null)
Util.closeStreamQuietly(fis);
}
return res;
}
}, new FutureListener<Object>() {
@Override
public void onFutureDone(Future<Object> future) {
listener.onDecodeOver(future.get(), index);
}
});
}
return state;
}
@SuppressLint("DefaultLocale")
public String getFileNameForIndex(int index) {
return String.format("%05d", index + 1);
}
public boolean getFileForName(String name, ImageData imageData) {
String[] list = mFolder.list();
for (String item : list) {
if(name.equals(Util.getName(item))) {
imageData.fileName = item;
if (Util.getExtension(item).toLowerCase().equals(GIF_EXTENSION))
imageData.type = TYPE_MOVIE;
else
imageData.type = TYPE_BITMAP;
return true;
}
}
return false;
}
public void changeState(int index, int state) {
final ImageData imageData = mImagesDate.get(index);
if(imageData != null) {
imageData.state = state;
if (mOnStateChangeListener != null) {
mOnStateChangeListener.onStateChange(index, state);
}
}
}
/**
* mSize is faithful
*
*/
public void scan() {
String[] fileList = mFolder.list();
}
}
package com.hippo.ehviewer.gallery.data;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Set;
import com.hippo.ehviewer.util.Future;
import com.hippo.ehviewer.util.FutureListener;
import com.hippo.ehviewer.util.ThreadPool;
import com.hippo.ehviewer.util.ThreadPool.Job;
import com.hippo.ehviewer.util.ThreadPool.JobContext;
import com.hippo.ehviewer.util.Util;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Movie;
import com.hippo.ehviewer.util.Log;
import android.util.SparseArray;
// TODO 初期建立一个线程检索文件夹中所有文件以寻找到所有图片文件
/**
* @author Hippo
*
* ImageSet 用于记录漫画的下载信息
* 对于已完成下载的则无特殊之处。
* 对于未完成下载的要记录,开始下载之处,目前下载截止之处,
* 以及下载失败之处。
* 同时拥有检查该目录识别图片文件。
*/
public class ImageSet {
@SuppressWarnings("unused")
private static final String TAG = "ImageSet";
private static final String GIF_EXTENSION = "gif";
public static final int TYPE_NONE = 0x0;
public static final int TYPE_BITMAP = 0x1;
public static final int TYPE_MOVIE = 0x2;
public static final int INVALID_ID = -1;
public static final int STATE_NONE = 0;
public static final int STATE_LOADING = 1;
public static final int STATE_LOADED = 2;
public static final int STATE_FAIL = 3;
protected Context mContext;
protected String mGid;
protected File mFolder;
protected int mSize;
private SparseArray<ImageData> mImagesDate;
private ThreadPool mThreadPool;
private OnStateChangeListener mOnStateChangeListener;
public interface OnStateChangeListener {
void onStateChange(int index, int state);
}
public interface OnDecodeOverListener {
/**
* May return Bitmap or Movie
*
* @param res
* @param index
*/
void onDecodeOver(Object res, int index);
}
private class ImageData {
int state;
String fileName;
int type;
public ImageData() {
state = STATE_NONE;
fileName = null;
type = TYPE_NONE;
}
}
// [startIndex, endIndex)
public ImageSet(Context context, String gid, File folder, int size, int startIndex, int endIndex,
Set<Integer> failIndexSet) {
if (folder == null || !folder.isDirectory())
size = 0;
// TODO
/*
if (folder == null)
throw new IllegalArgumentException("Folder is null");
if (!folder.isDirectory())
throw new IllegalArgumentException("Folder is not directory, path is " + folder.getPath());
*/
if (size < 0)
size = 0;
if (endIndex > size)
endIndex = size;
if (startIndex < 0)
startIndex = 0;
if (startIndex > endIndex)
startIndex = endIndex;
// TODO
/*
if (size < 0 || startIndex < 0
|| startIndex > endIndex || endIndex > size)
throw new IllegalArgumentException("size or index value error, size = "
+ size + ", startIndex = " + startIndex
+ ", endIndex = " + endIndex + ", path is " + folder.getPath());
*/
mContext = context;
mGid = gid;
mFolder = folder;
mSize = size;
// TODO sometimes size is too large
mImagesDate = new SparseArray<ImageData>(mSize);
int i = 0;
for (; i < startIndex; i++) {
mImagesDate.append(i, new ImageData());
}
for (; i < endIndex; i++) {
if (failIndexSet != null && failIndexSet.contains(i)) {
ImageData imageData = new ImageData();
imageData.state = STATE_FAIL;
mImagesDate.append(i, imageData);
}
else {
// Get file name only when you need it
ImageData imageData = new ImageData();
imageData.state = STATE_LOADED;
mImagesDate.append(i, imageData);
}
}
for (; i < size; i++) {
mImagesDate.append(i, new ImageData());
}
mThreadPool = new ThreadPool(1, 1);
}
public int getSize() {
return mSize;
}
public void setOnStateChangeListener(OnStateChangeListener l) {
mOnStateChangeListener = l;
}
public int getImage(final int index, final OnDecodeOverListener listener) {
final ImageData imageData = mImagesDate.get(index);
int state;
if (imageData == null)
state = INVALID_ID;
else
state = imageData.state;
if (state == STATE_LOADED && listener != null) {
mThreadPool.submit(new Job<Object>() {
@Override
public Object run(JobContext jc) {
Object res = null;
if (imageData.fileName == null
&& !getFileForName(getFileNameForIndex(index), imageData))
return null;
File file = new File(mFolder, imageData.fileName);
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
if (imageData.type == TYPE_BITMAP) {
BitmapFactory.Options opt = new BitmapFactory.Options();
// TODO why only ARGB_8888 always work well, other may slit image
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
res = BitmapFactory.decodeStream(fis, null, opt);
} else if (imageData.type == TYPE_MOVIE) {
res = Movie.decodeStream(fis);
} else {
// TYPE_NONE or something else, get error
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null)
Util.closeStreamQuietly(fis);
}
return res;
}
}, new FutureListener<Object>() {
@Override
public void onFutureDone(Future<Object> future) {
listener.onDecodeOver(future.get(), index);
}
});
}
return state;
}
@SuppressLint("DefaultLocale")
public String getFileNameForIndex(int index) {
return String.format("%05d", index + 1);
}
public boolean getFileForName(String name, ImageData imageData) {
String[] list = mFolder.list();
for (String item : list) {
if(name.equals(Util.getName(item))) {
imageData.fileName = item;
if (Util.getExtension(item).toLowerCase().equals(GIF_EXTENSION))
imageData.type = TYPE_MOVIE;
else
imageData.type = TYPE_BITMAP;
return true;
}
}
return false;
}
public void changeState(int index, int state) {
final ImageData imageData = mImagesDate.get(index);
if(imageData != null) {
imageData.state = state;
if (mOnStateChangeListener != null) {
mOnStateChangeListener.onStateChange(index, state);
}
}
}
/**
* mSize is faithful
*
*/
public void scan() {
String[] fileList = mFolder.list();
}
}
@@ -1,299 +1,299 @@
/*
* 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.glrenderer;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.opengl.GLUtils;
import com.hippo.ehviewer.util.Log;
import junit.framework.Assert;
import java.util.HashMap;
import javax.microedition.khronos.opengles.GL11;
// UploadedTextures use a Bitmap for the content of the texture.
//
// Subclasses should implement onGetBitmap() to provide the Bitmap and
// implement onFreeBitmap(mBitmap) which will be called when the Bitmap
// is not needed anymore.
//
// isContentValid() is meaningful only when the isLoaded() returns true.
// It means whether the content needs to be updated.
//
// The user of this class should call recycle() when the texture is not
// needed anymore.
//
// By default an UploadedTexture is opaque (so it can be drawn faster without
// blending). The user or subclass can override it using setOpaque().
public abstract class UploadedTexture extends BasicTexture {
// To prevent keeping allocation the borders, we store those used borders here.
// Since the length will be power of two, it won't use too much memory.
private static HashMap<BorderKey, Bitmap> sBorderLines =
new HashMap<BorderKey, Bitmap>();
private static BorderKey sBorderKey = new BorderKey();
@SuppressWarnings("unused")
private static final String TAG = "Texture";
private boolean mContentValid = true;
// indicate this textures is being uploaded in background
private boolean mIsUploading = false;
private boolean mOpaque = true;
private boolean mThrottled = false;
private static int sUploadedCount;
private static final int UPLOAD_LIMIT = 100;
protected Bitmap mBitmap;
private int mBorder;
protected UploadedTexture() {
this(false);
}
protected UploadedTexture(boolean hasBorder) {
super(null, 0, STATE_UNLOADED);
if (hasBorder) {
setBorder(true);
mBorder = 1;
}
}
protected void setIsUploading(boolean uploading) {
mIsUploading = uploading;
}
public boolean isUploading() {
return mIsUploading;
}
private static class BorderKey implements Cloneable {
public boolean vertical;
public Config config;
public int length;
@Override
public int hashCode() {
int x = config.hashCode() ^ length;
return vertical ? x : -x;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof BorderKey)) return false;
BorderKey o = (BorderKey) object;
return vertical == o.vertical
&& config == o.config && length == o.length;
}
@Override
public BorderKey clone() {
try {
return (BorderKey) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
}
protected void setThrottled(boolean throttled) {
mThrottled = throttled;
}
private static Bitmap getBorderLine(
boolean vertical, Config config, int length) {
BorderKey key = sBorderKey;
key.vertical = vertical;
key.config = config;
key.length = length;
Bitmap bitmap = sBorderLines.get(key);
if (bitmap == null) {
bitmap = vertical
? Bitmap.createBitmap(1, length, config)
: Bitmap.createBitmap(length, 1, config);
sBorderLines.put(key.clone(), bitmap);
}
return bitmap;
}
private Bitmap getBitmap() {
if (mBitmap == null) {
mBitmap = onGetBitmap();
int w = mBitmap.getWidth() + mBorder * 2;
int h = mBitmap.getHeight() + mBorder * 2;
if (mWidth == UNSPECIFIED) {
setSize(w, h);
}
}
return mBitmap;
}
private void freeBitmap() {
//Assert.assertTrue(mBitmap != null);
if (mBitmap != null)
onFreeBitmap(mBitmap);
mBitmap = null;
}
@Override
public int getWidth() {
if (mWidth == UNSPECIFIED) getBitmap();
return mWidth;
}
@Override
public int getHeight() {
if (mWidth == UNSPECIFIED) getBitmap();
return mHeight;
}
protected abstract Bitmap onGetBitmap();
protected abstract void onFreeBitmap(Bitmap bitmap);
protected void invalidateContent() {
if (mBitmap != null) freeBitmap();
mContentValid = false;
mWidth = UNSPECIFIED;
mHeight = UNSPECIFIED;
}
/**
* Whether the content on GPU is valid.
*/
public boolean isContentValid() {
return isLoaded() && mContentValid;
}
/**
* Updates the content on GPU's memory.
* @param canvas
*/
public void updateContent(GLCanvas canvas) {
if (!isLoaded()) {
if (mThrottled && ++sUploadedCount > UPLOAD_LIMIT) {
return;
}
uploadToCanvas(canvas);
} else if (!mContentValid) {
Bitmap bitmap = getBitmap();
int format = GLUtils.getInternalFormat(bitmap);
int type = GLUtils.getType(bitmap);
canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
freeBitmap();
mContentValid = true;
}
}
public static void resetUploadLimit() {
sUploadedCount = 0;
}
public static boolean uploadLimitReached() {
return sUploadedCount > UPLOAD_LIMIT;
}
private void uploadToCanvas(GLCanvas canvas) {
Bitmap bitmap = getBitmap();
if (bitmap != null) {
try {
int bWidth = bitmap.getWidth();
int bHeight = bitmap.getHeight();
int width = bWidth + mBorder * 2;
int height = bHeight + mBorder * 2;
int texWidth = getTextureWidth();
int texHeight = getTextureHeight();
Assert.assertTrue(bWidth <= texWidth && bHeight <= texHeight);
// Upload the bitmap to a new texture.
mId = canvas.getGLId().generateTexture();
canvas.setTextureParameters(this);
if (bWidth == texWidth && bHeight == texHeight) {
canvas.initializeTexture(this, bitmap);
} else {
int format = GLUtils.getInternalFormat(bitmap);
int type = GLUtils.getType(bitmap);
Config config = bitmap.getConfig();
canvas.initializeTextureSize(this, format, type);
canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
if (mBorder > 0) {
// Left border
Bitmap line = getBorderLine(true, config, texHeight);
canvas.texSubImage2D(this, 0, 0, line, format, type);
// Top border
line = getBorderLine(false, config, texWidth);
canvas.texSubImage2D(this, 0, 0, line, format, type);
}
// Right border
if (mBorder + bWidth < texWidth) {
Bitmap line = getBorderLine(true, config, texHeight);
canvas.texSubImage2D(this, mBorder + bWidth, 0, line, format, type);
}
// Bottom border
if (mBorder + bHeight < texHeight) {
Bitmap line = getBorderLine(false, config, texWidth);
canvas.texSubImage2D(this, 0, mBorder + bHeight, line, format, type);
}
}
} finally {
freeBitmap();
}
// Update texture state.
setAssociatedCanvas(canvas);
mState = STATE_LOADED;
mContentValid = true;
} else {
mState = STATE_ERROR;
throw new RuntimeException("Texture load fail, no bitmap");
}
}
@Override
protected boolean onBind(GLCanvas canvas) {
updateContent(canvas);
return isContentValid();
}
@Override
protected int getTarget() {
return GL11.GL_TEXTURE_2D;
}
public void setOpaque(boolean isOpaque) {
mOpaque = isOpaque;
}
@Override
public boolean isOpaque() {
return mOpaque;
}
@Override
public void recycle() {
super.recycle();
if (mBitmap != null) freeBitmap();
}
}
/*
* 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.glrenderer;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.opengl.GLUtils;
import com.hippo.ehviewer.util.Log;
import junit.framework.Assert;
import java.util.HashMap;
import javax.microedition.khronos.opengles.GL11;
// UploadedTextures use a Bitmap for the content of the texture.
//
// Subclasses should implement onGetBitmap() to provide the Bitmap and
// implement onFreeBitmap(mBitmap) which will be called when the Bitmap
// is not needed anymore.
//
// isContentValid() is meaningful only when the isLoaded() returns true.
// It means whether the content needs to be updated.
//
// The user of this class should call recycle() when the texture is not
// needed anymore.
//
// By default an UploadedTexture is opaque (so it can be drawn faster without
// blending). The user or subclass can override it using setOpaque().
public abstract class UploadedTexture extends BasicTexture {
// To prevent keeping allocation the borders, we store those used borders here.
// Since the length will be power of two, it won't use too much memory.
private static HashMap<BorderKey, Bitmap> sBorderLines =
new HashMap<BorderKey, Bitmap>();
private static BorderKey sBorderKey = new BorderKey();
@SuppressWarnings("unused")
private static final String TAG = "Texture";
private boolean mContentValid = true;
// indicate this textures is being uploaded in background
private boolean mIsUploading = false;
private boolean mOpaque = true;
private boolean mThrottled = false;
private static int sUploadedCount;
private static final int UPLOAD_LIMIT = 100;
protected Bitmap mBitmap;
private int mBorder;
protected UploadedTexture() {
this(false);
}
protected UploadedTexture(boolean hasBorder) {
super(null, 0, STATE_UNLOADED);
if (hasBorder) {
setBorder(true);
mBorder = 1;
}
}
protected void setIsUploading(boolean uploading) {
mIsUploading = uploading;
}
public boolean isUploading() {
return mIsUploading;
}
private static class BorderKey implements Cloneable {
public boolean vertical;
public Config config;
public int length;
@Override
public int hashCode() {
int x = config.hashCode() ^ length;
return vertical ? x : -x;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof BorderKey)) return false;
BorderKey o = (BorderKey) object;
return vertical == o.vertical
&& config == o.config && length == o.length;
}
@Override
public BorderKey clone() {
try {
return (BorderKey) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
}
protected void setThrottled(boolean throttled) {
mThrottled = throttled;
}
private static Bitmap getBorderLine(
boolean vertical, Config config, int length) {
BorderKey key = sBorderKey;
key.vertical = vertical;
key.config = config;
key.length = length;
Bitmap bitmap = sBorderLines.get(key);
if (bitmap == null) {
bitmap = vertical
? Bitmap.createBitmap(1, length, config)
: Bitmap.createBitmap(length, 1, config);
sBorderLines.put(key.clone(), bitmap);
}
return bitmap;
}
private Bitmap getBitmap() {
if (mBitmap == null) {
mBitmap = onGetBitmap();
int w = mBitmap.getWidth() + mBorder * 2;
int h = mBitmap.getHeight() + mBorder * 2;
if (mWidth == UNSPECIFIED) {
setSize(w, h);
}
}
return mBitmap;
}
private void freeBitmap() {
//Assert.assertTrue(mBitmap != null);
if (mBitmap != null)
onFreeBitmap(mBitmap);
mBitmap = null;
}
@Override
public int getWidth() {
if (mWidth == UNSPECIFIED) getBitmap();
return mWidth;
}
@Override
public int getHeight() {
if (mWidth == UNSPECIFIED) getBitmap();
return mHeight;
}
protected abstract Bitmap onGetBitmap();
protected abstract void onFreeBitmap(Bitmap bitmap);
protected void invalidateContent() {
if (mBitmap != null) freeBitmap();
mContentValid = false;
mWidth = UNSPECIFIED;
mHeight = UNSPECIFIED;
}
/**
* Whether the content on GPU is valid.
*/
public boolean isContentValid() {
return isLoaded() && mContentValid;
}
/**
* Updates the content on GPU's memory.
* @param canvas
*/
public void updateContent(GLCanvas canvas) {
if (!isLoaded()) {
if (mThrottled && ++sUploadedCount > UPLOAD_LIMIT) {
return;
}
uploadToCanvas(canvas);
} else if (!mContentValid) {
Bitmap bitmap = getBitmap();
int format = GLUtils.getInternalFormat(bitmap);
int type = GLUtils.getType(bitmap);
canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
freeBitmap();
mContentValid = true;
}
}
public static void resetUploadLimit() {
sUploadedCount = 0;
}
public static boolean uploadLimitReached() {
return sUploadedCount > UPLOAD_LIMIT;
}
private void uploadToCanvas(GLCanvas canvas) {
Bitmap bitmap = getBitmap();
if (bitmap != null) {
try {
int bWidth = bitmap.getWidth();
int bHeight = bitmap.getHeight();
int width = bWidth + mBorder * 2;
int height = bHeight + mBorder * 2;
int texWidth = getTextureWidth();
int texHeight = getTextureHeight();
Assert.assertTrue(bWidth <= texWidth && bHeight <= texHeight);
// Upload the bitmap to a new texture.
mId = canvas.getGLId().generateTexture();
canvas.setTextureParameters(this);
if (bWidth == texWidth && bHeight == texHeight) {
canvas.initializeTexture(this, bitmap);
} else {
int format = GLUtils.getInternalFormat(bitmap);
int type = GLUtils.getType(bitmap);
Config config = bitmap.getConfig();
canvas.initializeTextureSize(this, format, type);
canvas.texSubImage2D(this, mBorder, mBorder, bitmap, format, type);
if (mBorder > 0) {
// Left border
Bitmap line = getBorderLine(true, config, texHeight);
canvas.texSubImage2D(this, 0, 0, line, format, type);
// Top border
line = getBorderLine(false, config, texWidth);
canvas.texSubImage2D(this, 0, 0, line, format, type);
}
// Right border
if (mBorder + bWidth < texWidth) {
Bitmap line = getBorderLine(true, config, texHeight);
canvas.texSubImage2D(this, mBorder + bWidth, 0, line, format, type);
}
// Bottom border
if (mBorder + bHeight < texHeight) {
Bitmap line = getBorderLine(false, config, texWidth);
canvas.texSubImage2D(this, 0, mBorder + bHeight, line, format, type);
}
}
} finally {
freeBitmap();
}
// Update texture state.
setAssociatedCanvas(canvas);
mState = STATE_LOADED;
mContentValid = true;
} else {
mState = STATE_ERROR;
throw new RuntimeException("Texture load fail, no bitmap");
}
}
@Override
protected boolean onBind(GLCanvas canvas) {
updateContent(canvas);
return isContentValid();
}
@Override
protected int getTarget() {
return GL11.GL_TEXTURE_2D;
}
public void setOpaque(boolean isOpaque) {
mOpaque = isOpaque;
}
@Override
public boolean isOpaque() {
return mOpaque;
}
@Override
public void recycle() {
super.recycle();
if (mBitmap != null) freeBitmap();
}
}
File diff suppressed because it is too large. Load diff
@@ -74,7 +74,7 @@ public class Downloader implements Runnable {
* FAILED or COMPLETED or STOPED
* @param status
*/
public void onDownloadOver(int status);
public void onDownloadOver(int status, String eMsg);
}
public class Controlor {
@@ -195,7 +195,7 @@ public class Downloader implements Runnable {
mFile.delete();
if (mListener != null)
mListener.onDownloadOver(status);
mListener.onDownloadOver(status, getEMsg());
}
public int getStatus() {
@@ -4,11 +4,11 @@ import java.util.HashMap;
import java.util.Map;
import com.hippo.ehviewer.AppContext;
import com.hippo.ehviewer.DownloadInfo;
import com.hippo.ehviewer.EhClient;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.EhClient.DownloadMangaManager;
import com.hippo.ehviewer.activity.DownloadActivity;
import com.hippo.ehviewer.activity.DownloadInfo;
import com.hippo.ehviewer.util.Download;
import android.app.Notification;
+221 -215
View File
@@ -1,215 +1,221 @@
package com.hippo.ehviewer.util;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Environment;
import android.preference.PreferenceManager;
public class Config {
@SuppressWarnings("unused")
private static final String TAG = "Config";
private static final String KEY_ALLOWED = "allowed";
private static final String KEY_FIRST = "first_time";
private static final String KEY_LOGIN = "login";
private static final String KEY_IS_EXHENTAI = "is_exhentai";
private static final String KEY_UPDATE_DATE = "update_date";
private static final String CP_CACHE = "preference_cp_cache";
private static final String CP_CACHE_DEFAULT = "25";
private static final String PAGE_SCALING = "preference_page_scaling";
private static final String PAGE_SCALING_DEFAULT = "3";
private static final String START_POSITION = "preference_start_position";
private static final String START_POSITION_DEFAULT = "1";
private static final String SCREEN_ORI = "preference_screen_ori";
private static final String SCREEN_ORI_DEFAULT = "0";
private static final String DOWNLOAD_PATH = "preference_download_path";
private static final String DOWNLOAD_PATH_DEFAULT = Environment.getExternalStorageDirectory() + "/EhViewer/download/";
private static final String UPDATE_SERVER = "preference_update_server";
private static final String UPDATE_SERVER_DEFAULT = "1";
private static boolean mInit = false;
private static Context mContext;
private static SharedPreferences mConfigPre;
/**
* Init Config
*
* @param context Application context
*/
public static void init(Context context) {
if (mInit)
return;
mInit = true;
mContext = context;
mConfigPre = PreferenceManager.getDefaultSharedPreferences(mContext);
}
/**
* Is init
* @return True if init
*/
public static boolean isInit() {
return mInit;
}
/**
* Get is it allowed to launch
*
* @return True if allowed
*/
public static boolean isAllowed() {
return mConfigPre.getBoolean(KEY_ALLOWED, false);
}
/**
* Allowed the appliation to launch
*/
public static void allowed() {
mConfigPre.edit().putBoolean(KEY_ALLOWED, true).apply();
}
/**
* Check is it first time to launch the application
*
* @return
*/
public static boolean isFirstTime() {
return mConfigPre.getBoolean(KEY_FIRST, true);
}
/**
* It is first time to launch the application
*/
public static void firstTime() {
mConfigPre.edit().putBoolean(KEY_FIRST, false).apply();
}
/**
* Is login last time ?
*
* @return
*/
public static boolean isLogin() {
return mConfigPre.getBoolean(KEY_LOGIN, false);
}
public static void loginNow() {
mConfigPre.edit().putBoolean(KEY_LOGIN, true).apply();
}
public static void logoutNow() {
mConfigPre.edit().putBoolean(KEY_LOGIN, false).apply();
}
public static String getDownloadPath() {
return mConfigPre.getString(DOWNLOAD_PATH, DOWNLOAD_PATH_DEFAULT);
}
/**
* Get cover cache size in MB
*
* @return
*/
public static int getCoverDiskCacheSize() {
try {
return Integer.parseInt(mConfigPre.getString(CP_CACHE, CP_CACHE_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(CP_CACHE, CP_CACHE_DEFAULT).apply();
return 25;
}
}
public static int getPageScalingMode() {
int pageScalingMode = 3;
try {
pageScalingMode = Integer.parseInt(mConfigPre.getString(
PAGE_SCALING, PAGE_SCALING_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(PAGE_SCALING, PAGE_SCALING_DEFAULT)
.apply();
}
return pageScalingMode;
}
public static int getStartPosition() {
int startPosition = 1;
try {
startPosition = Integer.parseInt(mConfigPre.getString(
START_POSITION, START_POSITION_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(START_POSITION, START_POSITION_DEFAULT)
.apply();
}
return startPosition;
}
public static int getScreenOriMode() {
int screenOriMode = 0;
try {
screenOriMode = Integer.parseInt(mConfigPre.getString(
SCREEN_ORI, SCREEN_ORI_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(SCREEN_ORI, SCREEN_ORI_DEFAULT)
.apply();
}
return screenOriPre2Value(screenOriMode);
}
public static int screenOriPre2Value(int screenOriModePre) {
switch (screenOriModePre) {
case 0:
return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
case 1:
return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
case 2:
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
default:
return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
}
public static boolean isExhentai() {
return mConfigPre.getBoolean(KEY_IS_EXHENTAI, false);
}
public static void exhentai(boolean isExhentai) {
mConfigPre.edit().putBoolean(KEY_IS_EXHENTAI, isExhentai).apply();
}
public static int getUpdateDate() {
return mConfigPre.getInt(KEY_UPDATE_DATE, 0);
}
public static void setUpdateDate() {
setUpdateDate(Util.getDate());
}
public static void setUpdateDate(int date) {
mConfigPre.edit().putInt(KEY_UPDATE_DATE, date).apply();
}
public static String getUpdateServer() {
int value = 1;
try {
value = Integer.parseInt(mConfigPre.getString(UPDATE_SERVER, null));
} catch (Exception e) {
mConfigPre.edit().putString(UPDATE_SERVER, UPDATE_SERVER_DEFAULT)
.apply();
}
switch (value) {
case 1:
return "qiniu";
case 2:
return "gokuai";
case 0:
default:
return "google";
}
}
}
package com.hippo.ehviewer.util;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.os.Environment;
import android.preference.PreferenceManager;
public class Config {
@SuppressWarnings("unused")
private static final String TAG = "Config";
private static final String KEY_ALLOWED = "allowed";
private static final String KEY_FIRST = "first_time";
private static final String KEY_LOGIN = "login";
private static final String KEY_IS_EXHENTAI = "is_exhentai";
private static final String KEY_UPDATE_DATE = "update_date";
private static final String CP_CACHE = "preference_cp_cache";
private static final String CP_CACHE_DEFAULT = "25";
private static final String PAGE_SCALING = "preference_page_scaling";
private static final String PAGE_SCALING_DEFAULT = "3";
private static final String START_POSITION = "preference_start_position";
private static final String START_POSITION_DEFAULT = "1";
private static final String SCREEN_ORI = "preference_screen_ori";
private static final String SCREEN_ORI_DEFAULT = "0";
private static final String DOWNLOAD_PATH = "preference_download_path";
private static final String DOWNLOAD_PATH_DEFAULT = Environment.getExternalStorageDirectory() + "/EhViewer/download/";
private static final String UPDATE_SERVER = "preference_update_server";
private static final String UPDATE_SERVER_DEFAULT = "1";
private static final String MEDIA_SCAN = "preference_media_scan";
private static final boolean MEDIA_SCAN_DEFAULT = false;
private static boolean mInit = false;
private static Context mContext;
private static SharedPreferences mConfigPre;
/**
* Init Config
*
* @param context Application context
*/
public static void init(Context context) {
if (mInit)
return;
mInit = true;
mContext = context;
mConfigPre = PreferenceManager.getDefaultSharedPreferences(mContext);
}
/**
* Is init
* @return True if init
*/
public static boolean isInit() {
return mInit;
}
/**
* Get is it allowed to launch
*
* @return True if allowed
*/
public static boolean isAllowed() {
return mConfigPre.getBoolean(KEY_ALLOWED, false);
}
/**
* Allowed the appliation to launch
*/
public static void allowed() {
mConfigPre.edit().putBoolean(KEY_ALLOWED, true).apply();
}
/**
* Check is it first time to launch the application
*
* @return
*/
public static boolean isFirstTime() {
return mConfigPre.getBoolean(KEY_FIRST, true);
}
/**
* It is first time to launch the application
*/
public static void firstTime() {
mConfigPre.edit().putBoolean(KEY_FIRST, false).apply();
}
/**
* Is login last time ?
*
* @return
*/
public static boolean isLogin() {
return mConfigPre.getBoolean(KEY_LOGIN, false);
}
public static void loginNow() {
mConfigPre.edit().putBoolean(KEY_LOGIN, true).apply();
}
public static void logoutNow() {
mConfigPre.edit().putBoolean(KEY_LOGIN, false).apply();
}
public static String getDownloadPath() {
return mConfigPre.getString(DOWNLOAD_PATH, DOWNLOAD_PATH_DEFAULT);
}
/**
* Get cover cache size in MB
*
* @return
*/
public static int getCoverDiskCacheSize() {
try {
return Integer.parseInt(mConfigPre.getString(CP_CACHE, CP_CACHE_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(CP_CACHE, CP_CACHE_DEFAULT).apply();
return 25;
}
}
public static int getPageScalingMode() {
int pageScalingMode = 3;
try {
pageScalingMode = Integer.parseInt(mConfigPre.getString(
PAGE_SCALING, PAGE_SCALING_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(PAGE_SCALING, PAGE_SCALING_DEFAULT)
.apply();
}
return pageScalingMode;
}
public static int getStartPosition() {
int startPosition = 1;
try {
startPosition = Integer.parseInt(mConfigPre.getString(
START_POSITION, START_POSITION_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(START_POSITION, START_POSITION_DEFAULT)
.apply();
}
return startPosition;
}
public static int getScreenOriMode() {
int screenOriMode = 0;
try {
screenOriMode = Integer.parseInt(mConfigPre.getString(
SCREEN_ORI, SCREEN_ORI_DEFAULT));
} catch (Exception e) {
mConfigPre.edit().putString(SCREEN_ORI, SCREEN_ORI_DEFAULT)
.apply();
}
return screenOriPre2Value(screenOriMode);
}
public static int screenOriPre2Value(int screenOriModePre) {
switch (screenOriModePre) {
case 0:
return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
case 1:
return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
case 2:
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
default:
return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
}
public static boolean isExhentai() {
return mConfigPre.getBoolean(KEY_IS_EXHENTAI, false);
}
public static void exhentai(boolean isExhentai) {
mConfigPre.edit().putBoolean(KEY_IS_EXHENTAI, isExhentai).apply();
}
public static int getUpdateDate() {
return mConfigPre.getInt(KEY_UPDATE_DATE, 0);
}
public static void setUpdateDate() {
setUpdateDate(Util.getDate());
}
public static void setUpdateDate(int date) {
mConfigPre.edit().putInt(KEY_UPDATE_DATE, date).apply();
}
public static String getUpdateServer() {
int value = 1;
try {
value = Integer.parseInt(mConfigPre.getString(UPDATE_SERVER, null));
} catch (Exception e) {
mConfigPre.edit().putString(UPDATE_SERVER, UPDATE_SERVER_DEFAULT)
.apply();
}
switch (value) {
case 1:
return "qiniu";
case 2:
return "gokuai";
case 0:
default:
return "google";
}
}
public static boolean getMediaScan() {
return mConfigPre.getBoolean(MEDIA_SCAN, MEDIA_SCAN_DEFAULT);
}
}
+1 -1
View File
@@ -10,8 +10,8 @@ import java.util.ArrayList;
import android.content.Context;
import android.content.SharedPreferences;
import com.hippo.ehviewer.DownloadInfo;
import com.hippo.ehviewer.ListUrls;
import com.hippo.ehviewer.activity.DownloadInfo;
public class Download {
private static final String SHA_PRE_NAME = "download_info";
+9 -5
View File
@@ -19,10 +19,12 @@ import android.widget.ImageView;
public class Ui {
//private static final String TAG = "Ui";
private static Context mContext;
private static Resources mResources;
private static final BitmapFactory.Options opt = new BitmapFactory.Options();
public static final int HOLO_WHITE = 0xfff3f3f3;
//public static final int HOLO_WHITE = 0xfff3f3f3;
public static int HOLO_BLUE_DARK;
public static int BG_WHITE;
private static boolean mInit = false;
@@ -42,7 +44,10 @@ public class Ui {
opt.inPurgeable = true;
opt.inInputShareable = true;
mResources = mContext.getResources();
// init color
HOLO_BLUE_DARK = mResources.getColor(android.R.color.holo_blue_dark);
BG_WHITE = mResources.getColor(R.color.bg_white);
}
/**
@@ -215,11 +220,10 @@ public class Ui {
public static int getNavigationBarHeight(boolean force) {
if (!force && !hasNavigationBar())
return 0;
Resources resources = mContext.getResources();
int nbhResourceId = resources.getIdentifier(
int nbhResourceId = mResources.getIdentifier(
"navigation_bar_height", "dimen", "android");
if (nbhResourceId > 0)
return resources.getDimensionPixelSize(nbhResourceId);
return mResources.getDimensionPixelSize(nbhResourceId);
else
return 0;
}