From 38118dd1a4412f647ff12e9cf93a158096632f40 Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Sun, 25 May 2025 20:48:26 +0800 Subject: [PATCH] =?UTF-8?q?6.6.3=20-=20Alpha5=20-=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E4=BB=A3=E7=A0=81=E5=AD=90=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E8=87=AA=E5=8A=A8=E5=8A=A0=E8=BD=BD=E9=97=AE?= =?UTF-8?q?=E9=A2=98;=20=E6=94=AF=E6=8C=81=E5=B0=86=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=96=87=E4=BB=B6=E5=A4=B9=E9=87=8D=E7=BD=AE?= =?UTF-8?q?=E4=B8=BA=E5=88=9D=E5=A7=8B=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_zh-Hans.json | 4 +- .../model/explorer/WorkspaceFileProvider.java | 55 ++++++++++++------- .../main/java/org/autojs/autojs/pio/PFiles.kt | 14 ++++- .../org/autojs/autojs/runtime/api/Plugins.kt | 2 +- .../autojs/autojs/ui/explorer/ExplorerView.kt | 22 +++++++- app/src/main/res/menu/menu_dir_options.xml | 25 +++++---- app/src/main/res/menu/menu_script_options.xml | 40 +++++++------- 7 files changed, 104 insertions(+), 58 deletions(-) diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index 71519ea2..09759895 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -11,7 +11,7 @@ "images.compressToBytes 方法, 用于压缩图像并生成字节数组", "images.downsample 方法, 用于像素降采样并生成新的 ImageWrapper", "ui.keepScreenOn 方法, 用于 UI 页面获取焦点时保持设备屏幕常亮", - "ui.root 属性 (getter), 用于获取 UI 页面布局的 \"窗口内容根容器\" 节点", + "ui.root 属性 (getter), 用于获取 UI 页面布局的 \"窗口内容根容器\" 节点" ], "fix": [ "主页文档标签显示在线文档时部分内容被系统导航栏遮挡的问题", @@ -20,6 +20,7 @@ "无障碍服务关闭时音量加键停止所有脚本功能失效的问题", "定时任务页面编辑自定义广播内容时出现的输入法遮挡问题", "APK 文件类型信息对话框可能无法获取应用名称及 SDK 信息的问题", + "文件管理器示例代码进入项目目录时可能无法自动加载子目录文件内容的问题", "Android 15 部分页面状态栏背景颜色可能无法动态跟随主题色的问题", "dialogs 模块无法正常使用 customView 属性的问题 _[`issue #364`](http://issues.autojs6.com/364)_", "dialogs.input 方法的表达式参数可能无法获得执行结果的问题", @@ -49,6 +50,7 @@ "版本更新信息支持多语言显示 (与当前显示语言同步)", "使用异步加载方式一定程度提升文件管理器列表滑动流畅性", "脚本异常消息在控制台的显示内容与格式", + "示例代码支持将文件夹重置为初始内容", "APK 文件签名信息提升检测效率", "APK 文件类型信息及媒体文件类型信息优化对话框显示效率及信息展示逻辑", "Gradle 构建脚本提升版本自适应能力 _[`discussion #369`](http://discussions.autojs6.com/369)_" diff --git a/app/src/main/java/org/autojs/autojs/model/explorer/WorkspaceFileProvider.java b/app/src/main/java/org/autojs/autojs/model/explorer/WorkspaceFileProvider.java index e791e262..7ff6a27a 100644 --- a/app/src/main/java/org/autojs/autojs/model/explorer/WorkspaceFileProvider.java +++ b/app/src/main/java/org/autojs/autojs/model/explorer/WorkspaceFileProvider.java @@ -2,9 +2,10 @@ package org.autojs.autojs.model.explorer; import android.content.Context; import android.content.res.AssetManager; - import androidx.annotation.Nullable; - +import io.reactivex.Observable; +import io.reactivex.Single; +import io.reactivex.schedulers.Schedulers; import org.autojs.autojs.model.script.ScriptFile; import org.autojs.autojs.pio.PFile; import org.autojs.autojs.pio.PFiles; @@ -14,11 +15,7 @@ import org.autojs.autojs.util.WorkingDirectoryUtils; import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; -import java.io.InputStream; - -import io.reactivex.Observable; -import io.reactivex.Single; -import io.reactivex.schedulers.Schedulers; +import java.io.IOException; public class WorkspaceFileProvider extends ExplorerFileProvider { @@ -88,31 +85,47 @@ public class WorkspaceFileProvider extends ExplorerFileProvider { return Observable.just(pathOfAsset) .flatMap(path -> Observable.fromArray(mAssetManager.list(path))) .map(child -> { - PFile file = new PFile(new File(directory, child).getPath()); - if (file.exists()) { - return file; - } - try { - InputStream stream = mAssetManager.open(pathOfAsset + File.separator + child); - PFiles.copyStream(stream, file.getPath()); - } catch (FileNotFoundException e) { - file.mkdirs(); - } - return file; + PFile localFile = new PFile(new File(directory, child).getPath()); + copyAssetRecursively(pathOfAsset + File.separator + child, localFile); + return localFile; }); } + private void copyAssetRecursively(String assetPath, File dest) throws IOException { + String[] children = mAssetManager.list(assetPath); + if (children == null || children.length == 0) { + if (!dest.exists()) { + try { + PFiles.copyAssetFile(mAssetManager, assetPath, dest.getPath()); + } catch (FileNotFoundException ignored) { + /* Ignored. */ + } + } + return; + } + if (!dest.exists()) { + dest.mkdirs(); + } + for (String child : children) { + copyAssetRecursively(assetPath + File.separator + child, new File(dest, child)); + } + } + @Nullable public Observable resetSample(ScriptFile file) { - if (file.getPath().length() <= mSampleDir.getPath().length() + 1) { + if (!file.getPath().startsWith(mSampleDir.getPath())) { return null; } String pathOfSample = file.getPath().substring(mSampleDir.getPath().length()); String pathOfAsset = SAMPLE_PATH + pathOfSample; return Observable .fromCallable(() -> { - try (InputStream stream = mAssetManager.open(pathOfAsset)) { - PFiles.copyStream(stream, file.getPath()); + try { + if (file.isDirectory()) { + PFiles.copyAssetDir(mAssetManager, pathOfAsset, file.getPath()); + } else { + PFiles.copyAssetFile(mAssetManager, pathOfAsset, file.getPath()); + } } catch (FileNotFoundException ignored) { return new ScriptFile(System.currentTimeMillis() + "\ufeff" + Math.random()); } diff --git a/app/src/main/java/org/autojs/autojs/pio/PFiles.kt b/app/src/main/java/org/autojs/autojs/pio/PFiles.kt index 940b06cb..cf415dfd 100644 --- a/app/src/main/java/org/autojs/autojs/pio/PFiles.kt +++ b/app/src/main/java/org/autojs/autojs/pio/PFiles.kt @@ -281,23 +281,31 @@ object PFiles { } @JvmStatic + @JvmOverloads @Throws(IOException::class) - fun copyAssetDir(manager: AssetManager, assetsDir: String, toDir: String, list: Array?) { + fun copyAssetDir(manager: AssetManager, assetsDir: String, toDir: String, list: Array? = null) { File(toDir).mkdirs() val ls = list ?: manager.list(assetsDir) ?: throw IOException("Not a directory: $assetsDir") ls.forEach { file -> if (!TextUtils.isEmpty(file)) { val fullAssetsPath = join(assetsDir, file) val children = manager.list(fullAssetsPath) + val toPath = join(toDir, file) if (children.isNullOrEmpty()) { - manager.open(fullAssetsPath).use { stream -> copyStream(stream, join(toDir, file)) } + copyAssetFile(manager, fullAssetsPath, toPath) } else { - copyAssetDir(manager, fullAssetsPath, join(toDir, file), children) + copyAssetDir(manager, fullAssetsPath, toPath, children) } } } } + @JvmStatic + @Throws(IOException::class) + fun copyAssetFile(manager: AssetManager, assetFile: String, toPath: String) { + manager.open(assetFile).use { stream -> copyStream(stream, toPath) } + } + fun renameWithoutExtensionAndReturnNewPath(path: String, newName: String): String { val file = File(path) val newFile = File(file.parent, newName + "." + getExtension(file.name)) diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/Plugins.kt b/app/src/main/java/org/autojs/autojs/runtime/api/Plugins.kt index 64a96edd..c2fae5d3 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/Plugins.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/Plugins.kt @@ -43,7 +43,7 @@ class Plugins(private val context: Context, private val runtime: PluginRuntime) try { val plugin = Plugin.load(context, packageContext, runtime, runtime.topLevelScope) val scriptCacheDir = getScriptCacheDir(packageName) - copyAssetDir(packageContext.context.assets, plugin.assetsScriptDir, scriptCacheDir.path, null) + copyAssetDir(packageContext.context.assets, plugin.assetsScriptDir, scriptCacheDir.path) plugin.mainScriptPath = File(scriptCacheDir, "index.js").path bindService(plugin) mPlugins[packageName] = plugin diff --git a/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt b/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt index 12b153fc..ed079ef8 100644 --- a/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt +++ b/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerView.kt @@ -904,7 +904,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef menu.removeItem(R.id.action_set_as_working_dir) } val samplePath = PFile(context.filesDir, WorkspaceFileProvider.SAMPLE_PATH).path - if (!(mExplorerItem.path.startsWith(samplePath))) { + if (!mExplorerItem.path.startsWith(samplePath)) { menu.removeItem(R.id.reset) } popupMenu.setOnMenuItemClickListener(this@ExplorerView) @@ -961,6 +961,10 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef if (!mExplorerPage!!.canBuildApk()) { menu.removeItem(R.id.action_build_apk) } + val samplePath = PFile(context.filesDir, WorkspaceFileProvider.SAMPLE_PATH).path + if (!mExplorerPage!!.path.startsWith(samplePath)) { + menu.removeItem(R.id.reset) + } popupMenu.setOnMenuItemClickListener { item: MenuItem -> when (item.itemId) { R.id.action_rename -> { @@ -979,6 +983,22 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef R.id.action_build_apk -> { BuildActivity.launch(context, selectedItem!!.path) } + R.id.reset -> { + val o = Explorers.Providers.workspace() + .resetSample(selectedItem!!.toScriptFile()) + if (o == null) { + resetFailed() + } else { + o.observeOn(AndroidSchedulers.mainThread()) + .subscribe({ file: ScriptFile -> + if (file.exists()) { + resetSucceeded() + } else { + resetFailed() + } + }, Observers.toastMessage()) + } + } else -> null } != null } diff --git a/app/src/main/res/menu/menu_dir_options.xml b/app/src/main/res/menu/menu_dir_options.xml index 818f42b2..24ff0d7c 100644 --- a/app/src/main/res/menu/menu_dir_options.xml +++ b/app/src/main/res/menu/menu_dir_options.xml @@ -1,20 +1,21 @@ - + - + android:id="@+id/action_rename" + android:title="@string/text_rename" /> - + android:id="@+id/action_delete" + android:title="@string/text_delete" /> - + android:id="@+id/action_set_as_working_dir" + android:title="@string/text_set_as_working_dir" /> + android:id="@+id/action_build_apk" + android:title="@string/text_build_apk" /> + \ No newline at end of file diff --git a/app/src/main/res/menu/menu_script_options.xml b/app/src/main/res/menu/menu_script_options.xml index 0568c3c1..c6ae3164 100644 --- a/app/src/main/res/menu/menu_script_options.xml +++ b/app/src/main/res/menu/menu_script_options.xml @@ -1,31 +1,33 @@ - + + + android:id="@+id/rename" + android:title="@string/text_rename" /> + android:id="@+id/delete" + android:title="@string/text_delete" /> + android:id="@+id/timed_task" + android:title="@string/text_timed_task" /> + android:id="@+id/create_shortcut" + android:title="@string/text_send_shortcut" /> + android:id="@+id/action_build_apk" + android:title="@string/text_build_apk" /> + android:id="@+id/reset" + android:title="@string/text_reset_to_initial_content" /> + android:id="@+id/send" + android:title="@string/text_send" /> + android:id="@+id/open_by_other_apps" + android:title="@string/text_open_by_other_apps" /> + android:id="@+id/run_repeatedly" + android:title="@string/text_run_repeatedly" /> \ No newline at end of file