Add share and save image in GalleryActivity

This commit is contained in:
seven332 committed 2016-03-11 22:42:05 +08:00
1 parent 44c9c66952
commit 5dd781a3fb
13 files changed
+333 -49

No files matched your search

@@ -28,8 +28,9 @@ public class AppConfig {
private static final String APP_DIRNAME = "EhViewer";
private static final String SPIDER_INFO = "spider_info";
private static final String DOWNLOAD = "download";
private static final String TEMP = "temp";
private static final String IMAGE = "image";
private static Context sContext;
@@ -50,7 +51,7 @@ public class AppConfig {
* mkdirs and get
*/
@Nullable
public static File getDirInAppDir(String filename) {
public static File getDirInExternalAppDir(String filename) {
File appFolder = getExternalAppDir();
if (appFolder != null) {
File dir = new File(appFolder, filename);
@@ -60,7 +61,7 @@ public class AppConfig {
}
@Nullable
public static File getFileInAppDir(String filename) {
public static File getFileInExternalAppDir(String filename) {
File appFolder = getExternalAppDir();
if (appFolder != null) {
File file = new File(appFolder, filename);
@@ -71,6 +72,21 @@ public class AppConfig {
@Nullable
public static File getDefaultDownloadDir() {
return getDirInAppDir(DOWNLOAD);
return getDirInExternalAppDir(DOWNLOAD);
}
@Nullable
public static File getExternalTempDir() {
return getDirInExternalAppDir(TEMP);
}
@Nullable
public static File getExternalImageDir() {
return getDirInExternalAppDir(IMAGE);
}
@Nullable
public static File createExternalTempFile() {
return FileUtils.createTempFile(getExternalTempDir(), null);
}
}
@@ -433,7 +433,7 @@ public class Settings {
boolean writeXml = false;
boolean writeFile = false;
String userID = getString(KEY_USER_ID, null);
File file = AppConfig.getFileInAppDir(FILENAME_USER_ID);
File file = AppConfig.getFileInExternalAppDir(FILENAME_USER_ID);
if (null == userID || !isValidUserID(userID)) {
writeXml = true;
// Get use ID from out sd card file
@@ -17,6 +17,7 @@
package com.hippo.ehviewer.gallery;
import android.os.Process;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
@@ -24,32 +25,37 @@ import com.hippo.ehviewer.GetText;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.gallery.gl.GalleryPageView;
import com.hippo.image.Image;
import com.hippo.unifile.UniFile;
import com.hippo.yorozuya.FileUtils;
import com.hippo.yorozuya.IOUtils;
import com.hippo.yorozuya.PriorityThread;
import com.hippo.yorozuya.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
public class DirGalleryProvider extends GalleryProvider implements Runnable {
private static final String TAG = DirGalleryProvider.class.getSimpleName();
private static final AtomicInteger sIdGenerator = new AtomicInteger();
private final File mDir;
private final UniFile mDir;
private final Stack<Integer> mRequests = new Stack<>();
private final AtomicInteger mDecodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX);
private final AtomicReference<UniFile[]> mFileList = new AtomicReference<>();
@Nullable
private Thread mBgThread;
private volatile int mSize = STATE_WAIT;
private String mError;
public DirGalleryProvider(File dir) {
public DirGalleryProvider(@NonNull UniFile dir) {
mDir = dir;
}
@@ -100,10 +106,62 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
return mError;
}
@Override
public boolean save(int index, @NonNull UniFile file) {
UniFile[] fileList = mFileList.get();
if (null == fileList || index < 0 || index >= fileList.length) {
return false;
}
InputStream is = null;
OutputStream os = null;
try {
is = fileList[index].openInputStream();
os = file.openOutputStream();
IOUtils.copy(is, os);
return true;
} catch (IOException e) {
return false;
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
}
@Nullable
@Override
public UniFile save(int index, @NonNull UniFile dir, @NonNull String filename) {
UniFile[] fileList = mFileList.get();
if (null == fileList || index < 0 || index >= fileList.length) {
return null;
}
UniFile src = fileList[index];
String extension = FileUtils.getExtensionFromFilename(src.getName());
UniFile dst = dir.subFile(null != extension ? filename + "." + extension : filename);
if (null == dst) {
return null;
}
InputStream is = null;
OutputStream os = null;
try {
is = src.openInputStream();
os = dst.openOutputStream();
IOUtils.copy(is, os);
return dst;
} catch (IOException e) {
return null;
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
}
@Override
public void run() {
// It may take a long time, so run it in new thread
String[] files = mDir.list(new ImageFilter());
UniFile[] files = mDir.listFiles();
if (files == null) {
mSize = STATE_ERROR;
@@ -119,6 +177,9 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
// Sort it
Arrays.sort(files);
// Put file list
mFileList.lazySet(files);
// Set state normal and notify
mSize = files.length;
notifyDataChanged();
@@ -146,8 +207,9 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
continue;
}
InputStream is = null;
try {
InputStream is = new FileInputStream(new File(mDir, files[index]));
is = files[index].openInputStream();
Image image = Image.decode(is, true);
mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX);
if (image != null) {
@@ -155,13 +217,18 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
} else {
notifyPageFailed(index, GetText.getString(R.string.error_decoding_failed));
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX);
notifyPageFailed(index, GetText.getString(R.string.error_not_found));
notifyPageFailed(index, GetText.getString(R.string.error_reading_failed));
} finally {
IOUtils.closeQuietly(is);
}
mDecodingIndex.lazySet(GalleryPageView.INVALID_INDEX);
}
// Clear file list
mFileList.lazySet(null);
Log.i(TAG, "ImageDecoder end");
}
@@ -17,11 +17,13 @@
package com.hippo.ehviewer.gallery;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.hippo.ehviewer.client.data.GalleryInfo;
import com.hippo.ehviewer.spider.SpiderQueen;
import com.hippo.image.Image;
import com.hippo.unifile.UniFile;
import com.hippo.yorozuya.SimpleHandler;
public class EhGalleryProvider extends GalleryProvider implements SpiderQueen.OnSpiderListener {
@@ -71,6 +73,25 @@ public class EhGalleryProvider extends GalleryProvider implements SpiderQueen.On
}
}
@Override
public boolean save(int index, @NonNull UniFile file) {
if (null != mSpiderQueen) {
return mSpiderQueen.save(index, file);
} else {
return false;
}
}
@Nullable
@Override
public UniFile save(int index, @NonNull UniFile dir, @NonNull String filename) {
if (null != mSpiderQueen) {
return mSpiderQueen.save(index, dir, filename);
} else {
return null;
}
}
@Override
public void putStartPage(int page) {
if (mSpiderQueen != null) {
@@ -17,11 +17,14 @@
package com.hippo.ehviewer.gallery;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import com.hippo.gl.glrenderer.GLCanvas;
import com.hippo.gl.view.GLRoot;
import com.hippo.image.Image;
import com.hippo.unifile.UniFile;
import com.hippo.yorozuya.ConcurrentPool;
import com.hippo.yorozuya.OSUtils;
@@ -86,6 +89,14 @@ public abstract class GalleryProvider {
return 0;
}
public abstract boolean save(int index, @NonNull UniFile file);
/**
* @param filename without extension
*/
@Nullable
public abstract UniFile save(int index, @NonNull UniFile dir, @NonNull String filename);
public void putStartPage(int page) {}
public void setGalleryProviderListener(GalleryProviderListener listener) {
@@ -17,6 +17,7 @@
package com.hippo.ehviewer.gallery;
import android.os.Process;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
@@ -24,6 +25,7 @@ import com.hippo.ehviewer.GetText;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.gallery.gl.GalleryPageView;
import com.hippo.image.Image;
import com.hippo.unifile.UniFile;
import com.hippo.yorozuya.PriorityThread;
import com.hippo.yorozuya.StringUtils;
@@ -105,6 +107,19 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
return mError;
}
@Override
public boolean save(int index, @NonNull UniFile file) {
// TODO
return false;
}
@Nullable
@Override
public UniFile save(int index, @NonNull UniFile dir, @NonNull String filename) {
// TODO
return null;
}
@Override
public void run() {
ZipFile zipFile = null;
@@ -121,9 +136,6 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
// Check zip file null
if (zipFile == null) {
mSize = STATE_ERROR;
if (mError == null) {
mError = GetText.getString(R.string.error_unknown);
}
// Notify to to show error
notifyDataChanged();
@@ -17,6 +17,7 @@
package com.hippo.ehviewer.spider;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Process;
import android.support.annotation.IntDef;
@@ -551,6 +552,72 @@ public class SpiderQueen implements Runnable {
}
}
public boolean save(int index, @NonNull UniFile file) {
int state = getPageState(index);
if (STATE_FINISHED != state) {
return false;
}
InputStreamPipe pipe = mSpiderDen.openInputStreamPipe(index);
if (null == pipe) {
return false;
}
OutputStream os = null;
try {
os = file.openOutputStream();
pipe.obtain();
IOUtils.copy(pipe.open(), os);
return true;
} catch (IOException e) {
return false;
} finally {
pipe.close();
pipe.release();
IOUtils.closeQuietly(os);
}
}
@Nullable
public UniFile save(int index, @NonNull UniFile dir, @NonNull String filename) {
int state = getPageState(index);
if (STATE_FINISHED != state) {
return null;
}
InputStreamPipe pipe = mSpiderDen.openInputStreamPipe(index);
if (null == pipe) {
return null;
}
OutputStream os = null;
try {
pipe.obtain();
// Get dst file
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(pipe.open(), null, options);
pipe.close();
String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(options.outMimeType);
UniFile dst = dir.subFile(null != extension ? filename + "." + extension : filename);
if (null == dst) {
return null;
}
// Copy
os = dst.openOutputStream();
IOUtils.copy(pipe.open(), os);
return dst;
} catch (IOException e) {
return null;
} finally {
pipe.close();
pipe.release();
IOUtils.closeQuietly(os);
}
}
public int getStartPage() {
mSpiderInfo = readSpiderInfoFromLocal();
if (mSpiderInfo != null) {
@@ -21,17 +21,22 @@ import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SwitchCompat;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.MimeTypeMap;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.hippo.ehviewer.AppConfig;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.Settings;
import com.hippo.ehviewer.client.data.GalleryInfo;
@@ -46,6 +51,7 @@ import com.hippo.ehviewer.gallery.gl.ImageView;
import com.hippo.gl.glrenderer.ImageTexture;
import com.hippo.gl.view.GLRootView;
import com.hippo.image.Image;
import com.hippo.unifile.UniFile;
import com.hippo.util.SystemUiHelper;
import com.hippo.widget.Slider;
import com.hippo.yorozuya.AnimationUtils;
@@ -142,7 +148,7 @@ public class GalleryActivity extends TrackedActivity
if (ACTION_DIR.equals(mAction)) {
if (mFilename != null) {
mGalleryProvider = new DirGalleryProvider(new File(mFilename));
mGalleryProvider = new DirGalleryProvider(UniFile.fromFile(new File(mFilename)));
}
} else if (ACTION_ZIP.equals(mAction)) {
if (mFilename != null) {
@@ -658,6 +664,83 @@ public class GalleryActivity extends TrackedActivity
}
}
private void shareImage(int page) {
if (null == mGalleryProvider) {
return;
}
File dir = AppConfig.getExternalTempDir();
if (null == dir) {
Toast.makeText(this, R.string.error_cant_create_temp_file, Toast.LENGTH_SHORT).show();
return;
}
UniFile file;
if (null == (file = mGalleryProvider.save(page, UniFile.fromFile(dir), Long.toString(System.currentTimeMillis())))) {
Toast.makeText(this, R.string.error_cant_save_image, Toast.LENGTH_SHORT).show();
return;
}
// TODO Create ContentProvider for some app are not grand storage write permission
Uri uri = file.getUri();
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
MimeTypeMap.getFileExtensionFromUrl(uri.toString()));
if (TextUtils.isEmpty(mimeType)) {
mimeType = "image/jpeg";
}
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType(mimeType);
startActivity(Intent.createChooser(intent, getString(R.string.share_image)));
}
private void saveImage(int page) {
if (null == mGalleryProvider) {
return;
}
File dir = AppConfig.getExternalImageDir();
if (null == dir) {
Toast.makeText(this, R.string.error_cant_save_image, Toast.LENGTH_SHORT).show();
return;
}
UniFile file;
if (null == (file = mGalleryProvider.save(page, UniFile.fromFile(dir), Long.toString(System.currentTimeMillis())))) {
Toast.makeText(this, R.string.error_cant_save_image, Toast.LENGTH_SHORT).show();
return;
}
Toast.makeText(this, getString(R.string.image_saved, file.getUri()), Toast.LENGTH_SHORT).show();
}
private void showPageDialog(final int page) {
Resources resources = GalleryActivity.this.getResources();
new AlertDialog.Builder(GalleryActivity.this)
.setTitle(resources.getString(R.string.page_menu_title, page + 1))
.setItems(R.array.page_menu_entries, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mGalleryProvider == null) {
return;
}
switch (which) {
case 0: // Refresh
mGalleryProvider.forceRequest(page);
break;
case 1: // Share
shareImage(page);
break;
case 2: // Save
saveImage(page);
break;
case 3: // Add a bookmark
break;
}
}
}).show();
}
private class NotifyTask implements Runnable {
public static final int KEY_LAYOUT_MODE = 0;
@@ -699,31 +782,7 @@ public class GalleryActivity extends TrackedActivity
}
private void onLongPressPage(final int index) {
Resources resources = GalleryActivity.this.getResources();
new AlertDialog.Builder(GalleryActivity.this)
.setTitle(resources.getString(R.string.page_menu_title, index + 1))
.setItems(R.array.page_menu_entries, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (mGalleryProvider == null) {
return;
}
switch (which) {
case 0: // Refresh
mGalleryProvider.forceRequest(index);
break;
case 1: // Share
// TODO
break;
case 2: // Save
// TODO
break;
case 3: // Add a bookmark
break;
}
}
}).show();
showPageDialog(index);
}
@Override