From ce8da252c38296f887ece936e74391995ab142fa Mon Sep 17 00:00:00 2001 From: tarsin Date: Tue, 14 Jun 2022 09:48:48 +0800 Subject: [PATCH] Initial archive export stub --- .../ehviewer/ui/scene/GalleryDetailScene.java | 42 +++++++++++++++++++ .../main/res/menu/scene_gallery_detail.xml | 4 ++ app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../java/com/hippo/UriArchiveAccessor.java | 14 +++++++ native/src/main/jni/archive.c | 6 +++ 6 files changed, 68 insertions(+) diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java index 590927a7d..6a73584d8 100755 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -64,11 +64,14 @@ import androidx.core.view.ViewCompat; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.progressindicator.CircularProgressIndicator; import com.google.android.material.snackbar.Snackbar; +import com.hippo.UriArchiveAccessor; import com.hippo.app.EditTextDialogBuilder; import com.hippo.beerbelly.BeerBelly; import com.hippo.ehviewer.AppConfig; +import com.hippo.ehviewer.BuildConfig; import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.EhDB; +import com.hippo.ehviewer.GetText; import com.hippo.ehviewer.R; import com.hippo.ehviewer.Settings; import com.hippo.ehviewer.UrlOpener; @@ -105,6 +108,7 @@ import com.hippo.text.URLImageGetter; import com.hippo.util.AppHelper; import com.hippo.util.ClipboardUtil; import com.hippo.util.ExceptionUtils; +import com.hippo.util.IoThreadPoolExecutor; import com.hippo.util.ReadableTime; import com.hippo.view.ViewTransition; import com.hippo.widget.AutoWrapLayout; @@ -537,6 +541,44 @@ public class GalleryDetailScene extends ToolbarScene implements View.OnClickList voteTag(builder.getText().trim(), 1); dialog.dismiss(); }); + } else if (itemId == R.id.action_export) { + ActivityResultLauncher exportLauncher = registerForActivityResult( + new ActivityResultContracts.CreateDocument(), + uri -> { + if (uri != null) { + try { + // grantUriPermission might throw RemoteException on MIUI + requireActivity().grantUriPermission(BuildConfig.APPLICATION_ID, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + } catch (Exception e) { + ExceptionUtils.throwIfFatal(e); + e.printStackTrace(); + } + try { + AlertDialog alertDialog = new MaterialAlertDialogBuilder(requireActivity()) + .setCancelable(false) + .setView(R.layout.preference_dialog_task) + .show(); + IoThreadPoolExecutor.getInstance().execute(() -> { + boolean success = false; + Activity activity = getActivity(); + if (activity != null) { + activity.runOnUiThread(() -> { + if (alertDialog.isShowing()) { + alertDialog.dismiss(); + } + showTip( + (success) + ? GetText.getString(R.string.settings_advanced_export_data_to, uri.toString()) + : GetText.getString(R.string.settings_advanced_export_data_failed), + BaseScene.LENGTH_SHORT); + }); + } + }); + } catch (Exception e) { + showTip(R.string.settings_advanced_export_data_failed, BaseScene.LENGTH_SHORT); + } + } + }); } return true; } diff --git a/app/src/main/res/menu/scene_gallery_detail.xml b/app/src/main/res/menu/scene_gallery_detail.xml index 090b8230f..1da803ab9 100644 --- a/app/src/main/res/menu/scene_gallery_detail.xml +++ b/app/src/main/res/menu/scene_gallery_detail.xml @@ -28,4 +28,8 @@ android:id="@+id/action_open_in_other_app" android:title="@string/open_in_other_app" /> + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 444abd2a8..638d1cf72 100755 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -762,4 +762,5 @@ 依赖库之版本 需要解锁 + 导出 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 92667d121..608257217 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -826,4 +826,5 @@ Library Version Require Unlock + Export diff --git a/native/src/main/java/com/hippo/UriArchiveAccessor.java b/native/src/main/java/com/hippo/UriArchiveAccessor.java index 491bbfbef..6e59a4758 100644 --- a/native/src/main/java/com/hippo/UriArchiveAccessor.java +++ b/native/src/main/java/com/hippo/UriArchiveAccessor.java @@ -102,4 +102,18 @@ public class UriArchiveAccessor implements Closeable { } } } + + private static native boolean compressDirToOutStream(String dirname, int format, OutputStream os); + + public static synchronized boolean exportGalleryArchive(String dirName, int format, Uri target, Context context) { + try { + OutputStream os = context.getContentResolver().openOutputStream(target); + compressDirToOutStream(dirName, format, os); + os.close(); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } } diff --git a/native/src/main/jni/archive.c b/native/src/main/jni/archive.c index d06d33eae..f55f4c578 100644 --- a/native/src/main/jni/archive.c +++ b/native/src/main/jni/archive.c @@ -164,4 +164,10 @@ Java_com_hippo_UriArchiveAccessor_extracttoOutputStream(JNIEnv *env, jobject thi archive_read_close(arc->archive); archive_destroy_inst(arc); return 0; +} + +JNIEXPORT jboolean JNICALL +Java_com_hippo_UriArchiveAccessor_compressDirToOutStream(JNIEnv *env, jclass clazz, jstring dirname, + jint format, jobject os) { + return JNI_FALSE; } \ No newline at end of file