From 5dd781a3fb17075e53fb8ab30acfde266ea1fcf0 Mon Sep 17 00:00:00 2001 From: seven332 Date: Fri, 11 Mar 2016 22:42:05 +0800 Subject: [PATCH] Add share and save image in GalleryActivity --- .../java/com/hippo/ehviewer/AppConfig.java | 24 +++- .../java/com/hippo/ehviewer/Settings.java | 2 +- .../ehviewer/gallery/DirGalleryProvider.java | 83 +++++++++++-- .../ehviewer/gallery/EhGalleryProvider.java | 21 ++++ .../ehviewer/gallery/GalleryProvider.java | 11 ++ .../ehviewer/gallery/ZipGalleryProvider.java | 18 ++- .../hippo/ehviewer/spider/SpiderQueen.java | 67 +++++++++++ .../hippo/ehviewer/ui/GalleryActivity.java | 111 ++++++++++++++---- app/src/main/res/values-zh-rCN/strings.xml | 9 ++ app/src/main/res/values-zh-rHK/strings.xml | 15 ++- app/src/main/res/values-zh-rTW/strings.xml | 15 ++- app/src/main/res/values/strings.xml | 4 + yorozuya | 2 +- 13 files changed, 333 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/com/hippo/ehviewer/AppConfig.java b/app/src/main/java/com/hippo/ehviewer/AppConfig.java index a9635a248..970a8af1e 100644 --- a/app/src/main/java/com/hippo/ehviewer/AppConfig.java +++ b/app/src/main/java/com/hippo/ehviewer/AppConfig.java @@ -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); } } diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.java b/app/src/main/java/com/hippo/ehviewer/Settings.java index c8fa136bd..99eb266b7 100644 --- a/app/src/main/java/com/hippo/ehviewer/Settings.java +++ b/app/src/main/java/com/hippo/ehviewer/Settings.java @@ -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 diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java index 626afff13..8ae1cb9d9 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/DirGalleryProvider.java @@ -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 mRequests = new Stack<>(); private final AtomicInteger mDecodingIndex = new AtomicInteger(GalleryPageView.INVALID_INDEX); + private final AtomicReference 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"); } diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java index a9d9606d9..d517f6752 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/EhGalleryProvider.java @@ -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) { diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java index 093b4e7fb..debaf0148 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/GalleryProvider.java @@ -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) { diff --git a/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java b/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java index 918651ca1..1e257da39 100644 --- a/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java +++ b/app/src/main/java/com/hippo/ehviewer/gallery/ZipGalleryProvider.java @@ -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(); diff --git a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java index 60cc3d709..54f7b313c 100644 --- a/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java +++ b/app/src/main/java/com/hippo/ehviewer/spider/SpiderQueen.java @@ -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) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java index c563ae55d..ece93a8d4 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java @@ -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 diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index a96e10d86..41aa06729 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -68,6 +68,8 @@ 无效链接 获取 pToken 错误 指定画廊的关键字应该看起来像 \"618395 0439fa3666\" + 无法创建临时文件 + 无法保存图片 本应用中内容来自互联网,部分内容可能对您的生理及心理造成难以恢复的伤害。本应用作者不会对由本应用造成的后果负责。您是否愿意继续使用该应用? 用户名不可为空 @@ -255,6 +257,9 @@ 删除标签 删除“%s”? + + 这里是阅读历史 + 第 %d 页 @string/refresh @@ -262,6 +267,8 @@ 保存 添加书签 菜单 + 分享图片 + 图片已保存至 %s EH @@ -311,6 +318,8 @@ 启用数据统计 关于数据统计 + 开源许可 + 选择文件夹 该文件夹不可写 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index bbe015cc6..957617337 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -68,6 +68,8 @@ 無效鏈接 獲取 pToken 錯誤 指定畫廊的關鍵字應該看起來像 \"618395 0439fa3666\" + 無法創建臨時文件 + 無法保存圖片 本應用中內容來自互聯網,部分內容可能對您的生理及心理造成難以恢復的傷害。本應用作者不會對由本應用造成的後果負責。您是否願意繼續使用該應用? 用户名不可為空 @@ -115,7 +117,7 @@ 刪除 刪除快速搜索 刪除“%s”? - 未添加快速搜索 + 這裏是快速搜索 2 星 @@ -235,7 +237,7 @@ 標籤 默認 移動 - 標籤 + 下載標籤 全部開始 全部停止 EhViewer 下載服務 @@ -245,7 +247,7 @@ 默認下載標籤 - 無標籤 + 這裏是下載標籤 添加 新標籤 標籤文本為空 @@ -255,6 +257,9 @@ 刪除標籤 刪除“%s”? + + 這裏是閲讀歷史 + 第 %d 頁 @string/refresh @@ -262,6 +267,8 @@ 保存 添加書籤 菜單 + 分享圖片 + 圖片已保存至 %s EH @@ -311,6 +318,8 @@ 啟用數據統計 關於數據統計 + 開源許可 + 選擇文件夾 該文件夾不可寫 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5a4220477..beec1c733 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -68,6 +68,8 @@ 無效連結 獲取 pToken 錯誤 指定畫廊的關鍵字應該看起來像 \"618395 0439fa3666\" + 無法建立臨時檔案 + 無法儲存圖片 本應用中內容來自網際網路,部分內容可能對您的生理及心理造成難以恢復的傷害。本應用作者不會對由本應用造成的後果負責。您是否願意繼續使用該應用? 使用者名稱不可為空 @@ -115,7 +117,7 @@ 刪除 刪除快速搜尋 刪除“%s”? - 未新增快速搜尋 + 這裡是快速搜尋 2 星 @@ -235,7 +237,7 @@ 標籤 預設 移動 - 標籤 + 下載標籤 全部開始 全部停止 EhViewer 下載服務 @@ -245,7 +247,7 @@ 預設下載標籤 - 無標籤 + 這裡是下載標籤 新增 新標籤 標籤文字為空 @@ -255,6 +257,9 @@ 刪除標籤 刪除“%s”? + + 這裡是閱讀歷史 + 第 %d 頁 @string/refresh @@ -262,6 +267,8 @@ 儲存 新增書籤 選單 + 分享圖片 + 圖片已儲存至 %s EH @@ -311,6 +318,8 @@ 啟用資料統計 關於資料統計 + 開源許可 + 選擇資料夾 該資料夾不可寫 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0a9adef8e..618ad2062 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -107,6 +107,8 @@ Invalid url Get pToken error Keyword should looks like \"618395 0439fa3666\" for specify gallery + Can\'t create temp file + Can\'t save image The content of this application is from the Internet. Some of it may do physical or mental harm to you. You have learnt the risks above and would like to undertake them. Do you want to use this application? Username cannot be an empty string @@ -305,6 +307,8 @@ Save Add a bookmark Menu + Share image + Image saved to %s EH Show Japanese title diff --git a/yorozuya b/yorozuya index e1d491a60..b29dbe5c2 160000 --- a/yorozuya +++ b/yorozuya @@ -1 +1 @@ -Subproject commit e1d491a60e36e6915b690414beee7b84b8b3aa8f +Subproject commit b29dbe5c27d552562586bb2474d602d57119f0a5