unknown
No files matched your search
|
Before Width: | Height: | Size: 188 B |
|
Before Width: | Height: | Size: 174 B |
|
Before Width: | Height: | Size: 173 B |
|
Before Width: | Height: | Size: 160 B |
|
Before Width: | Height: | Size: 195 B |
|
Before Width: | Height: | Size: 183 B |
|
After Width: | Height: | Size: 401 B |
|
Before Width: | Height: | Size: 213 B |
|
Before Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 247 B |
|
After Width: | Height: | Size: 134 B |
|
Before Width: | Height: | Size: 114 B |
|
Before Width: | Height: | Size: 166 B |
|
Before Width: | Height: | Size: 95 B |
|
Before Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 129 B |
|
Before Width: | Height: | Size: 177 B |
|
After Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 155 B |
|
Before Width: | Height: | Size: 200 B |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||