Add share and save image in GalleryActivity
This commit is contained in:
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
|
||||
|
||||
Reference in new issue
Block a user