From ff0ca695a954d5ff4552d34234bb875908798644 Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Mon, 2 Feb 2026 21:32:58 +0800 Subject: [PATCH] =?UTF-8?q?6.7.0=20-=20Alpha19=20-=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=99=A8=E5=A2=9E=E5=8A=A0=20"=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E5=88=B0"=20=E5=8F=8A=20"=E5=A4=8D=E5=88=B6=E5=88=B0"?= =?UTF-8?q?=20=E8=8F=9C=E5=8D=95=E9=A1=B9,=20=E6=94=AF=E6=8C=81=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E4=B8=AD=E6=AD=A2=E5=8F=8A=E8=BF=9B=E5=BA=A6=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_ja.json | 42 +- .changelog/lang_zh-Hans.json | 3 +- .readme/lang_ja.json | 2 +- .../java/org/autojs/autojs/app/DialogUtils.kt | 208 +++- .../autojs/app/tool/JsonSocketClientTool.kt | 31 +- .../core/plugin/center/PluginInstaller.kt | 27 +- .../model/explorer/ExplorerFileItem.java | 7 +- .../autojs/model/explorer/ExplorerItem.java | 8 +- .../model/explorer/ExplorerSampleItem.java | 9 +- .../model/explorer/WorkspaceFileProvider.java | 4 +- .../network/download/DownloadManager.java | 80 +- .../autojs/network/download/ProgressInfo.java | 17 +- .../main/java/org/autojs/autojs/pio/PFiles.kt | 47 +- .../autojs/autojs/runtime/ScriptRuntime.kt | 4 +- .../org/autojs/autojs/runtime/api/Files.kt | 4 + .../api/augment/colors/ColorNativeObject.kt | 4 +- .../runtime/api/augment/colors/Colors.kt | 35 +- .../autojs/autojs/ui/common/RxDialogs.java | 24 +- .../autojs/ui/common/ScriptOperations.java | 920 +++++++++++++++++- .../autojs/autojs/ui/explorer/ExplorerView.kt | 114 ++- .../filechooser/ExplorerItemViewHolder.java | 6 +- .../filechooser/FileChooserDialogBuilder.java | 3 +- .../autojs/ui/floating/CircularMenu.java | 2 +- .../autojs/ui/main/FloatingActionMenu.java | 2 +- .../ui/main/scripts/ApkInfoDialogManager.kt | 2 +- .../scripts/EditableFileInfoDialogManager.kt | 4 +- .../java/org/autojs/autojs/util/FileUtils.kt | 9 +- .../org/autojs/autojs/util/ThreadUtils.java | 25 +- .../java/org/autojs/autojs/util/ViewUtils.kt | 39 +- app/src/main/res/layout/explorer_category.xml | 6 +- .../main/res/layout/explorer_directory.xml | 113 +-- app/src/main/res/menu/menu_dir_options.xml | 8 +- app/src/main/res/menu/menu_script_options.xml | 22 +- app/src/main/res/values-ar/strings.xml | 107 +- app/src/main/res/values-en/strings.xml | 111 ++- app/src/main/res/values-es/strings.xml | 93 +- app/src/main/res/values-fr/strings.xml | 95 +- app/src/main/res/values-ja/strings.xml | 119 ++- app/src/main/res/values-ko/strings.xml | 95 +- app/src/main/res/values-night/colors.xml | 2 + app/src/main/res/values-ru/strings.xml | 95 +- app/src/main/res/values-zh-rHK/strings.xml | 111 ++- app/src/main/res/values-zh-rTW/strings.xml | 111 ++- app/src/main/res/values-zh/strings.xml | 99 +- app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 110 ++- version.properties | 6 +- 47 files changed, 2153 insertions(+), 833 deletions(-) diff --git a/.changelog/lang_ja.json b/.changelog/lang_ja.json index 91d5658e..290404dc 100644 --- a/.changelog/lang_ja.json +++ b/.changelog/lang_ja.json @@ -33,7 +33,7 @@ "images.compressToBytes メソッドで画像を圧縮してバイト配列を取得", "images.downsample メソッドで解像度を下げて新しい ImageWrapper を生成", "ui.keepScreenOn メソッドで UI ページがフォーカス中は画面を点灯したまま維持", - "ui.root プロパティ (getter) で UI レイアウト内の「ウィンドウコンテンツのルートコンテナ」ノードを取得", + "ui.root プロパティ (getter) で UI レイアウト内の [ウィンドウコンテンツのルートコンテナ] ノードを取得", "webview 要素が JsBridge ベースのウェブページレイアウトをサポート (参照 [Auto.js Pro](https://g.pro.autojs.org/)) [例: Layout > Interactive HTML / Vue2 + Vant (SFC)] _[`issue #281`](http://issues.autojs6.com/281)_", "レイアウトインスペクターが要素の非表示をサポート (寄稿 [TonyJiangWJ](https://github.com/TonyJiangWJ)) _[`pr #371`](http://pr.autojs6.com/371)_ _[`issue #355`](http://issues.autojs6.com/355)_" ], @@ -67,7 +67,7 @@ "テーマカラーの適用範囲を拡大, より多くのウィジェットをサポート", "メインページのドロワー幅がランドスケープおよび超ワイド画面に適応", "『アプリについて』と『開発者について』ページに横向きとコンパクトレイアウトを追加", - "設定ダイアログに「デフォルト値を使用」メニューを追加", + "設定ダイアログに [デフォルト値を使用] メニューを追加", "ファイルマネージャーの FAB が外部タップ時に自動で隠れるように", "コードフォーマッターが `??`, `?.`, `??=` 演算子をサポート", "コードエディタが GB18030 / UTF-16 (LE/BE) / Shift_JIS などのエンコーディングでのファイル読み書きに対応", @@ -174,7 +174,7 @@ ], "fix": [ "一部の環境でバージョンを低く戻すことでプロジェクトが正常にコンパイルできなくなる問題", - "存在しないメソッドを呼び出す際に発生する可能性がある「非プリミティブ型の値」エラー", + "存在しないメソッドを呼び出す際に発生する可能性がある [非プリミティブ型の値] エラー", "一部のデバイスでスクリプトショートカットが正常に追加できない問題 (暫定修正) _[`issue #221`](http://issues.autojs6.com/221)_", "automator.click/longClick メソッドのパラメーター型制限の誤り _[`issue #275`](http://issues.autojs6.com/275)_", "セレクターが ConsString 型のパラメーターをサポートしない問題 _[`issue #277`](http://issues.autojs6.com/277)_", @@ -264,9 +264,9 @@ "アプリパッケージが opencc モジュールを正常に使用できない問題" ], "improvement": [ - "パッケージページ内の「利用不可 ABI」コントロールのクリックヒントユーザー体験", - "Shizuku を使用して「ポインタ位置」表示スイッチをコントロールするサポート", - "Shizuku を使用して「メディアの投影」および「セキュリティ設定の変更」許可スイッチをコントロールするサポート", + "パッケージページ内の [利用不可 ABI] コントロールのクリックヒントユーザー体験", + "Shizuku を使用して [ポインタ位置] 表示スイッチをコントロールするサポート", + "Shizuku を使用して [メディアの投影] および [セキュリティ設定の変更] 許可スイッチをコントロールするサポート", "automator.gestureAsync/gesturesAsync がコールバック関数パラメータをサポート", "tasks モジュールが同期方式でデータベース操作を実行するサポート, データアクセスの不一致問題を回避", "スクリプト実行モードがパイプ記号区切りモードパラメータ (例 `\"ui|auto\";` のように開始) をサポート", @@ -342,9 +342,9 @@ "importClass でインポートしたクラス名とグローバル変数が衝突するとコードが例外をスローする問題 _[`issue #185`](http://issues.autojs6.com/185)_", "Android 7.x でアクセシビリティサービスが使用できない問題", "Android 14 で runtime.loadJar/loadDex メソッドが正常に使用できない可能性がある問題 (試修)", - "Android システムのクイック設定パネルに「レイアウト範囲分析」と「レイアウト階層分析」が表示されない問題 _[`issue #193`](http://issues.autojs6.com/193)_", + "Android システムのクイック設定パネルに [レイアウト範囲分析] と [レイアウト階層分析] が表示されない問題 _[`issue #193`](http://issues.autojs6.com/193)_", "自動更新チェック機能がアプリの [ANR](https://developer.android.com/topic/performance/vitals/anr) を引き起こす可能性がある問題 (試修) _[`issue #186`](http://issues.autojs6.com/186)_", - "ファイルマネージャーでサンプルコードフォルダーをクリックして「上へ」ボタンを押すとワーキングパスページに戻れない問題 _[`issue #129`](http://issues.autojs6.com/129)_", + "ファイルマネージャーでサンプルコードフォルダーをクリックして [上へ] ボタンを押すとワーキングパスページに戻れない問題 _[`issue #129`](http://issues.autojs6.com/129)_", "コードエディターで置換機能を使用時に置換ボタンが表示されない問題", "コードエディターで長押し削除するとアプリがクラッシュする可能性のある問題 (試修)", "コードエディターで fx ボタンをクリックしてモジュール関数クイックパネルが表示されない問題", @@ -378,7 +378,7 @@ "ocr モジュールの一部の方法でエリアパラメータを認識できなかった問題 _[`issue #162`](http://issues.autojs6.com/162)_ _[`issue #175`](http://issues.autojs6.com/175)_", "Android 7.x で新バージョンを検出する際にバージョン情報を取得できなかった問題", "Android 14 でスクリーンショット権限を要求するとアプリがクラッシュする問題", - "ホームドロワーで「浮動ボタン」を切り替えるとアプリがクラッシュすることがある問題", + "ホームドロワーで [浮動ボタン] を切り替えるとアプリがクラッシュすることがある問題", "メニューを使用して浮動ボタンを閉じた後にアプリを再起動すると浮動ボタンが表示されたままになることがある問題", "Android 13 以降のシステム設定ページで AutoJs6 の言語を選択および切り替えると反映されない問題", "ビルドツールが最初のビルド時に OpenCV リソースの自動デプロイを完了できない問題" @@ -459,7 +459,7 @@ "無障害サービスの自動開始成功率を向上", "Kotlin アノテーション処理を kapt から KSP に移行", "ビルドツールが IntelliJ Idea EAP バージョンをサポート", - "ビルドツールが Java リリースバージョンに適応して「無効なリリースバージョン」問題を回避するように", + "ビルドツールが Java リリースバージョンに適応して [無効なリリースバージョン] 問題を回避するように", "ビルドツールの IDE および関連プラグインのバージョンダウングレードロジックを最適化し, バージョン予測能力を追加", "VSCode プラグイン 1.0.7 に適応" ], @@ -493,7 +493,7 @@ "fix": [ "VSCode プラグインがスクリプトの文字総数が 4 桁を超えるとデータを解析できない問題 _[`issue #91`](http://issues.autojs6.com/91)_ _[`issue #93`](http://issues.autojs6.com/93)_ _[`issue #100`](http://issues.autojs6.com/100)_ _[`issue #109`](http://issues.autojs6.com/109)_", "VSCode プラグインがファイルを正常に保存できない問題 _[`issue #92`](http://issues.autojs6.com/91)_ _[`issue #94`](http://issues.autojs6.com/93)_", - "無障害サービスの「管理」メニュー項目のクリックでページが遷移しないことがある問題", + "無障害サービスの [管理] メニュー項目のクリックでページが遷移しないことがある問題", "runtime.requestPermissions メソッドが消失した問題 _[`issue #104`](http://issues.autojs6.com/104)_", "events.emitter が MainThreadProxy パラメータに対応しない問題 _[`issue #103`](http://issues.autojs6.com/103)_", " _[`pr #78`](http://pr.autojs6.com/78)_ で存在していたコードエディタがコードを整形できない問題", @@ -626,7 +626,7 @@ "console.setSize などのメソッドが機能しない可能性のある問題 _[`issue #50`](http://issues.autojs6.com/50)_", "colors.material カラースペースの色定数の誤った割り当て", "UI モードの日付選択ウィジェットの minDate および maxDate 属性が日付フォーマットを正しく解析できない問題", - "スクリプトを実行した後, ホームの「タスク」タブページに素早く切り替えると, 同じ実行中のタスクが 2 つ表示される問題", + "スクリプトを実行した後, ホームの [タスク] タブページに素早く切り替えると, 同じ実行中のタスクが 2 つ表示される問題", "ファイルマネージャのページが他のページから戻るとページの状態がリセットされる可能性のある問題 _[`issue #52`](http://issues.autojs6.com/52)_", "ファイルマネージャのページソート状態とアイコン表示状態が一致しない問題" ], @@ -697,7 +697,7 @@ "高バージョンの Android システムでクイック設定パネルのアイコンをクリックした後, パネルが自動的に閉じない場合がある問題 (試修) _[`issue #7`](http://issues.autojs6.com/7)_", "高バージョンの Android システムで一部のページが通知バー領域と重なる問題", "Android 10 以降のシステムでブラシの色を設定するサンプルコードが正常に動作しない問題", - "サンプルコード「音楽管理者」のファイル名を「ファイル管理者」に訂正し, 正常機能を回復", + "サンプルコード [音楽管理者] のファイル名を [ファイル管理者] に訂正し, 正常機能を回復", "ファイルマネージャーで下にスワイプして更新する際に位置ずれが発生する可能性のある問題", "ui モジュールのスコープバインディングエラーにより, 一部の UI ベーススクリプトがコンポーネントの属性にアクセスできない問題", "録画スクリプト後のファイル名入力ダイアログが外部領域をクリックすると録画内容が失われる問題", @@ -733,7 +733,7 @@ "更新チェック/更新ダウンロード/更新通知機能が Android 7.x システムに対応", "設定ページを再設計 (AndroidX に移行)", "設定ページで設定項目を長押しして詳細情報を取得することが可能", - "夜間モードに「システムに従う」設定オプションを追加 (Android 9 および以上)", + "夜間モードに [システムに従う] 設定オプションを追加 (Android 9 および以上)", "アプリ起動画面が夜間モードに適応", "アプリアイコンに番号付けを追加して複数のオープンソースバージョンを共存するユーザーの使用体験を向上", "テーマカラーにより多くの Material Design Color (マテリアルデザインカラー) オプションを追加", @@ -806,8 +806,8 @@ "fix": [ "Android 10 システムでの外部ストレージの読み書きができない問題 _[`issue #17`](http://issues.autojs6.com/17)_", "エディタページで長押しするとアプリがクラッシュする可能性のある問題 _[`issue #18`](http://issues.autojs6.com/18)_", - "エディタページの長押しメニュー「行を削除」と「行をコピー」の機能が無効になっている問題", - "エディタページのオプションメニューで「貼り付け」機能が欠如している問題" + "エディタページの長押しメニュー [行を削除] と [行をコピー] の機能が無効になっている問題", + "エディタページのオプションメニューで [貼り付け] 機能が欠如している問題" ], "improvement": [ "一部の例外メッセージ文字列をリソース化 (en / zh)", @@ -825,7 +825,7 @@ "アプリのパッケージ名を org.autojs.autojs6 に変更し, オープンソースの Auto.js アプリパッケージ名との競合を回避" ], "feature": [ - "ホーム画面のドロワーに「投影メディア権限」スイッチを追加 (Root / ADB 方法) (スイッチの状態検出は実験的)", + "ホーム画面のドロワーに [投影メディア権限] スイッチを追加 (Root / ADB 方法) (スイッチの状態検出は実験的)", "ファイルブラウザが隠しファイルとフォルダを表示サポート (設定ページを参照)", "強制 Root チェック機能 (設定ページ及びサンプルコードを参照)", "autojs モジュール (サンプルコード > AutoJs6 を参照)", @@ -854,7 +854,7 @@ ], "improvement": [ "RootAutomator は Root 権限がない場合にインスタンス化できません", - "「アプリおよび開発者について」ページを再設計", + "[アプリおよび開発者について] ページを再設計", "すべての組み込み JavaScript モジュールを再構築", "すべての Gradle ビルドスクリプトを再構築し, 共通設定スクリプト (config.gradle) を追加", "Gradle ビルドツールがバージョン管理とビルドファイルの自動命名をサポート", @@ -893,7 +893,7 @@ "feature": [ "多言語切り替え機能 (未完成)", "recorder モジュール (サンプルコード > 計時器を参照)", - "「安全設定の変更権限」を使用してアクセシビリティサービスと設定のスイッチを自動的に有効化" + "[安全設定の変更権限] を使用してアクセシビリティサービスと設定のスイッチを自動的に有効化" ], "fix": [ "クイック設定パネルの関連アイコンをクリックした後, パネルが自動的に閉じない問題 (仮修理) _[`issue #7`](http://issues.autojs6.com/7)_", @@ -987,7 +987,7 @@ "スケジュールタスクパネルの一回限りのタスクの月表示エラー", "アプリの設定ページのスイッチカラーがテーマ変更に応じて変わらない問題", "パッケージプラグインが認識されないおよびダウンロードアドレスが無効な問題", - "ホーム画面ドロワー 「使用状況アクセス権限を見る」スイッチの状態が同期されない問題", + "ホーム画面ドロワー [使用状況アクセス権限を見る] スイッチの状態が同期されない問題", "TemplateMatching.fastTemplateMatching 潜在的な Mat メモリリーク問題" ], "improvement": [ @@ -997,7 +997,7 @@ "ホーム画面ドロワーからユーザーログイン関連モジュールおよびレイアウトプレースホルダーを削除", "ホーム画面からコミュニティおよびマーケットタブを削除し, レイアウトアライメントを最適化", "いくつかの設定オプションのデフォルトスイッチ状態を変更", - "「アプリについて」ページに SinceDate を追加し, Copyright の表示を最適化", + "[アプリについて] ページに SinceDate を追加し, Copyright の表示を最適化", "JSON モジュールを 2017-06-12 バージョンにアップグレードし, cycle.js を統合", "アクティビティがフォアグラウンドになるときの自動アップデートチェック機能および関連ボタンの削除", "AppOpsKt#isOpPermissionGranted 内部コードロジック", diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index a6cf33c9..fce51f92 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -1,7 +1,7 @@ { "$data": { "v6.7.0": { - "released_date": "2026/01/31", + "released_date": "2026/02/02", "feature": [ "插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮/主页标签页)", "Paddle OCR (PP-OCRv5) 插件, 用于光学字符识别", @@ -36,6 +36,7 @@ "等价系列选择器 (UiSelector#id/text/...) 及包含系列选择器 (UiSelector#xxxContains) 支持正则表达式参数", "选择器的正则表达式参数支持使用标志 (i, m, s, u)", "正则表达式支持后瞻断言语法 _[`issue #464`](http://issues.autojs6.com/464)_", + "文件管理器增加 \"移动到\" 及 \"复制到\" 菜单项, 支持操作中止及进度状态显示", "主页抽屉增加 \"指针位置\" 工具", "主页抽屉增加 \"所有文件管理权限\" 开关", "主页抽屉增加 \"后台弹出界面\" 开关 (针对 [小米/Vivo] 设备)", diff --git a/.readme/lang_ja.json b/.readme/lang_ja.json index 60dcdcc1..574f5371 100644 --- a/.readme/lang_ja.json +++ b/.readme/lang_ja.json @@ -141,7 +141,7 @@ "p_project_compilation_and_build_android_studio_intellij_idea": "AutoJs6 オープンソース プロジェクトのデバッグや開発が必要な場合は, [Android Studio](https://pro.autojs.org/) ([Google](https://www.google.com/) 社製品) または [IntelliJ IDEA](https://www.jetbrains.com/idea/) ([Jetbrains](https://www.jetbrains.com/) 社製品) を使用できます", "step_android_sdk": "Android SDK (Android ソフトウェア開発キット)", "step_appearance_behavior": "Appearance & Behavior (外観と動作)", - "step_build_execution_deployment": "Build, Execution, Deployment (ビルド、実行、デプロイ)", + "step_build_execution_deployment": "Build, Execution, Deployment (ビルド, 実行, デプロイ)", "step_build_tools": "Build Tools (ビルドツール)", "step_debug_apk_path": "デフォルトの署名が含まれたデバッグ版のインストールパッケージを生成します", "step_debug_version_path": "デバッグ版 (デバッグバージョン)", diff --git a/app/src/main/java/org/autojs/autojs/app/DialogUtils.kt b/app/src/main/java/org/autojs/autojs/app/DialogUtils.kt index e36c441b..4cc2b9f3 100644 --- a/app/src/main/java/org/autojs/autojs/app/DialogUtils.kt +++ b/app/src/main/java/org/autojs/autojs/app/DialogUtils.kt @@ -6,6 +6,7 @@ import android.app.Activity import android.content.Context import android.content.ContextWrapper import android.content.DialogInterface +import android.content.res.ColorStateList import android.os.Build import android.os.Looper import android.provider.Settings @@ -19,18 +20,26 @@ import androidx.preference.PreferenceViewHolder import com.afollestad.materialdialogs.DialogAction import com.afollestad.materialdialogs.MaterialDialog import org.autojs.autojs.annotation.ReservedForCompatibility +import org.autojs.autojs.event.BackCompat +import org.autojs.autojs.theme.ThemeColorManager import org.autojs.autojs.theme.preference.LongClickablePreferenceLike import org.autojs.autojs.ui.explorer.ExplorerView -import org.autojs.autojs.event.BackCompat +import org.autojs.autojs.util.ColorUtils +import org.autojs.autojs.util.ThreadUtils.runOnMain import org.autojs.autojs.util.ViewUtils.showSnack import org.autojs.autojs6.R +import java.util.Locale +import java.util.concurrent.Callable +import java.util.concurrent.CountDownLatch +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicReference /** * Created by Stardust on Aug 4, 2017. * Transformed by SuperMonster003 on Oct 19, 2022. - * Modified by JetBrains AI Assistant (GPT-5.2) as of Jan 18, 2026. * Modified by OpenAI ChatGPT (GPT-5.2 Thinking) as of Jan 20, 2026. - * Modified by SuperMonster003 as of Jan 20, 2026. + * Modified by JetBrains AI Assistant (GPT-5.2) as of Feb 1, 2026. + * Modified by SuperMonster003 as of Feb 1, 2026. */ object DialogUtils { @@ -40,6 +49,7 @@ object DialogUtils { fun MaterialDialog.Builder.showAdaptive() = build().showAdaptive() @JvmStatic + @Suppress("DEPRECATION") fun MaterialDialog.showAdaptive() = showDialog(this) /** @@ -80,6 +90,7 @@ object DialogUtils { */ @JvmStatic @JvmOverloads + @Deprecated("Use showAdaptive instead.", ReplaceWith("showAdaptive(dialog, focusable)")) @ReservedForCompatibility fun showDialog(dialog: T, focusable: Boolean = true): T { runOnMain { @@ -178,6 +189,92 @@ object DialogUtils { return dialog } + /** + * Build dialog on the main thread and return it. + * + * Note: + * - MaterialDialog.Builder.build() may internally create Android Dialog/Handler. + * - Building on a background thread can crash with "Can't create handler inside thread ...". + * + * zh-CN: + * + * 在主线程 build 对话框并返回实例. + * + * 注: + * - MaterialDialog.Builder.build() 内部可能创建 Android Dialog/Handler. + * - 在后台线程 build 可能触发 "Can't create handler inside thread ..." 崩溃. + */ + @JvmStatic + fun buildAdaptive(builder: MaterialDialog.Builder): T { + @Suppress("UNCHECKED_CAST") + return buildAdaptive { builder.build() as T } + } + + /** + * Build dialog on the main thread by a callable factory. + * + * zh-CN: 通过 callable 工厂在主线程 build 对话框. + */ + @JvmStatic + fun buildAdaptive(factory: Callable): T { + if (Looper.getMainLooper() == Looper.myLooper()) { + return factory.call() + } + + val ref = AtomicReference() + val err = AtomicReference() + val latch = CountDownLatch(1) + + GlobalAppContext.post { + try { + ref.set(factory.call()) + } catch (t: Throwable) { + err.set(t) + Log.w(TAG, "buildAdaptive: failed", t) + } finally { + latch.countDown() + } + } + + // Wait a bit to avoid infinite blocking in background threads. + // zh-CN: 设置等待超时以避免后台线程无限阻塞. + latch.await(5, TimeUnit.SECONDS) + + err.get()?.let { throw RuntimeException(it) } + + return ref.get() ?: throw RuntimeException("buildAdaptive: dialog is null (timeout or build failed)") + } + + /** + * Build and show dialog on the main thread, then return the dialog instance. + * Use this when the caller might be running on a background thread. + * + * zh-CN: + * + * 在主线程 build 并 show 对话框, 然后返回对话框实例. + * 当调用方可能运行在后台线程时使用该方法. + */ + @JvmStatic + @JvmOverloads + fun buildAndShowAdaptive(builder: MaterialDialog.Builder, focusable: Boolean = true): T { + val dialog = buildAdaptive(builder) + @Suppress("DEPRECATION") + return showDialog(dialog, focusable) + } + + /** + * Build and show dialog on the main thread with a callable factory, then return the instance. + * + * zh-CN: 使用 callable 工厂在主线程 build 并 show 对话框, 然后返回实例. + */ + @JvmStatic + @JvmOverloads + fun buildAndShowAdaptive(factory: Callable, focusable: Boolean = true): T { + val dialog = buildAdaptive(factory) + @Suppress("DEPRECATION") + return showDialog(dialog, focusable) + } + private fun unwrapActivity(context: Context?): Activity? { return when (context) { is Activity -> context @@ -186,14 +283,6 @@ object DialogUtils { } } - private inline fun runOnMain(crossinline block: () -> Unit) { - if (Looper.getMainLooper() == Looper.myLooper()) { - block() - } else { - GlobalAppContext.post { block() } - } - } - @JvmStatic fun fixCheckBoxGravity(dialog: T): T = dialog.also { it.view.findViewById(com.afollestad.materialdialogs.R.id.md_promptCheckbox)?.gravity = Gravity.CENTER_VERTICAL @@ -215,10 +304,6 @@ object DialogUtils { dialog.getActionButton(actionButton)?.isEnabled = !dialog.items.isNullOrEmpty() } - @JvmStatic - fun MaterialDialog.installBackHandler(onBack: (DialogInterface) -> Boolean): MaterialDialog = - BackCompat.installDialogBackHandler(this, onBack = onBack) - @JvmStatic fun adaptToExplorer(dialog: MaterialDialog, explorerView: ExplorerView): MaterialDialog { val time = object { @@ -297,4 +382,97 @@ object DialogUtils { } } + @JvmStatic + fun MaterialDialog.installBackHandler(onBack: (DialogInterface) -> Boolean): MaterialDialog = + BackCompat.installDialogBackHandler(this, onBack = onBack) + + @JvmStatic + @JvmOverloads + fun MaterialDialog.setProgressNumberFormatByBytes(readBytes: Long, totalBytes: Long, invalidBytesHint: String = ""): MaterialDialog = also { + setProgressNumberFormat(getProgressBytesFormat(readBytes, totalBytes, invalidBytesHint)) + } + + @JvmStatic + fun MaterialDialog.setProgressNumberFormatByBytes(readBytes: Long, totalBytes: Long, showPendingHint: Boolean): MaterialDialog = also { + setProgressNumberFormat(getProgressBytesFormat(readBytes, totalBytes, if (showPendingHint) "..." else "")) + } + + @Suppress("LocalVariableName") + private fun getProgressBytesFormat( + readBytes: Long, + totalBytes: Long, + invalidBytesHint: String = "", + ): String { + + if (totalBytes <= 0 || readBytes <= 0) { + return invalidBytesHint + } + + val locale = Locale.getDefault() + + val r = readBytes.toDouble() + val t = totalBytes.toDouble() + + val KiB = 1024.0 + val MiB = KiB * 1024.0 + val GiB = MiB * 1024.0 + val TiB = GiB * 1024.0 + + return when { + totalBytes < 1000L -> + String.format(locale, "%.0f B / %.0f B", r, t) + + totalBytes < 1000L * 1024L -> when { + readBytes < 1000L -> + String.format(locale, "%.0f B / %.1f KiB", r, t / KiB) + else -> + String.format(locale, "%.1f KiB / %.1f KiB", r / KiB, t / KiB) + } + + totalBytes < 1000L * 1024L * 1024L -> when { + readBytes < 1000L -> + String.format(locale, "%.0f B / %.2f MiB", r, t / MiB) + readBytes < 1000L * 1024L -> + String.format(locale, "%.1f KiB / %.2f MiB", r / KiB, t / MiB) + else -> + String.format(locale, "%.2f MiB / %.2f MiB", r / MiB, t / MiB) + } + + totalBytes < 1000L * 1024L * 1024L * 1024L -> when { + readBytes < 1000L -> + String.format(locale, "%.0f B / %.2f GiB", r, t / GiB) + readBytes < 1000L * 1024L -> + String.format(locale, "%.1f KiB / %.2f GiB", r / KiB, t / GiB) + readBytes < 1000L * 1024L * 1024L -> + String.format(locale, "%.2f MiB / %.2f GiB", r / MiB, t / GiB) + else -> + String.format(locale, "%.2f GiB / %.2f GiB", r / GiB, t / GiB) + } + + else -> when { + readBytes < 1000L -> + String.format(locale, "%.0f B / %.2f TiB", r, t / TiB) + readBytes < 1000L * 1024L -> + String.format(locale, "%.1f KiB / %.2f TiB", r / KiB, t / TiB) + readBytes < 1000L * 1024L * 1024L -> + String.format(locale, "%.2f MiB / %.2f TiB", r / MiB, t / TiB) + readBytes < 1000L * 1024L * 1024L * 1024L -> + String.format(locale, "%.2f GiB / %.2f TiB", r / GiB, t / TiB) + else -> + String.format(locale, "%.2f TiB / %.2f TiB", r / TiB, t / TiB) + } + } + } + + @JvmStatic + fun MaterialDialog.applyProgressThemeColorTintLists(): MaterialDialog = also { + val progressBar = progressBar ?: return@also + + val bgColor = context.getColor(R.color.dialog_progress_gray_background_tint) + val fgColor = ColorUtils.adjustColorForContrast(bgColor, ThemeColorManager.colorPrimary, 2.3) + + progressBar.setProgressTintList(ColorStateList.valueOf(fgColor)) + progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(bgColor)) + } + } \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/app/tool/JsonSocketClientTool.kt b/app/src/main/java/org/autojs/autojs/app/tool/JsonSocketClientTool.kt index 0c145556..03e94ccc 100644 --- a/app/src/main/java/org/autojs/autojs/app/tool/JsonSocketClientTool.kt +++ b/app/src/main/java/org/autojs/autojs/app/tool/JsonSocketClientTool.kt @@ -20,6 +20,7 @@ import org.autojs.autojs.pluginclient.DevPluginService import org.autojs.autojs.pluginclient.JsonSocketClient import org.autojs.autojs.ui.common.NotAskAgainDialog import org.autojs.autojs.util.Observers +import org.autojs.autojs.util.ThreadUtils.runOnMain import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.R import java.lang.ref.WeakReference @@ -95,23 +96,15 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { return a.isFinishing || a.isDestroyed } - private fun runOnMainThread(action: () -> Unit) { - if (Looper.myLooper() == Looper.getMainLooper()) { - action() - } else { - mainHandler.post { action() } - } - } - private fun dismissConnectionDialogSilently() { - runOnMainThread { + runOnMain(mainHandler) { runCatching { connectionDialogRef?.get()?.dismiss() } connectionDialogRef = null } } private fun dismissConnectingStatusDialogSilently() { - runOnMainThread { + runOnMain(mainHandler) { runCatching { connectingStatusDisposable?.dispose() } connectingStatusDisposable = null runCatching { connectingStatusDialogRef?.get()?.dismiss() } @@ -120,7 +113,7 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { } private fun dismissConnectionFailedDialogSilently() { - runOnMainThread { + runOnMain(mainHandler) { runCatching { connectionFailedDialogRef?.get()?.dismiss() } connectionFailedDialogRef = null } @@ -136,7 +129,7 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { private fun scheduleDismissConnectingDialogWithMinDuration(shownAt: Long, afterDismiss: (() -> Unit)? = null) { val elapsed = System.currentTimeMillis() - shownAt val delay = (connectingDialogMinShowMillis - elapsed).coerceAtLeast(0L) - runOnMainThread { + runOnMain(mainHandler) { mainHandler.postDelayed( { dismissConnectingStatusDialogSilently() @@ -296,12 +289,12 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { .positiveColorRes(R.color.dialog_button_attraction) .autoDismiss(false) .dismissListener { - runOnMainThread { connectionDialogRef = null } + runOnMain(mainHandler) { connectionDialogRef = null } onConnectionDialogDismissed.onDismiss(it) } .show() .also { dialog: MaterialDialog -> - runOnMainThread { connectionDialogRef = WeakReference(dialog) } + runOnMain(mainHandler) { connectionDialogRef = WeakReference(dialog) } dialog.setOnKeyListener { _, keyCode, _ -> if (keyCode == KeyEvent.KEYCODE_ENTER) { @@ -360,7 +353,7 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { // Close input dialog first, then show status dialog. // zh-CN: 先关闭输入 dialog, 再显示状态 dialog. - runOnMainThread { runCatching { dismissInputDialog?.dismiss() } } + runOnMain(mainHandler) { runCatching { dismissInputDialog?.dismiss() } } dismissConnectingStatusDialogSilently() dismissConnectionFailedDialogSilently() @@ -382,7 +375,7 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { dismissConnectingStatusDialogSilently() inputRemoteHost(isAutoConnect = false, prefill = trimmedHost) } - .positiveText(R.string.dialog_button_interrupt_connection) + .positiveText(R.string.dialog_button_abort_connection) .positiveColorRes(R.color.dialog_button_caution) .onPositive { d, _ -> // Treat as user interrupt: stop current attempt and mark normally closed. @@ -482,7 +475,7 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { dismissConnectingStatusDialogSilently() inputRemoteHost(isAutoConnect = false, prefill = host) } - .positiveText(R.string.dialog_button_interrupt_connection) + .positiveText(R.string.dialog_button_abort_connection) .positiveColorRes(R.color.dialog_button_caution) .onPositive { d, _ -> // Treat as user interrupt: stop current attempt and mark normally closed. @@ -578,8 +571,8 @@ class JsonSocketClientTool(context: Context) : AbstractJsonSocketTool(context) { } private fun showSnack(dialog: MaterialDialog, strRes: Int) { - runOnMainThread { - if (isContextInvalidForDialog()) return@runOnMainThread + runOnMain(mainHandler) { + if (isContextInvalidForDialog()) return@runOnMain ViewUtils.showSnack(dialog.view, dialog.context.getString(strRes)) } } diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInstaller.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInstaller.kt index ca165edc..2e1ed063 100644 --- a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInstaller.kt +++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInstaller.kt @@ -2,7 +2,6 @@ package org.autojs.autojs.core.plugin.center import android.content.Context import android.content.Intent -import android.content.res.ColorStateList import android.net.Uri import androidx.core.content.FileProvider import com.afollestad.materialdialogs.DialogAction @@ -11,7 +10,8 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.withContext -import org.autojs.autojs.network.download.DownloadManager +import org.autojs.autojs.app.DialogUtils.applyProgressThemeColorTintLists +import org.autojs.autojs.app.DialogUtils.setProgressNumberFormatByBytes import org.autojs.autojs.runtime.api.Mime import org.autojs.autojs.ui.main.scripts.ApkInfoDialogManager import org.autojs.autojs.util.ClipboardUtils @@ -182,13 +182,10 @@ object PluginInstaller { .autoDismiss(false) .show() + dialog.applyProgressThemeColorTintLists() dialog.setProgressNumberFormat(context.getString(R.string.text_half_ellipsis)) dialog.setProgress(0) - val progressBar = dialog.getProgressBar() - progressBar.setProgressTintList(ColorStateList.valueOf(context.getColor(R.color.dialog_progress_download_tint))) - progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(context.getColor(R.color.dialog_progress_download_bg_tint))) - try { val cache = File(context.cacheDir, "plugin_dl").apply { if (!exists()) mkdirs() } val name = guessFileName(url) @@ -204,15 +201,7 @@ object PluginInstaller { if (code !in 200..299) throw HttpStatusException(code, conn.responseMessage ?: "HTTP error") val total = conn.contentLengthLong.takeIf { it > 0 } ?: -1L - if (total > 0) { - dialog.setProgressNumberFormat( - DownloadManager.getProgressMegaBytesFormat( - context, - /* downloadedMiB */ 0f, - /* totalMiB */ total / (1024f * 1024f), - ) - ) - } + dialog.setProgressNumberFormatByBytes(0, total, true) conn.inputStream.use { input -> val md = MessageDigest.getInstance("SHA-256") @@ -233,13 +222,7 @@ object PluginInstaller { if (total > 0 && (now - lastUpdateTs > 80)) { val pct = ((downloaded * 100f) / total).coerceIn(0f, 100f) withContext(Dispatchers.Main) { - dialog.setProgressNumberFormat( - DownloadManager.getProgressMegaBytesFormat( - context, - downloaded / (1024f * 1024f), - total / (1024f * 1024f), - ) - ) + dialog.setProgressNumberFormatByBytes(downloaded, total, true) dialog.setProgress(pct.roundToInt()) } lastUpdateTs = now diff --git a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java index 27d34beb..d4945339 100644 --- a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java +++ b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java @@ -62,6 +62,11 @@ public class ExplorerFileItem implements ExplorerItem { return !isInSampleDir(mFile) && mFile.canWrite(); } + @Override + public boolean canMove() { + return !isInSampleDir(mFile) && mFile.canWrite(); + } + @Override public boolean canDelete() { return !isInSampleDir(mFile) && mFile.canWrite(); @@ -109,7 +114,7 @@ public class ExplorerFileItem implements ExplorerItem { return new ScriptFile(mFile); } - private boolean isInSampleDir(PFile file) { + public static boolean isInSampleDir(File file) { return Explorers.Providers.workspace().isInSampleDir(file); } diff --git a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerItem.java b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerItem.java index 180a2330..5426c06f 100644 --- a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerItem.java +++ b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerItem.java @@ -25,10 +25,16 @@ public interface ExplorerItem { long lastModified(); - boolean canDelete(); + boolean canMove(); + + default boolean canCopy() { + return true; + } boolean canRename(); + boolean canDelete(); + default boolean canBuildApk() { return true; } diff --git a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerSampleItem.java b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerSampleItem.java index a9331e22..8a8ab19b 100644 --- a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerSampleItem.java +++ b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerSampleItem.java @@ -5,6 +5,7 @@ import org.autojs.autojs.pio.PFile; import java.io.File; public class ExplorerSampleItem extends ExplorerFileItem { + public ExplorerSampleItem(PFile file, ExplorerPage parent) { super(file, parent); } @@ -27,6 +28,11 @@ public class ExplorerSampleItem extends ExplorerFileItem { return false; } + @Override + public boolean canMove() { + return false; + } + @Override public boolean canBuildApk() { return getFile().canBuildApk(); @@ -36,5 +42,4 @@ public class ExplorerSampleItem extends ExplorerFileItem { public boolean canSetAsWorkingDir() { return false; } - -} +} \ No newline at end of file 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 7ff6a27a..d068b70c 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 @@ -58,11 +58,11 @@ public class WorkspaceFileProvider extends ExplorerFileProvider { .subscribeOn(Schedulers.io()); } - public boolean isInSampleDir(PFile file) { + public boolean isInSampleDir(File file) { return file.getPath().startsWith(mSampleDir.getPath()); } - public boolean isCurrentSampleDir(PFile file) { + public boolean isCurrentSampleDir(File file) { return file.getPath().equals(mSampleDir.getPath()); } diff --git a/app/src/main/java/org/autojs/autojs/network/download/DownloadManager.java b/app/src/main/java/org/autojs/autojs/network/download/DownloadManager.java index 9b58a2f9..b2301745 100644 --- a/app/src/main/java/org/autojs/autojs/network/download/DownloadManager.java +++ b/app/src/main/java/org/autojs/autojs/network/download/DownloadManager.java @@ -22,8 +22,8 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; +import org.autojs.autojs.app.DialogUtils; import org.autojs.autojs.concurrent.VolatileBox; -import org.autojs.autojs.core.pref.Language; import org.autojs.autojs.network.UpdateChecker; import org.autojs.autojs.network.api.DownloadApi; import org.autojs.autojs.network.entity.VersionInfo; @@ -53,8 +53,6 @@ public class DownloadManager { private final int mRetryCount = 3; - // 10,000 KB (around but less than 10 MB) - private final int mMegaThreshold = 10000 * (1 << 10); private final Handler mHandler; private final DownloadApi mDownloadApi; private final ConcurrentHashMap> mDownloadStatuses = new ConcurrentHashMap<>(); @@ -119,16 +117,6 @@ public class DownloadManager { } } - @SuppressWarnings("ResultOfMethodCallIgnored") - @SuppressLint("CheckResult") - public Observable download(String url, String path) { - DownloadTask task = new DownloadTask(url, path); - mDownloadApi.download(url) - .subscribeOn(Schedulers.io()) - .subscribe(task::start, error -> task.progress().onError(error)); - return task.progress(); - } - public Observable downloadWithProgress(Context context, String url, String path) { String content = context.getString(R.string.text_file_name) + ": " + DownloadManager.parseFileNameLocally(url); return downloadWithProgress(context, url, path, content); @@ -139,12 +127,12 @@ public class DownloadManager { final String path = new File(downloadDir, versionInfo.getFileName()).getPath(); String url = versionInfo.getDownloadUrl(); initProgressDialog(context, versionInfo); - return download(context, url, path); + return download(url, path); } public Observable downloadWithProgress(Context context, String url, String path, String content) { initProgressDialog(context, url, content); - return download(context, url, path); + return download(url, path); } private void initProgressDialog(Context context, @NonNull String url, @Nullable VersionInfo versionInfo, @Nullable String content) { @@ -178,21 +166,12 @@ public class DownloadManager { mProgressDialog.setContent(contentText); } - if (versionInfo != null && versionInfo.getSize() > 0) { + if (versionInfo != null) { long size = versionInfo.getSize(); - if (size > mMegaThreshold) { - mProgressDialog.setProgressNumberFormat(getProgressMegaBytesFormat(context, 0, (float) (size / Math.pow(2, 20)))); - } else { - mProgressDialog.setProgressNumberFormat(getProgressKiloBytesFormat(context, 0, (float) (size / Math.pow(2, 10)))); - } - } else { - mProgressDialog.setProgressNumberFormat(context.getString(R.string.text_half_ellipsis)); + DialogUtils.setProgressNumberFormatByBytes(mProgressDialog, 0, size, context.getString(R.string.text_half_ellipsis)); } - ProgressBar progressBar = mProgressDialog.getProgressBar(); - progressBar.setProgressTintList(ColorStateList.valueOf(context.getColor(R.color.dialog_progress_download_tint))); - progressBar.setProgressBackgroundTintList(ColorStateList.valueOf(context.getColor(R.color.dialog_progress_download_bg_tint))); - + DialogUtils.applyProgressThemeColorTintLists(mProgressDialog); } private void initProgressDialog(Context context, String url, String content) { @@ -203,18 +182,23 @@ public class DownloadManager { initProgressDialog(context, versionInfo.getDownloadUrl(), versionInfo, null); } - @NonNull - private Observable download(Context context, String url, String path) { - PublishSubject subject = PublishSubject.create(); - DownloadManager downloadMgr = DownloadManager.getInstance(); - downloadMgr.download(url, path) + @SuppressLint("CheckResult") + @SuppressWarnings("ResultOfMethodCallIgnored") + private Observable download(String url, String path) { + + PublishSubject downloadSubject = PublishSubject.create(); + + DownloadTask task = new DownloadTask(url, path); + PublishSubject progressSubject = task.progress(); + + mDownloadApi.download(url) + .subscribeOn(Schedulers.io()) + .subscribe(task::start, progressSubject::onError); + + progressSubject .observeOn(AndroidSchedulers.mainThread()) .doOnNext(o -> { - if (o.getTotalBytes() > mMegaThreshold) { - mProgressDialog.setProgressNumberFormat(getProgressMegaBytesFormat(context, o.getReadMegaBytes(), o.getTotalMegaBytes())); - } else { - mProgressDialog.setProgressNumberFormat(getProgressKiloBytesFormat(context, o.getReadKiloBytes(), o.getTotalKiloBytes())); - } + DialogUtils.setProgressNumberFormatByBytes(mProgressDialog, o.getReadBytes(), o.getTotalBytes()); mProgressDialog.setProgress(o.getProgress()); }) .subscribe(new SimpleObserver<>() { @@ -227,8 +211,8 @@ public class DownloadManager { public void onComplete() { mProgressDialog.dismiss(); mProgressDialog = null; - subject.onNext(new File(path)); - subject.onComplete(); + downloadSubject.onNext(new File(path)); + downloadSubject.onComplete(); } @Override @@ -237,10 +221,10 @@ public class DownloadManager { mProgressDialog = null; disposeIfNeeded(); mOkHttpClient.dispatcher().cancelAll(); - subject.onError(error); + downloadSubject.onError(error); } }); - return subject; + return downloadSubject; } public void cancelDownload(String url) { @@ -250,18 +234,6 @@ public class DownloadManager { } } - public static String getProgressKiloBytesFormat(Context context, float readKiloBytes, float totalKiloBytes) { - return String.format(Language.getPrefLanguage().getLocale(), - context.getString(R.string.format_dialog_progress_number_format_kilo_bytes), - readKiloBytes, totalKiloBytes); - } - - public static String getProgressMegaBytesFormat(Context context, float readMegaBytes, float totalMegaBytes) { - return String.format(Language.getPrefLanguage().getLocale(), - context.getString(R.string.format_dialog_progress_number_format_mega_bytes), - readMegaBytes, totalMegaBytes); - } - private class DownloadTask { private final String mUrl; @@ -317,7 +289,7 @@ public class DownloadManager { private void activeProgressDialogButton() { MDButton button = mProgressDialog.getActionButton(DialogAction.POSITIVE); - button.setTextColor(mProgressDialog.getContext().getColor(R.color.dialog_progress_download_act_btn)); + button.setTextColor(mProgressDialog.getContext().getColor(R.color.dialog_button_caution)); button.setOnClickListener(view -> { mProgressDialog.dismiss(); DownloadManager.getInstance().cancelDownload(mUrl); diff --git a/app/src/main/java/org/autojs/autojs/network/download/ProgressInfo.java b/app/src/main/java/org/autojs/autojs/network/download/ProgressInfo.java index 3ba45708..988c8261 100644 --- a/app/src/main/java/org/autojs/autojs/network/download/ProgressInfo.java +++ b/app/src/main/java/org/autojs/autojs/network/download/ProgressInfo.java @@ -2,6 +2,7 @@ package org.autojs.autojs.network.download; /** * Created by SuperMonster003 on May 30, 2022. + * Modified by SuperMonster003 as of Feb 1, 2026. */ public class ProgressInfo { private long mRead = 0; @@ -15,14 +16,6 @@ public class ProgressInfo { return mTotal; } - public float getTotalKiloBytes() { - return (float) (mTotal / Math.pow(2, 10)); - } - - public float getTotalMegaBytes() { - return (float) (mTotal / Math.pow(2, 20)); - } - public void setTotal(long total) { mTotal = total; } @@ -35,14 +28,6 @@ public class ProgressInfo { return mRead; } - public float getReadKiloBytes() { - return (float) (mRead / Math.pow(2, 10)); - } - - public float getReadMegaBytes() { - return (float) (mRead / Math.pow(2, 20)); - } - public void setRead(long read) { mRead = read; } 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 b60d6f2f..61fb3cba 100644 --- a/app/src/main/java/org/autojs/autojs/pio/PFiles.kt +++ b/app/src/main/java/org/autojs/autojs/pio/PFiles.kt @@ -3,6 +3,7 @@ package org.autojs.autojs.pio import android.content.Context import android.content.res.AssetManager import android.text.TextUtils +import org.autojs.autojs.annotation.ReservedForCompatibility import org.autojs.autojs.app.GlobalAppContext import org.autojs.autojs.runtime.api.augment.converter.core.Bytes import org.autojs.autojs.tool.Func1 @@ -19,6 +20,7 @@ import java.io.IOException import java.io.InputStream import java.io.OutputStream import java.nio.charset.Charset +import java.util.Locale /** * Created by Stardust on Apr 1, 2017. @@ -368,11 +370,14 @@ object PFiles { @JvmStatic fun deleteRecursively(file: File): Boolean { - if (file.isFile) return file.delete() - val children = file.listFiles() - if (children != null) { - for (child in children) { - if (!deleteRecursively(child)) return false + if (file.isDirectory()) { + val children = file.listFiles() + if (children != null) { + for (child in children) { + if (!deleteRecursively(child)) { + return false + } + } } } return file.delete() @@ -444,6 +449,7 @@ object PFiles { @JvmStatic @JvmOverloads + @ReservedForCompatibility fun getHumanReadableSize(bytes: Long, useIecIdentifier: Boolean = false): String { return Bytes.string( source = bytes.toDouble(), @@ -457,6 +463,37 @@ object PFiles { ) } + @JvmStatic + @Suppress("LocalVariableName") + fun formatSizeWithUnit(bytes: Long): String { + + require(bytes >= 0) { + "Argument \"bytes\" for \"formatSizeWithUnit\" must be non-negative instead of $bytes." + } + + val locale = Locale.getDefault() + + val b = bytes.toDouble() + + val KiB = 1024.0 + val MiB = KiB * 1024.0 + val GiB = MiB * 1024.0 + val TiB = GiB * 1024.0 + + return when { + bytes < 1000L -> + String.format(locale, "%.0f B", b) + bytes < 1000L * 1024L -> + String.format(locale, "%.1f KiB", b / KiB) + bytes < 1000L * 1024L * 1024L -> + String.format(locale, "%.2f MiB", b / MiB) + bytes < 1000L * 1024L * 1024L * 1024L -> + String.format(locale, "%.2f GiB", b / GiB) + else -> + String.format(locale, "%.2f TiB", b / TiB) + } + } + @JvmStatic fun getElegantPath(path: String) = getElegantPath(path, null, false) diff --git a/app/src/main/java/org/autojs/autojs/runtime/ScriptRuntime.kt b/app/src/main/java/org/autojs/autojs/runtime/ScriptRuntime.kt index 503a8db6..a16c4bd3 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/ScriptRuntime.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/ScriptRuntime.kt @@ -769,8 +769,8 @@ class ScriptRuntime private constructor(builder: Builder) { QrCode(this).augment(target, true) Threads(this).augment(target, threads, true) UI(this).proxying(target, ui, true) - Colors.augmentWithRuntime(target, this, listOf(colors, Colors), true) - Color.augmentWithRuntime(target, this, false) + Colors.augmentWithRuntime(target, this, Colors.colorTables + colors, true) + Color.augmentWithRuntime(target, this,Colors.colorTables, false) Tasks(this).augment(target, true) Dialogs(this).augment(target, true) Continuation(this).augment(target, js_mod_continuation, true, READONLY) diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/Files.kt b/app/src/main/java/org/autojs/autojs/runtime/api/Files.kt index bd4bedeb..77a69c09 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/Files.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/Files.kt @@ -197,6 +197,10 @@ class Files(private val scriptRuntime: ScriptRuntime) { return PFiles.getHumanReadableSize(bytes, useIecIdentifier) } + fun formatSizeWithUnit(bytes: Long): String { + return PFiles.formatSizeWithUnit(bytes) + } + fun getSimplifiedPath(path: String?): String { return getElegantPath(ensurePathNotNull(path, ::getSimplifiedPath.name, shouldWrapWithPathMethod = false)) } diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/ColorNativeObject.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/ColorNativeObject.kt index f237caca..342cbcc3 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/ColorNativeObject.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/ColorNativeObject.kt @@ -93,7 +93,9 @@ class ColorNativeObject @JvmOverloads constructor(color: Any? = BLACK) : NativeO } @RhinoFunctionObjectBody - override fun equals(other: Any?) = Colors.isEqualRhino(color, other) + override fun equals(other: Any?) = runCatching { + Colors.isEqualRhino(color, other) + }.getOrDefault(false) @RhinoFunctionObjectBody override fun toStringReadable(): String = Colors.summaryRhino(color) diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/Colors.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/Colors.kt index b226fa5e..22d1c4ea 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/Colors.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/colors/Colors.kt @@ -7,27 +7,26 @@ import android.os.Build import androidx.core.graphics.ColorUtils.HSLToColor import androidx.core.graphics.ColorUtils.RGBToHSL import androidx.core.graphics.ColorUtils.calculateLuminance -import org.autojs.autojs.annotation.AugmentableSimpleGetterProxyInterface import org.autojs.autojs.annotation.RhinoFunctionBody import org.autojs.autojs.annotation.RhinoSingletonFunctionInterface import org.autojs.autojs.core.image.ColorDetector import org.autojs.autojs.core.image.ColorTable +import org.autojs.autojs.rhino.ArgumentGuards.Companion.component1 +import org.autojs.autojs.rhino.ArgumentGuards.Companion.component2 import org.autojs.autojs.rhino.extension.AnyExtensions.isJsNullish import org.autojs.autojs.rhino.extension.AnyExtensions.jsBrief import org.autojs.autojs.rhino.extension.AnyExtensions.jsSpecies -import org.autojs.autojs.rhino.ArgumentGuards.Companion.component1 -import org.autojs.autojs.rhino.ArgumentGuards.Companion.component2 import org.autojs.autojs.rhino.extension.ArrayExtensions.jsArrayBrief import org.autojs.autojs.rhino.extension.IterableExtensions.toNativeArray import org.autojs.autojs.rhino.extension.MapExtensions.toNativeObject import org.autojs.autojs.rhino.extension.ScriptableExtensions.prop import org.autojs.autojs.rhino.extension.ScriptableObjectExtensions.inquire import org.autojs.autojs.runtime.api.augment.Augmentable -import org.autojs.autojs.runtime.api.augment.SimpleGetterProxy import org.autojs.autojs.runtime.api.augment.jsox.Numberx import org.autojs.autojs.runtime.exception.ShouldNeverHappenException import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.theme.ThemeColor +import org.autojs.autojs.theme.ThemeColorManager import org.autojs.autojs.util.ColorUtils import org.autojs.autojs.util.ColorUtils.roundToAlphaString import org.autojs.autojs.util.ColorUtils.roundToHueString @@ -39,8 +38,6 @@ import org.autojs.autojs.util.RhinoUtils.newNativeObject import org.mozilla.javascript.Context import org.mozilla.javascript.NativeArray import org.mozilla.javascript.NativeObject -import org.mozilla.javascript.Scriptable -import org.mozilla.javascript.Scriptable.NOT_FOUND import org.mozilla.javascript.ScriptableObject.DONTENUM import java.util.function.Supplier import kotlin.math.abs @@ -48,7 +45,7 @@ import kotlin.math.roundToInt import android.graphics.Color as AndroidColor @Suppress("unused", "UNUSED_PARAMETER") -object Colors : Augmentable(), SimpleGetterProxy { +object Colors : Augmentable() { @JvmField @Suppress("MayBeConstant") @@ -58,7 +55,7 @@ object Colors : Augmentable(), SimpleGetterProxy { @Suppress("MayBeConstant") val DEFAULT_COLOR_ALGORITHM = "diff" - private val colorTables = arrayOf( + internal val colorTables = listOf( ColorTable.Android, ColorTable.Css, ColorTable.Web, @@ -155,29 +152,9 @@ object Colors : Augmentable(), SimpleGetterProxy { override val selfAssignmentGetters = listOf( "all" to Supplier { allForNativeObject } to DONTENUM, + "themeColor" to Supplier { ThemeColorManager.currentThemeColor }, ) - @JvmStatic - @AugmentableSimpleGetterProxyInterface - fun get(scope: Scriptable, key: String): Any? { - for (table in colorTables) { - // @Alter by SuperMonster003 on Jun 15, 2024. - // # for (member in table::class.members) { - // # if (member.name == name) { - // # return@ensureArgumentsOnlyOne member.call() - // # } - // # } - try { - return table::class.java.getDeclaredField(key).apply { - isAccessible = true - }.get(null) ?: NOT_FOUND - } catch (e: Exception) { - e.printStackTrace() - } - } - return NOT_FOUND - } - @JvmStatic @RhinoSingletonFunctionInterface fun toInt(args: Array): Int = ensureArgumentsOnlyOne(args) { diff --git a/app/src/main/java/org/autojs/autojs/ui/common/RxDialogs.java b/app/src/main/java/org/autojs/autojs/ui/common/RxDialogs.java index 047c5005..995426e6 100644 --- a/app/src/main/java/org/autojs/autojs/ui/common/RxDialogs.java +++ b/app/src/main/java/org/autojs/autojs/ui/common/RxDialogs.java @@ -1,32 +1,38 @@ package org.autojs.autojs.ui.common; import android.content.Context; - import com.afollestad.materialdialogs.MaterialDialog; - -import org.autojs.autojs6.R; - import io.reactivex.Observable; import io.reactivex.subjects.PublishSubject; +import org.autojs.autojs6.R; /** * Created by Stardust on Oct 21, 2017. + * Modified by SuperMonster003 as of Feb 1, 2026. */ public class RxDialogs { public static Observable confirm(Context context, String content) { return confirm(context, content, 0); } - + public static Observable confirm(Context context, String content, int positiveColorRes) { PublishSubject subject = PublishSubject.create(); MaterialDialog.Builder builder = new MaterialDialog.Builder(context) + .title(R.string.text_prompt) .content(content) - .negativeText(R.string.text_cancel) + .negativeText(R.string.dialog_button_abandon) .negativeColorRes(R.color.dialog_button_default) - .onNegative((dialog, which) -> subject.onNext(false)) - .positiveText(R.string.text_ok) - .onPositive((dialog, which) -> subject.onNext(true)); + .onNegative((dialog, which) -> { + subject.onNext(false); + subject.onComplete(); + }) + .positiveText(R.string.dialog_button_confirm) + .positiveColorRes(R.color.dialog_button_default) + .onPositive((dialog, which) -> { + subject.onNext(true); + subject.onComplete(); + }); if (positiveColorRes != 0) { builder.positiveColorRes(positiveColorRes); } diff --git a/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java b/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java index d7f3c8df..3d8c0fb9 100644 --- a/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java +++ b/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java @@ -4,11 +4,13 @@ import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.os.Environment; +import android.os.SystemClock; import android.text.Editable; import android.text.InputType; import android.util.Log; import android.view.View; import android.widget.EditText; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.pm.ShortcutManagerCompat; @@ -22,7 +24,6 @@ import io.reactivex.subjects.PublishSubject; import org.autojs.autojs.app.DialogUtils; import org.autojs.autojs.app.GlobalAppContext; import org.autojs.autojs.core.pref.Pref; -import org.autojs.autojs.util.MaterialDialogUtils; import org.autojs.autojs.external.ScriptIntents; import org.autojs.autojs.model.explorer.Explorer; import org.autojs.autojs.model.explorer.ExplorerDirPage; @@ -44,34 +45,69 @@ import org.autojs.autojs.ui.shortcut.ShortcutCreateActivity; import org.autojs.autojs.ui.timing.TimedTaskSettingActivity; import org.autojs.autojs.util.EnvironmentUtils; import org.autojs.autojs.util.IntentUtils; +import org.autojs.autojs.util.MaterialDialogUtils; import org.autojs.autojs.util.ShortcutUtils; import org.autojs.autojs.util.ViewUtils; import org.autojs.autojs.util.WorkingDirectoryUtils; import org.autojs.autojs6.R; -import org.reactivestreams.Publisher; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.autojs.autojs.util.FileUtils; import static org.autojs.autojs.app.DialogUtils.fixCheckBoxGravity; +import static org.autojs.autojs.model.explorer.ExplorerFileItem.isInSampleDir; import static org.autojs.autojs.util.FileUtils.TYPE.JAVASCRIPT; import static org.autojs.autojs.util.RhinoUtils.isMainThread; +import static org.autojs.autojs.util.ThreadUtils.runOnMain; /** * Created by Stardust on Jul 31, 2017. + * Modified by JetBrains AI Assistant (GPT-5.2) as of Jan 31, 2026. + * Modified by SuperMonster003 as of Feb 1, 2026. */ +@SuppressWarnings({"ResultOfMethodCallIgnored", "CodeBlock2Expr"}) @SuppressLint("CheckResult") public class ScriptOperations { private static final String LOG_TAG = "ScriptOperations"; + + // Minimum UI update interval for progress dialog, to reduce main-thread pressure. + // zh-CN: 进度对话框 UI 更新的最小间隔, 用于降低主线程压力. + private static final long PROGRESS_UPDATE_MIN_INTERVAL_MS = 50L; + + // Delay before showing progress dialog to avoid flashing for fast operations. + // zh-CN: 显示进度对话框前的延迟, 用于避免快速操作导致的闪现. + private static final long PROGRESS_DIALOG_SHOW_DELAY_MS = 200L; + + // Minimum duration to keep progress dialog visible once shown, to avoid flashing. + // zh-CN: 进度对话框一旦显示后的最短展示时长, 用于避免闪现. + private static final long PROGRESS_DIALOG_MIN_SHOW_MS = 300L; + + // Progress max for large files (totalBytes > Integer.MAX_VALUE), higher means smoother progress. + // zh-CN: 大文件 (totalBytes > Integer.MAX_VALUE) 的进度最大值, 值越大进度越细腻. + private static final int PROGRESS_MAX_LARGE = 10_000; + + // Suffix for partial copy output file. + // zh-CN: 复制过程的临时输出文件后缀. + private static final String PARTIAL_COPY_SUFFIX = ".partial"; + + private static final String INTERNAL_STORAGE_ROOT = "/storage/emulated/0"; + private final ExplorerPage mExplorerPage; private final Context mContext; private final View mView; @@ -135,14 +171,6 @@ public class ScriptOperations { } } - private void notifyFileCreated(ScriptFile scriptFile) { - if (scriptFile.isDirectory()) { - mExplorer.notifyItemCreated(new ExplorerDirPage(scriptFile, mExplorerPage)); - } else { - mExplorer.notifyItemCreated(new ExplorerFileItem(scriptFile, mExplorerPage)); - } - } - public void newFile() { final AtomicReference dialogRef = new AtomicReference<>(); String presetFileNamePrefix = getNewFileNamePresetPrefill(availablePrefixes.get(Pref.getInt(R.string.key_explorer_file_default_prefix, 0))); @@ -374,8 +402,548 @@ public class ScriptOperations { }); } + public Observable copy(@NonNull ScriptFile source) { + return copyOrMoveInternal(source, false); + } + + public Observable move(@NonNull ScriptFile source) { + return copyOrMoveInternal(source, true); + } + + private Observable copyOrMoveInternal(@NonNull ScriptFile source, boolean isMove) { + int titleRes = isMove ? R.string.text_move_to : R.string.text_copy_to; + String currentDir = isInSampleDir(source) ? WorkingDirectoryUtils.getPath() : getCurrentDirectoryPath(); + return new FileChooserDialogBuilder(mContext) + .title(titleRes) + .dir(currentDir) + .chooseDir() + .singleChoice() + .map(destDir -> new File(destDir.getPath(), source.getName())) + .flatMap(dest -> resolveSamePathIfNeeded(source, dest, isMove)) + .flatMap(dest -> confirmOverwriteIfNeeded(dest).map(ok -> dest)) + .flatMap(dest -> Observable + .fromCallable(() -> { + boolean sourceIsProject = ProjectConfig.isProject(source); + boolean sourceIsDir = source.isDirectory(); + + OperationController controller = new OperationController(); + ProgressDialogSession session = new ProgressDialogSession(controller); + + // For abort handling and refresh. + // zh-CN: 用于中止处理与刷新. + boolean destTouched = false; + + // Timestamp/progress/content state for throttling UI updates. + // zh-CN: 用于节流 UI 更新的时间戳/进度/文本状态. + final long[] lastProgressUpdateTime = new long[]{0L}; + final long[] lastProgressValue = new long[]{-1L}; + final long[] lastContentUpdateTime = new long[]{0L}; + + try { + long totalBytes = computeTotalBytes(source); + + MaterialDialog.Builder progressBuilder = buildCopyProgressDialogBuilder(totalBytes, isMove, sourceIsDir, controller); + + session.scheduleShow(progressBuilder); + + if (isMove) { + destTouched = true; + + moveFileOrDirWithProgress( + source, + dest, + totalBytes, + (copied, total) -> { + controller.throwIfCancelled(); + session.setProgressThrottled(copied, totalBytes, lastProgressUpdateTime, lastProgressValue); + }, + (currentFile) -> { + controller.throwIfCancelled(); + session.setContentThrottled(toContentList(source, dest, currentFile), lastContentUpdateTime); + }, + controller + ); + + notifyFileRemovedAtItsParent(sourceIsProject, sourceIsDir, source); + } else { + destTouched = true; + + copyFileOrDirWithProgress( + source, + dest, + totalBytes, + (copied, total) -> { + controller.throwIfCancelled(); + session.setProgressThrottled(copied, totalBytes, lastProgressUpdateTime, lastProgressValue); + }, + (currentFile) -> { + controller.throwIfCancelled(); + session.setContentThrottled(toContentList(source, dest, currentFile), lastContentUpdateTime); + }, + controller + ); + } + + ScriptFile newFile = new ScriptFile(dest.getPath()); + notifyFileCreatedAtItsParent(ProjectConfig.isProject(newFile), newFile.isDirectory(), newFile); + + GlobalAppContext.post(() -> ViewUtils.showSnack(mView, R.string.text_operation_completed)); + return dest.getPath(); + } catch (OperationAbortedException aborted) { + // Cleanup and refresh when aborted. + // zh-CN: 中止时清理并刷新. + if (destTouched) { + notifyChildrenChangedAtItsParent(new ScriptFile(dest.getPath())); + if (isMove) { + notifyChildrenChangedAtItsParent(source); + } + } + + GlobalAppContext.post(() -> ViewUtils.showSnack(mView, R.string.text_operation_aborted)); + return ""; + } finally { + session.dismissSafely(); + } + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .flatMap(path -> path.isEmpty() ? Observable.empty() : Observable.just(new ScriptFile(path)))); + } + + // Notify Explorer that a directory's children may have changed, using the item's real parent. + // zh-CN: 通知资源管理器某个目录的子项可能发生变化, 使用真实父目录. + private void notifyChildrenChangedAtItsParent(@NonNull ScriptFile file) { + File parent = new File(file.getPath()).getParentFile(); + if (parent == null) { + return; + } + ExplorerDirPage parentPage = new ExplorerDirPage(new ScriptFile(parent.getPath()), null); + runOnMain(() -> mExplorer.notifyChildrenChanged(parentPage)); + } + + // Build a progress dialog builder for copy/move operations. + // zh-CN: 为复制/移动操作构建进度对话框 Builder. + private MaterialDialog.Builder buildCopyProgressDialogBuilder(long totalBytes, boolean isMove, boolean isDir, @NonNull OperationController controller) { + int titleRes = isDir + ? isMove ? R.string.text_move_folder : R.string.text_copy_folder + : isMove ? R.string.text_move_file : R.string.text_copy_file; + + MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext) + .title(titleRes) + .content(R.string.ellipsis_six) + .negativeText(R.string.dialog_button_abort) + .negativeColorRes(R.color.dialog_button_caution) + .onNegative((dialog, which) -> { + controller.cancel(); + try { + dialog.setContent(mContext.getString(R.string.text_aborting)); + } catch (Throwable ignored) { + /* Ignored. */ + } + }) + .cancelable(false) + .canceledOnTouchOutside(false); + + if (totalBytes > 0 && totalBytes <= Integer.MAX_VALUE) { + // Determinate progress in bytes for small/medium files. + // zh-CN: 对于中小文件使用字节级确定性进度. + builder.progress(false, (int) totalBytes, true); + } else if (totalBytes > 0) { + // Determinate progress in scaled units for huge files. + // zh-CN: 对于超大文件使用缩放单位的确定性进度. + builder.progress(false, PROGRESS_MAX_LARGE, true); + } else { + builder.progress(true, 0); + } + return builder; + } + + // Resolve same-path cases before overwrite confirmation and actual copy/move. + // zh-CN: 在覆盖确认与实际复制/移动之前处理源路径与目标路径相同的情况. + private Observable resolveSamePathIfNeeded(@NonNull ScriptFile source, @NonNull File dest, boolean isMove) { + return Observable.fromCallable(() -> { + File srcFile = new File(source.getPath()); + return FileUtils.areSamePath(srcFile, dest); + }) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .flatMap(isSame -> { + if (!isSame) { + return Observable.just(dest); + } + + if (isMove) { + DialogUtils.showAdaptive(new MaterialDialog.Builder(mContext) + .title(R.string.text_prompt) + .content(R.string.text_move_aborted_same_path) + .positiveText(R.string.dialog_button_dismiss) + .build()); + return Observable.empty(); + } + + File parentFile = dest.getParentFile(); + String newName = generateNextIndexedName(parentFile, source.getName(), source.isDirectory()); + String message = mContext.getString(R.string.text_copy_same_path_confirm, newName); + + return confirmWithMessage(message) + .flatMap(yes -> yes + ? Observable.just(new File(parentFile, newName)) + : Observable.empty()); + }); + } + + private Observable confirmWithMessage(@NonNull CharSequence message) { + PublishSubject result = PublishSubject.create(); + DialogUtils.showAdaptive(new MaterialDialog.Builder(mContext) + .title(R.string.text_prompt) + .content(message) + .negativeText(R.string.dialog_button_abandon) + .negativeColorRes(R.color.dialog_button_default) + .onNegative((dialog, which) -> { + result.onNext(false); + result.onComplete(); + }) + .positiveText(R.string.dialog_button_continue) + .positiveColorRes(R.color.dialog_button_attraction) + .onPositive((dialog, which) -> { + result.onNext(true); + result.onComplete(); + }) + .cancelable(false) + .build()); + return result; + } + + // Generate next indexed name by scanning existing "-n" siblings and taking the first missing n from 1. + // zh-CN: 通过扫描同级目录中已有的 "-n" 名称, 从 1 开始取第一个缺失的 n 作为新后缀. + private String generateNextIndexedName(@Nullable File parentDir, @NonNull String originalName, boolean isDirectory) { + String base; + String extWithDot = ""; + + if (!isDirectory) { + int dot = originalName.lastIndexOf('.'); + if (dot > 0 && dot < originalName.length() - 1) { + base = originalName.substring(0, dot); + extWithDot = originalName.substring(dot); + } else { + base = originalName; + } + } else { + base = originalName; + } + + if (parentDir == null) { + long timestamp = System.currentTimeMillis(); + if (isDirectory) { + return base + "-" + timestamp; + } + return base + "-" + timestamp + extWithDot; + } + + Set existingIndexes = new HashSet<>(); + File[] files = parentDir.listFiles(); + if (files != null) { + String pattern; + if (isDirectory) { + pattern = "^" + Pattern.quote(base) + "-(\\d+)$"; + } else { + pattern = "^" + Pattern.quote(base) + "-(\\d+)" + Pattern.quote(extWithDot) + "$"; + } + Pattern p = Pattern.compile(pattern); + + for (File f : files) { + Matcher m = p.matcher(f.getName()); + if (m.matches()) { + try { + String foundIndex = m.group(1); + if (foundIndex == null) { + continue; + } + existingIndexes.add(Integer.parseInt(foundIndex)); + } catch (NumberFormatException ignored) { + /* Ignored. */ + } + } + } + } + + int n = 1; + while (existingIndexes.contains(n)) { + n++; + } + + if (isDirectory) { + return base + "-" + n; + } + return base + "-" + n + extWithDot; + } + + // Compute total bytes of all files under a file or directory. + // zh-CN: 计算文件或目录下所有文件的总字节数. + private long computeTotalBytes(@NonNull File src) { + if (!src.exists()) { + return 0L; + } + if (src.isFile()) { + return Math.max(0L, src.length()); + } + long sum = 0L; + File[] children = src.listFiles(); + if (children == null) { + return 0L; + } + for (File child : children) { + sum += computeTotalBytes(child); + } + return sum; + } + + // Copy file or directory recursively with progress updates and current path callback. + // zh-CN: 带进度更新与当前路径回调的递归复制. + private void copyFileOrDirWithProgress( + @NonNull File src, + @NonNull File dst, + long totalBytes, + @NonNull ProgressCallback callback, + @NonNull FileProgressCallback fileCallback, + @NonNull OperationController controller + ) throws IOException { + controller.throwIfCancelled(); + long[] copied = new long[]{0L}; + copyFileOrDirWithProgressInternal(src, dst, totalBytes, copied, callback, fileCallback, controller); + } + + private void copyFileOrDirWithProgressInternal( + @NonNull File src, + @NonNull File dst, + long totalBytes, + @NonNull long[] copied, + @NonNull ProgressCallback callback, + @NonNull FileProgressCallback pathCallback, + @NonNull OperationController controller + ) throws IOException { + controller.throwIfCancelled(); + + pathCallback.onFile(dst); + + if (src.isDirectory()) { + if (!dst.exists() && !dst.mkdirs()) { + throw new IOException("mkdirs failed: " + dst); + } + File[] children = src.listFiles(); + if (children == null) { + return; + } + for (File child : children) { + copyFileOrDirWithProgressInternal(child, new File(dst, child.getName()), totalBytes, copied, callback, pathCallback, controller); + } + return; + } + + copyFileWithProgressAtomic(src, dst, totalBytes, copied, callback, pathCallback, controller); + } + + // Copy file with an atomic "partial file then rename" strategy, supports abort cleanup. + // zh-CN: 使用 "临时文件写入后再 rename" 的原子复制策略, 支持中止清理. + private void copyFileWithProgressAtomic( + @NonNull File src, + @NonNull File dst, + long totalBytes, + @NonNull long[] copied, + @NonNull ProgressCallback callback, + @NonNull FileProgressCallback pathCallback, + @NonNull OperationController controller + ) throws IOException { + controller.throwIfCancelled(); + + File parent = dst.getParentFile(); + if (parent != null && !parent.exists() && !parent.mkdirs()) { + throw new IOException("mkdirs failed: " + parent); + } + + File partial = new File(dst.getPath() + PARTIAL_COPY_SUFFIX + "." + UUID.randomUUID()); + boolean committed = false; + + try { + try (FileInputStream fis = new FileInputStream(src); + FileOutputStream fos = new FileOutputStream(partial)) { + + byte[] buffer = new byte[256 * 1024]; + int read; + while ((read = fis.read(buffer)) != -1) { + controller.throwIfCancelled(); + + fos.write(buffer, 0, read); + copied[0] += read; + + pathCallback.onFile(dst); + callback.onProgress(copied[0], totalBytes); + } + fos.getFD().sync(); + } + + controller.throwIfCancelled(); + + // Replace destination by rename. + // zh-CN: 通过 rename 替换目标文件. + if (dst.exists() && !dst.delete()) { + throw new IOException("failed to replace destination: " + dst); + } + if (!partial.renameTo(dst)) { + throw new IOException("rename partial to destination failed: " + partial + " -> " + dst); + } + + committed = true; + } catch (OperationAbortedException aborted) { + // Propagate abort to upper layers. + // zh-CN: 将中止异常继续上抛给上层处理. + throw aborted; + } catch (Throwable t) { + if (t instanceof IOException io) { + throw io; + } + throw new IOException(t); + } finally { + if (!committed) { + // Delete partial file on abort/error. + // zh-CN: 中止/出错时删除临时文件. + if (partial.exists() && !partial.delete()) { + Log.w(LOG_TAG, "copyFileWithProgressAtomic: failed to delete partial file: " + partial); + } + } + } + } + + // Move with progress; try rename first, fallback to copy+delete, supports current path callback. + // zh-CN: 带进度的移动; 优先 rename, 失败则 copy+delete, 支持当前路径回调. + private void moveFileOrDirWithProgress( + @NonNull File src, + @NonNull File dst, + long totalBytes, + @NonNull ProgressCallback callback, + @NonNull FileProgressCallback fileCallback, + @NonNull OperationController controller + ) throws IOException { + controller.throwIfCancelled(); + + fileCallback.onFile(dst); + + if (src.renameTo(dst)) { + return; + } + + copyFileOrDirWithProgress(src, dst, totalBytes, callback, fileCallback, controller); + + controller.throwIfCancelled(); + + boolean deleted = deleteRecursivelyWithProgress(src, null, controller); + if (!deleted && src.exists()) { + throw new IOException("Delete after copy failed: " + src); + } + } + + // Delete file or directory recursively with progress; supports cancellation and optional current-path callback. + // zh-CN: 带进度的递归删除; 支持中止, 并支持可选的当前路径回调. + private boolean deleteRecursivelyWithProgress(@NonNull File file, @Nullable FileProgressCallback fileCallback, @NonNull OperationController controller) { + controller.throwIfCancelled(); + + if (fileCallback != null) { + fileCallback.onFile(file); + } + + if (file.isDirectory()) { + File[] children = file.listFiles(); + if (children != null) { + for (File child : children) { + controller.throwIfCancelled(); + if (!deleteRecursivelyWithProgress(child, fileCallback, controller)) { + return false; + } + } + } + } + controller.throwIfCancelled(); + return file.delete(); + } + + private void notifyFileRemovedAtItsParent(boolean isProject, boolean isDir, @NonNull ScriptFile scriptFile) { + ExplorerPage parent = new ExplorerDirPage(new ScriptFile(new File(scriptFile.getPath()).getParent()), null); + runOnMain(() -> { + if (isProject) { + mExplorer.notifyItemRemoved(new ExplorerProjectPage(scriptFile, parent)); + } else if (isDir) { + mExplorer.notifyItemRemoved(new ExplorerDirPage(scriptFile, parent)); + } else { + mExplorer.notifyItemRemoved(new ExplorerFileItem(scriptFile, parent)); + } + }); + } + + private void notifyFileCreatedAtItsParent(boolean isProject, boolean isDir, @NonNull ScriptFile scriptFile) { + ExplorerPage parent = new ExplorerDirPage(new ScriptFile(new File(scriptFile.getPath()).getParent()), null); + runOnMain(() -> { + if (isProject) { + mExplorer.notifyItemCreated(new ExplorerProjectPage(scriptFile, parent)); + } else if (isDir) { + mExplorer.notifyItemCreated(new ExplorerDirPage(scriptFile, parent)); + } else { + mExplorer.notifyItemCreated(new ExplorerFileItem(scriptFile, parent)); + } + }); + } + + private Observable confirmOverwriteIfNeeded(@NonNull File dest) { + if (!dest.exists()) { + return Observable.just(true); + } + int confirmOverwriteRes = dest.isDirectory() + ? R.string.confirm_overwrite_directory + : R.string.confirm_overwrite_file; + return RxDialogs.confirm(mContext, confirmOverwriteRes, R.color.dialog_button_caution) + .flatMap(yes -> { + if (!yes) { + return Observable.empty(); + } + return Observable.fromCallable(() -> { + boolean deleted; + if (dest.isDirectory()) { + deleted = PFiles.deleteRecursively(dest); + } else { + deleted = dest.delete(); + } + if (!deleted && dest.exists()) { + Log.e(LOG_TAG, "confirmOverwriteIfNeeded: delete failed: " + dest); + throw new IOException("Delete failed: " + dest); + } + return true; + }).subscribeOn(Schedulers.io()); + }); + } + + private void notifyFileCreated(ScriptFile scriptFile) { + runOnMain(() -> { + if (scriptFile.isDirectory()) { + mExplorer.notifyItemCreated(new ExplorerDirPage(scriptFile, mExplorerPage)); + } else { + mExplorer.notifyItemCreated(new ExplorerFileItem(scriptFile, mExplorerPage)); + } + }); + } + private void notifyFileChanged(ExplorerFileItem oldItem, ExplorerFileItem newItem) { - mExplorer.notifyItemChanged(oldItem, newItem); + runOnMain(() -> mExplorer.notifyItemChanged(oldItem, newItem)); + } + + private void notifyFileRemoved(boolean isProject, boolean isDir, ScriptFile scriptFile) { + runOnMain(() -> { + if (isProject) { + mExplorer.notifyItemRemoved(new ExplorerProjectPage(scriptFile, mExplorerPage)); + } else if (isDir) { + mExplorer.notifyItemRemoved(new ExplorerDirPage(scriptFile, mExplorerPage)); + } else { + mExplorer.notifyItemRemoved(new ExplorerFileItem(scriptFile, mExplorerPage)); + } + }); } public void createShortcut(ScriptFile file) { @@ -422,15 +990,61 @@ public class ScriptOperations { public void deleteWithoutConfirm(final ScriptFile scriptFile) { boolean isDir = scriptFile.isDirectory(); boolean isProject = ProjectConfig.isProject(scriptFile); - Observable.fromPublisher((Publisher) s -> s.onNext(PFiles.deleteRecursively(scriptFile))) + + int titleRes = isDir ? R.string.text_delete_folder : R.string.text_delete_file; + + Observable.fromCallable(() -> { + OperationController controller = new OperationController(); + ProgressDialogSession session = new ProgressDialogSession(controller); + + final long[] lastContentUpdateTime = new long[]{0L}; + + try { + // For delete, indeterminate progress is acceptable and consistent. + // zh-CN: 删除操作使用不确定进度条即可, 行为更稳定. + MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext) + .title(titleRes) + .content(R.string.ellipsis_six) + .negativeText(R.string.dialog_button_abort) + .negativeColorRes(R.color.dialog_button_caution) + .onNegative((dialog, which) -> { + controller.cancel(); + try { + dialog.setContent(mContext.getString(R.string.text_aborting)); + } catch (Throwable ignored) { + /* Ignored. */ + } + }) + .progress(true, 0) + .progressIndeterminateStyle(true) + .cancelable(false) + .canceledOnTouchOutside(false); + + session.scheduleShow(builder); + + boolean deleted = deleteRecursivelyWithProgress( + scriptFile, + currentFile -> session.setContentThrottled(toContentList(scriptFile, currentFile), lastContentUpdateTime), + controller + ); + + return deleted ? 1 : 0; + } catch (OperationAbortedException aborted) { + return -1; + } finally { + session.dismissSafely(); + } + }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(deleted -> { - if (deleted) { - showMessage(R.string.text_already_deleted); - notifyFileRemoved(isProject, isDir, scriptFile); - } else { - showMessage(R.string.text_failed_to_delete); + switch (deleted) { + case 1 -> { + showMessage(R.string.text_already_deleted); + notifyFileRemoved(isProject, isDir, scriptFile); + } + case 0 -> showMessage(R.string.text_failed_to_delete); + case -1 -> showMessage(R.string.text_operation_aborted); } }); } @@ -441,16 +1055,6 @@ public class ScriptOperations { showMessage(R.string.text_done); } - private void notifyFileRemoved(boolean isProject, boolean isDir, ScriptFile scriptFile) { - if (isProject) { - mExplorer.notifyItemRemoved(new ExplorerProjectPage(scriptFile, mExplorerPage)); - } else if (isDir) { - mExplorer.notifyItemRemoved(new ExplorerDirPage(scriptFile, mExplorerPage)); - } else { - mExplorer.notifyItemRemoved(new ExplorerFileItem(scriptFile, mExplorerPage)); - } - } - public Observable download(String url) { Log.i(LOG_TAG, "dir = " + WorkingDirectoryUtils.getPath() + ", sdcard = " + Environment.getExternalStorageDirectory() + ", url = " + url); String fileName = DownloadManager.parseFileNameLocally(url); @@ -466,14 +1070,13 @@ public class ScriptOperations { } return RxDialogs.confirm(mContext, R.string.confirm_overwrite_file, R.color.dialog_button_caution) .flatMap(yes -> { - if (yes) { - if (!new File(savePath).delete()) { - Log.e(LOG_TAG, "download: delete failed"); - } - return Observable.just(savePath); - } else { + if (!yes) { return Observable.empty(); } + if (!new File(savePath).delete()) { + Log.e(LOG_TAG, "download: delete failed"); + } + return Observable.just(savePath); }); }) .flatMap(savePath -> DownloadManager.getInstance().downloadWithProgress(mContext, url, savePath)) @@ -504,6 +1107,69 @@ public class ScriptOperations { IntentUtils.startSafely(intent, mContext); } + private List toContentList(File src, File current) { + return List.of( + mContext.getString(R.string.text_property_colon_value, mContext.getString(R.string.text_directory), getBriefDirectoryName(src, false)), + mContext.getString(R.string.text_property_colon_value, mContext.getString(R.string.text_name), current.getName()) + ); + } + + private List toContentList(File src, File dst, File current) { + return List.of( + mContext.getString(R.string.text_property_colon_value, mContext.getString(R.string.text_source), getBriefDirectoryName(src, true)), + mContext.getString(R.string.text_property_colon_value, mContext.getString(R.string.text_destination), getBriefDirectoryName(dst, true)), + mContext.getString(R.string.text_property_colon_value, mContext.getString(R.string.text_name), current.getName()) + ); + } + + @NonNull + private String getBriefDirectoryName(@NonNull File file, boolean showDirParent) { + try { + if (file.isDirectory()) { + if (!showDirParent) { + String fullPath = file.getAbsolutePath(); + if (isInternalStorageRoot(fullPath)) { + return mContext.getString(R.string.term_internal_strorage); + } + return file.getName(); + } + + File parent = file.getParentFile(); + if (parent == null) { + return "/" + file.getName(); + } + + String parentPath = parent.getAbsolutePath(); + if (isInternalStorageRoot(parentPath)) { + return mContext.getString(R.string.term_internal_strorage) + "/" + file.getName(); + } + + return parent.getName() + "/" + file.getName(); + } + + File parent = file.getParentFile(); + if (parent == null) { + return "/"; + } + + String parentPath = parent.getAbsolutePath(); + if (isInternalStorageRoot(parentPath)) { + return mContext.getString(R.string.term_internal_strorage); + } + + return parent.getName(); + } catch (Exception e) { + return mContext.getString(R.string.text_unknown); + } + } + + private boolean isInternalStorageRoot(String absPath) { + if (absPath == null) return false; + String p = absPath; + while (p.length() > 1 && p.endsWith("/")) p = p.substring(0, p.length() - 1); + return INTERNAL_STORAGE_ROOT.equals(p); + } + private class InputCallback implements MaterialDialog.InputCallback { private final String mExcluded; @@ -542,4 +1208,190 @@ public class ScriptOperations { } } -} + private static final class ProgressDialogSession { + + private final OperationController controller; + private final AtomicReference dialogRef = new AtomicReference<>(); + + // Whether the session has been closed (operation finished/aborted), used to prevent late dialog showing. + // zh-CN: 会话是否已关闭 (操作已完成/已中止), 用于防止延迟任务在结束后仍弹出对话框. + private final AtomicBoolean closed = new AtomicBoolean(false); + + private final AtomicBoolean showScheduled = new AtomicBoolean(false); + + private volatile boolean shown = false; + + private long shownAtUptimeMs = 0L; + + ProgressDialogSession(OperationController controller) { + this.controller = controller; + } + + void scheduleShow(MaterialDialog.Builder builder) { + if (!showScheduled.compareAndSet(false, true)) { + return; + } + + GlobalAppContext.postDelayed(() -> { + // Skip showing if operation already finished/aborted. + // zh-CN: 若操作已结束/已中止, 则不再显示对话框. + if (closed.get() || controller.cancelled.get()) { + return; + } + + MaterialDialog dialog = DialogUtils.buildAndShowAdaptive(builder::build); + dialog.setProgressNumberFormat("..."); + DialogUtils.applyProgressThemeColorTintLists(dialog); + + // If closed becomes true right after building, dismiss immediately to avoid dangling dialog. + // zh-CN: 若 build 后立刻变为 closed, 则立即关闭, 避免对话框悬挂. + if (closed.get()) { + try { + if (dialog.isShowing()) { + dialog.dismiss(); + } + } catch (Throwable ignored) { + /* Ignored. */ + } + return; + } + + dialogRef.set(dialog); + shown = true; + shownAtUptimeMs = SystemClock.uptimeMillis(); + }, PROGRESS_DIALOG_SHOW_DELAY_MS); + } + + void setContentThrottled(List contentList, long[] lastUpdateTime) { + long now = SystemClock.uptimeMillis(); + + if (now - lastUpdateTime[0] < PROGRESS_UPDATE_MIN_INTERVAL_MS) { + return; + } + + lastUpdateTime[0] = now; + + MaterialDialog dialog = dialogRef.get(); + if (dialog == null) { + return; + } + GlobalAppContext.post(() -> { + try { + TextView contentView = dialog.getContentView(); + if (contentView != null) { + ViewUtils.setLinesEllipsizedIndividually(contentView, contentList, 1.5f); + } + } catch (Throwable ignored) { + /* Ignored. */ + } + }); + } + + void setProgressThrottled(long progress, long totalBytes, long[] lastUpdateTime, long[] lastProgress) { + long now = SystemClock.uptimeMillis(); + + if (progress == lastProgress[0]) { + return; + } + if (now - lastUpdateTime[0] < PROGRESS_UPDATE_MIN_INTERVAL_MS) { + return; + } + + lastUpdateTime[0] = now; + lastProgress[0] = progress; + + MaterialDialog dialog = dialogRef.get(); + if (dialog == null) { + return; + } + GlobalAppContext.post(() -> { + try { + DialogUtils.setProgressNumberFormatByBytes(dialog, progress, totalBytes, true); + + int v; + int max; + + if (totalBytes > 0 && totalBytes <= Integer.MAX_VALUE) { + max = (int) totalBytes; + v = (int) Math.max(0L, Math.min(progress, max)); + } else if (totalBytes > 0) { + max = PROGRESS_MAX_LARGE; + double ratio = (double) progress / (double) totalBytes; + v = (int) Math.round(ratio * (double) max); + v = Math.max(0, Math.min(max, v)); + } else { + // No total bytes, keep indeterminate behavior. + // zh-CN: 无总字节数, 保持不确定进度行为. + return; + } + + dialog.setMaxProgress(max); + dialog.setProgress(v); + } catch (Throwable ignored) { + /* Ignored. */ + } + }); + } + + void dismissSafely() { + // Mark closed first so delayed show won't create a dialog after completion. + // zh-CN: 先标记 closed, 防止延迟 show 在完成后创建对话框. + closed.set(true); + + MaterialDialog dialog = dialogRef.get(); + if (dialog == null) { + return; + } + + long now = SystemClock.uptimeMillis(); + long delay = 0L; + + if (shown) { + long shownDuration = now - shownAtUptimeMs; + if (shownDuration < PROGRESS_DIALOG_MIN_SHOW_MS) { + delay = PROGRESS_DIALOG_MIN_SHOW_MS - shownDuration; + } + } + + GlobalAppContext.postDelayed(() -> { + try { + if (dialog.isShowing()) { + dialog.dismiss(); + } + } catch (Throwable ignored) { + /* Ignored. */ + } + }, delay); + } + } + + // Controller for cancellable operations (copy/move/delete). + // zh-CN: 用于可取消操作 (复制/移动/删除) 的控制器. + private static final class OperationController { + final AtomicBoolean cancelled = new AtomicBoolean(false); + + void cancel() { + cancelled.set(true); + } + + void throwIfCancelled() { + if (cancelled.get()) { + throw new OperationAbortedException(); + } + } + } + + private static final class OperationAbortedException extends RuntimeException { + OperationAbortedException() { + super("Operation aborted"); + } + } + + private interface FileProgressCallback { + void onFile(@NonNull File currentFile); + } + + private interface ProgressCallback { + void onProgress(long copiedBytes, long totalBytes); + } +} \ No newline at end of file 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 3189351a..c7a80389 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 @@ -30,7 +30,6 @@ import org.autojs.autojs.core.pref.Pref.putInt import org.autojs.autojs.core.pref.Pref.putLinkedList import org.autojs.autojs.core.pref.Pref.putString import org.autojs.autojs.core.pref.Pref.remove -import org.autojs.autojs.util.ViewUtils.setForceShowIconCompat import org.autojs.autojs.model.explorer.Explorer import org.autojs.autojs.model.explorer.ExplorerChangeEvent import org.autojs.autojs.model.explorer.ExplorerDirPage @@ -65,6 +64,7 @@ import org.autojs.autojs.util.ColorUtils import org.autojs.autojs.util.EnvironmentUtils.externalStoragePath import org.autojs.autojs.util.FileUtils import org.autojs.autojs.util.Observers +import org.autojs.autojs.util.ViewUtils.setForceShowIconCompat import org.autojs.autojs.util.ViewUtils.showSnack import org.autojs.autojs.util.WorkingDirectoryUtils import org.autojs.autojs.util.WorkingDirectoryUtils.path @@ -76,14 +76,16 @@ import org.autojs.autojs6.databinding.ExplorerFirstCharIconBinding import org.autojs.autojs6.databinding.ExplorerViewBinding import org.greenrobot.eventbus.Subscribe import java.io.File -import java.util.* +import java.util.LinkedList +import java.util.Objects +import java.util.Stack import java.util.concurrent.Callable /** * Created by Stardust on Aug 21, 2017. * Transformed by SuperMonster003 on Nov 23, 2024. * Modified by JetBrains AI Assistant (GPT-5.2) as of Apr 20, 2026. - * Modified by SuperMonster003 as of Apr 20, 2026. + * Modified by SuperMonster003 as of Feb 2, 2026. */ @SuppressLint("CheckResult", "NonConstantResourceId", "NotifyDataSetChanged") open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRefreshListener, PopupMenu.OnMenuItemClickListener { @@ -253,35 +255,45 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef override fun onMenuItemClick(item: MenuItem): Boolean { when (item.itemId) { - R.id.rename -> { + R.id.action_move_to -> { + ScriptOperations(context, this@ExplorerView, currentPage) + .move(selectedItem!!.toScriptFile()) + .subscribe(Observers.emptyObserver()) + } + R.id.action_copy_to -> { + ScriptOperations(context, this@ExplorerView, currentPage) + .copy(selectedItem!!.toScriptFile()) + .subscribe(Observers.emptyObserver()) + } + R.id.action_rename -> { ScriptOperations(context, this@ExplorerView, currentPage) .rename(selectedItem as ExplorerFileItem?) .subscribe(Observers.emptyObserver()) } - R.id.delete -> { + R.id.action_delete -> { ScriptOperations(context, this@ExplorerView, currentPage) .delete(selectedItem!!.toScriptFile()) } - R.id.run_repeatedly -> { + R.id.action_run_repeatedly -> { ScriptLoopDialog(context, selectedItem!!.toScriptFile()) .show() notifyItemOperated() } - R.id.create_shortcut -> { + R.id.action_create_shortcut -> { ScriptOperations(context, this@ExplorerView, currentPage) .createShortcut(selectedItem!!.toScriptFile()) mRequestHostDialogHide?.run() } - R.id.open_by_other_apps -> { + R.id.action_open_by_other_apps -> { Scripts.openByOtherApps(selectedItem!!.toScriptFile()) notifyItemOperated() } - R.id.send -> { + R.id.action_send -> { Scripts.send(context, selectedItem!!.toScriptFile()) notifyItemOperated() mRequestHostDialogHide?.run() } - R.id.timed_task -> { + R.id.action_timed_task -> { ScriptOperations(context, this@ExplorerView, currentPage) .timedTask(selectedItem!!.toScriptFile()) notifyItemOperated() @@ -292,7 +304,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef notifyItemOperated() mRequestHostDialogHide?.run() } - R.id.reset -> { + R.id.action_reset -> { val o = Explorers.Providers.workspace() .resetSample(selectedItem!!.toScriptFile()) if (o == null) { @@ -757,7 +769,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef setTextWith(mName) { ExplorerViewHelper.getDisplayName(context, item) } setTextWith(mFileDate) { PFile.getFullDateString(item.lastModified()) } - setTextWith(mFileSize) { PFiles.getHumanReadableSize(item.size) } + setTextWith(mFileSize) { PFiles.formatSizeWithUnit(item.size) } Observable.fromCallable { val shouldEditShow = item.isTextEditable || item.isExternalEditable @@ -947,15 +959,21 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef popupMenu.inflate(R.menu.menu_script_options) val menu = popupMenu.menu if (!mExplorerItem.isExecutable) { - menu.removeItem(R.id.create_shortcut) - menu.removeItem(R.id.timed_task) - menu.removeItem(R.id.run_repeatedly) + menu.removeItem(R.id.action_create_shortcut) + menu.removeItem(R.id.action_timed_task) + menu.removeItem(R.id.action_run_repeatedly) } - if (!mExplorerItem.canDelete()) { - menu.removeItem(R.id.delete) + if (!mExplorerItem.canMove()) { + menu.removeItem(R.id.action_move_to) + } + if (!mExplorerItem.canCopy()) { + menu.removeItem(R.id.action_copy_to) } if (!mExplorerItem.canRename()) { - menu.removeItem(R.id.rename) + menu.removeItem(R.id.action_rename) + } + if (!mExplorerItem.canDelete()) { + menu.removeItem(R.id.action_delete) } if (!mExplorerItem.canBuildApk()) { menu.removeItem(R.id.action_build_apk) @@ -965,7 +983,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef } val samplePath = PFile(context.filesDir, WorkspaceFileProvider.SAMPLE_PATH).path if (!mExplorerItem.path.startsWith(samplePath)) { - menu.removeItem(R.id.reset) + menu.removeItem(R.id.action_reset) } popupMenu.setOnMenuItemClickListener(this@ExplorerView) popupMenu.show() @@ -1012,47 +1030,61 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef } private fun showOptionsMenu() { + val explorerPage = mExplorerPage ?: return val popupMenu = PopupMenu(context, mOptions) val menu = popupMenu.menu popupMenu.inflate(R.menu.menu_dir_options) - if (!mExplorerPage!!.canRename()) { + if (!explorerPage.canMove()) { + menu.removeItem(R.id.action_move_to) + } + if (!explorerPage.canCopy()) { + menu.removeItem(R.id.action_copy_to) + } + if (!explorerPage.canRename()) { menu.removeItem(R.id.action_rename) } - if (!mExplorerPage!!.canDelete()) { + if (!explorerPage.canDelete()) { menu.removeItem(R.id.action_delete) } - if (!mExplorerPage!!.canSetAsWorkingDir()) { + if (!explorerPage.canSetAsWorkingDir()) { menu.removeItem(R.id.action_set_as_working_dir) } - if (!mExplorerPage!!.canBuildApk()) { + if (!explorerPage.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) + if (!explorerPage.path.startsWith(samplePath)) { + menu.removeItem(R.id.action_reset) } popupMenu.setOnMenuItemClickListener { item: MenuItem -> + val selectedItem = selectedItem ?: return@setOnMenuItemClickListener false + val explorerView = this@ExplorerView when (item.itemId) { - R.id.action_rename -> { - ScriptOperations(context, this@ExplorerView, currentPage) - .rename(selectedItem as ExplorerFileItem?) + R.id.action_copy_to -> + ScriptOperations(context, explorerView, currentPage) + .copy(selectedItem.toScriptFile()) .subscribe(Observers.emptyObserver()) - } - R.id.action_delete -> { - ScriptOperations(context, this@ExplorerView, currentPage) - .delete(selectedItem!!.toScriptFile()) - } - R.id.action_set_as_working_dir -> { - ScriptOperations(context, this@ExplorerView, currentPage) - .setAsWorkingDir(selectedItem!!.toScriptFile()) - } + R.id.action_move_to -> + ScriptOperations(context, explorerView, currentPage) + .move(selectedItem.toScriptFile()) + .subscribe(Observers.emptyObserver()) + R.id.action_rename -> + ScriptOperations(context, explorerView, currentPage) + .rename(selectedItem as? ExplorerFileItem) + .subscribe(Observers.emptyObserver()) + R.id.action_delete -> + ScriptOperations(context, explorerView, currentPage) + .delete(selectedItem.toScriptFile()) + R.id.action_set_as_working_dir -> + ScriptOperations(context, explorerView, currentPage) + .setAsWorkingDir(selectedItem.toScriptFile()) R.id.action_build_apk -> { mRequestHostDialogHide?.run() - BuildActivity.launch(context, selectedItem!!.path) + BuildActivity.launch(context, selectedItem.path) } - R.id.reset -> { + R.id.action_reset -> { val o = Explorers.Providers.workspace() - .resetSample(selectedItem!!.toScriptFile()) + .resetSample(selectedItem.toScriptFile()) if (o == null) { resetFailed() } else { @@ -1148,7 +1180,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") override fun bind(isDirCategory: Any, position: Int) { if (isDirCategory !is Boolean) return - val titleRes = if (isDirCategory) R.string.text_directory else R.string.text_file + val titleRes = if (isDirCategory) R.string.text_folder else R.string.text_file val count = if (isDirCategory) explorerItemManager.groupCount() else explorerItemManager.itemCount() binding.title.text = "${context.getString(titleRes)} [ $count ]" mIsDir = isDirCategory diff --git a/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java b/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java index 48cff871..bfbe8a1b 100644 --- a/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java +++ b/app/src/main/java/org/autojs/autojs/ui/filechooser/ExplorerItemViewHolder.java @@ -1,17 +1,13 @@ package org.autojs.autojs.ui.filechooser; import android.content.Context; -import android.content.res.ColorStateList; import android.view.View; - import androidx.annotation.NonNull; - import org.autojs.autojs.core.ui.widget.JsCheckBox; import org.autojs.autojs.model.explorer.ExplorerItem; import org.autojs.autojs.pio.PFile; import org.autojs.autojs.pio.PFiles; import org.autojs.autojs.theme.ThemeColorHelper; -import org.autojs.autojs.theme.ThemeColorManagerCompat; import org.autojs.autojs.ui.explorer.ExplorerViewHelper; import org.autojs.autojs.ui.widget.BindableViewHolder; import org.autojs.autojs.util.ColorUtils; @@ -59,7 +55,7 @@ class ExplorerItemViewHolder extends BindableViewHolder { fileChooseListView.getSelectedFiles().remove(mExplorerItem.toScriptFile()); } }); - listFileBinding.scriptFileSize.setText(PFiles.getHumanReadableSize(explorerItem.getSize())); + listFileBinding.scriptFileSize.setText(PFiles.formatSizeWithUnit(explorerItem.getSize())); listFileBinding.scriptFileDate.setText(PFile.getFullDateString(explorerItem.lastModified())); switch (explorerItem.getType()) { diff --git a/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java b/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java index f7879f5a..a5589807 100644 --- a/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java +++ b/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java @@ -73,7 +73,8 @@ public class FileChooserDialogBuilder extends MaterialDialog.Builder { @Override public MaterialDialog show() { - return DialogUtils.adaptToExplorer(super.show(), mFileChooseListView); + MaterialDialog dialog = DialogUtils.showAdaptive(this); + return DialogUtils.adaptToExplorer(dialog, mFileChooseListView); } public FileChooserDialogBuilder dir(String rootDir, String initialDir) { diff --git a/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenu.java b/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenu.java index 9b4f5af4..1c9ec9ee 100644 --- a/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenu.java +++ b/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenu.java @@ -203,7 +203,7 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { // zh-CN: 需要时恢复宿主对话框 (overlay), 并保留状态. mScriptListDialogExplorerView.setRequestHostDialogShow(() -> { if (!scriptListDialog.isShowing()) { - DialogUtils.showDialog(scriptListDialog); + DialogUtils.showAdaptive(scriptListDialog); } }); diff --git a/app/src/main/java/org/autojs/autojs/ui/main/FloatingActionMenu.java b/app/src/main/java/org/autojs/autojs/ui/main/FloatingActionMenu.java index 189f507e..8c288276 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/FloatingActionMenu.java +++ b/app/src/main/java/org/autojs/autojs/ui/main/FloatingActionMenu.java @@ -37,7 +37,7 @@ public class FloatingActionMenu extends FrameLayout implements View.OnClickListe R.drawable.ic_project_white}; private static final int[] LABELS = { - R.string.text_directory, + R.string.text_folder, R.string.text_file, R.string.text_import, R.string.text_project}; diff --git a/app/src/main/java/org/autojs/autojs/ui/main/scripts/ApkInfoDialogManager.kt b/app/src/main/java/org/autojs/autojs/ui/main/scripts/ApkInfoDialogManager.kt index 7a89dedb..40626336 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/scripts/ApkInfoDialogManager.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/scripts/ApkInfoDialogManager.kt @@ -138,7 +138,7 @@ object ApkInfoDialogManager { dialog.setCopyableTextIfAbsent(binding.packageNameValue, packageName) dialog.setCopyableTextIfAbsent(binding.deviceSdkValue, "${Build.VERSION.SDK_INT}") - dialog.setCopyableTextIfAbsent(binding.fileSizeValue, this) { PFiles.getHumanReadableSize(apkFile.length()) } + dialog.setCopyableTextIfAbsent(binding.fileSizeValue, this) { PFiles.formatSizeWithUnit(apkFile.length()) } dialog.setCopyableTextIfAbsent(binding.signatureSchemeValue, this) { getApkSignatureInfo(apkFile) } withContext(Dispatchers.Main) { diff --git a/app/src/main/java/org/autojs/autojs/ui/main/scripts/EditableFileInfoDialogManager.kt b/app/src/main/java/org/autojs/autojs/ui/main/scripts/EditableFileInfoDialogManager.kt index a96aa95f..165c4ce8 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/scripts/EditableFileInfoDialogManager.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/scripts/EditableFileInfoDialogManager.kt @@ -91,7 +91,7 @@ object EditableFileInfoDialogManager { setCopyableTextIfAbsent(binding.lineCountValue, textUnknown) setCopyableTextIfAbsent(binding.charCountValue, textUnknown) setCopyableTextIfAbsent(binding.lineBreakValue, textUnknown) - setCopyableTextIfAbsent(binding.fileSizeValue, scope) { PFiles.getHumanReadableSize(file.length()) } + setCopyableTextIfAbsent(binding.fileSizeValue, scope) { PFiles.formatSizeWithUnit(file.length()) } } else -> dialog.apply { val charsetMatch = StringUtils.detectCharset(bytes) @@ -166,7 +166,7 @@ object EditableFileInfoDialogManager { private fun getReadableSizeString(context: Context, charset: Charset, bytes: ByteArray, text: String): Pair { val (size, suffix) = getByteCount(context, charset, bytes, text) - return PFiles.getHumanReadableSize(size) to suffix + return PFiles.formatSizeWithUnit(size) to suffix } private fun getByteCountString(context: Context, charset: Charset, bytes: ByteArray, text: String): Pair { diff --git a/app/src/main/java/org/autojs/autojs/util/FileUtils.kt b/app/src/main/java/org/autojs/autojs/util/FileUtils.kt index d3a7928d..ec19d7d3 100644 --- a/app/src/main/java/org/autojs/autojs/util/FileUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/FileUtils.kt @@ -114,6 +114,12 @@ object FileUtils { return false } + @JvmStatic + fun areSamePath(a: File, b: File): Boolean = + runCatching { + a.getCanonicalPath() == b.getCanonicalPath() + }.getOrNull() ?: (a.absolutePath == b.absolutePath) + suspend fun Uri.toCacheFile( context: Context, subDir: String = "from_uri", @@ -3384,5 +3390,4 @@ object FileUtils { ) { val isLikelyApk = isZipReadable && hasAndroidManifest && (hasClassesDex || hasResourcesArsc || hasResDir) } - -} +} \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/util/ThreadUtils.java b/app/src/main/java/org/autojs/autojs/util/ThreadUtils.java index 8a7a6192..59da3f0d 100644 --- a/app/src/main/java/org/autojs/autojs/util/ThreadUtils.java +++ b/app/src/main/java/org/autojs/autojs/util/ThreadUtils.java @@ -1,5 +1,9 @@ package org.autojs.autojs.util; +import android.os.Handler; +import androidx.annotation.NonNull; +import org.autojs.autojs.app.GlobalAppContext; + import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -9,8 +13,11 @@ import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; +import static org.autojs.autojs.util.RhinoUtils.isMainThread; + /** * Created by SuperMonster003 on May 26, 2022. + * Modified by SuperMonster003 as of Feb 2, 2026. */ public class ThreadUtils { @@ -49,4 +56,20 @@ public class ThreadUtils { future.cancel(true); return result.get(); } -} + + public static void runOnMain(Handler handler, @NonNull Runnable r) { + if (isMainThread()) { + r.run(); + return; + } + handler.post(r); + } + + public static void runOnMain(@NonNull Runnable r) { + if (isMainThread()) { + r.run(); + return; + } + GlobalAppContext.post(r); + } +} \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/util/ViewUtils.kt b/app/src/main/java/org/autojs/autojs/util/ViewUtils.kt index fccffd3e..6eefa19f 100644 --- a/app/src/main/java/org/autojs/autojs/util/ViewUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/ViewUtils.kt @@ -75,10 +75,11 @@ import org.autojs.autojs6.R import kotlin.math.floor import kotlin.math.min import kotlin.math.roundToInt +import android.text.TextUtils as AndroidTextUtils /** * Created by Stardust on Jan 24, 2017. - * Modified by SuperMonster003 as of Sep 11, 2022. + * Modified by SuperMonster003 as of Feb 2, 2026. */ @Suppress("unused") object ViewUtils { @@ -1323,6 +1324,37 @@ object ViewUtils { } } + @JvmStatic + @JvmOverloads + fun TextView.setLinesEllipsizedIndividually( + lines: List, + lineSpacing: Float = 0f, + where: AndroidTextUtils.TruncateAt = AndroidTextUtils.TruncateAt.MIDDLE + ) { + post { + val avail = width - paddingLeft - paddingRight + if (avail <= 0) { + post { setLinesEllipsizedIndividually(lines, lineSpacing, where) } + return@post + } + + setLineSpacing(0f, lineSpacing) + + val out = buildString { + lines.forEachIndexed { idx, s -> + val e = AndroidTextUtils.ellipsize(s, paint, avail.toFloat(), where) + if (idx > 0) append('\n') + append(e) + } + } + + setSingleLine(false) + ellipsize = null + + text = out + } + } + enum class MODE(val key: String) { DAY(key(R.string.key_night_mode_always_off)), @@ -1345,9 +1377,7 @@ object ViewUtils { private fun dysfunction() { isAutoNightModeEnabled = false } - } - } @SuppressLint("ClickableViewAccessibility") @@ -1370,7 +1400,6 @@ object ViewUtils { } } } - } private class TextSizeScaleListener(private val textView: TextView) : ScaleGestureDetector.SimpleOnScaleGestureListener() { @@ -1406,7 +1435,5 @@ object ViewUtils { } fun getTextSize(): Float = DisplayUtils.pxToSp(textView.textSize) - } - } \ No newline at end of file diff --git a/app/src/main/res/layout/explorer_category.xml b/app/src/main/res/layout/explorer_category.xml index 71d0da06..7d2c2ea1 100644 --- a/app/src/main/res/layout/explorer_category.xml +++ b/app/src/main/res/layout/explorer_category.xml @@ -32,8 +32,10 @@ android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="center_vertical" - android:text="@string/text_directory" + android:ellipsize="middle" + android:gravity="center_vertical" + android:maxLines="1" + android:text="@string/text_folder" android:textColor="@color/explorer_category_operation_button" android:textSize="13sp" /> diff --git a/app/src/main/res/layout/explorer_directory.xml b/app/src/main/res/layout/explorer_directory.xml index 35bb538b..b4b640d5 100644 --- a/app/src/main/res/layout/explorer_directory.xml +++ b/app/src/main/res/layout/explorer_directory.xml @@ -1,73 +1,74 @@ - + + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:paddingTop="9dp" + android:paddingBottom="9dp"> + android:id="@+id/icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="center_vertical" + android:layout_marginHorizontal="16dp" /> + + + android:id="@+id/name" + android:ellipsize="middle" + android:gravity="center_vertical" + android:maxLines="1" + android:textColor="?android:textColorPrimary" + android:textSize="14sp" + tools:text="@string/text_sample_name" /> - - + android:id="@+id/script_dir_date" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:ellipsize="end" + android:maxLines="1" + android:textColor="?android:textColorSecondary" + android:textSize="11sp" + tools:text="@string/text_sample_file_date" /> + android:id="@+id/more" + android:layout_width="52dp" + android:layout_height="20dp" + android:layout_gravity="center_vertical" + android:background="?selectableItemBackgroundBorderless" + android:clickable="true" + android:focusable="true" + android:paddingHorizontal="16dp" + android:src="@drawable/ic_more_vert_black_24dp" + app:tint="#A9AAAB" /> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_dir_options.xml b/app/src/main/res/menu/menu_dir_options.xml index 24ff0d7c..50e63892 100644 --- a/app/src/main/res/menu/menu_dir_options.xml +++ b/app/src/main/res/menu/menu_dir_options.xml @@ -2,6 +2,12 @@ + + @@ -15,7 +21,7 @@ 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 c6ae3164..a28ec36a 100644 --- a/app/src/main/res/menu/menu_script_options.xml +++ b/app/src/main/res/menu/menu_script_options.xml @@ -3,31 +3,37 @@ xmlns:android="http://schemas.android.com/apk/res/android"> + + \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 44739036..0fb1ec34 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -7,7 +7,6 @@ - مبنى... تنظيف... التغليف ... @@ -52,7 +51,8 @@ تحتوي الإعدادات \"abi\" على خيارات غير متاحة تحتوي الإعدادات \"lib\" على خيارات غير صالحة تحتوي الإعدادات \"lib\" على خيارات غير متاحة - ملف موجود بالفعل.\nالكتابة فوق؟ + المجلد موجود بالفعل. هل تريد الاستبدال? + الملف موجود بالفعل. هل تريد الاستبدال? 1. اضغط مع الاستمرار على اسم التطبيق (AutoJs6) في الصفحة الرئيسية للانتقال إلى صفحة الإعدادات\n2. اضغط مع الاستمرار على خيار إعدادات معين في صفحة الإعدادات لعرض معلومات مفصلة اللون الحالي للثيم %1$s مُعد بواسطة لوحة الألوان زر عائم لعرض المحتوي الفعلي @@ -96,12 +96,14 @@ ينطبق الوضع الليلي (المعروف أيضًا باسم Dark theme) على كل من واجهة مستخدم نظام Android والتطبيقات التي تعمل على الجهاز ، مما يحسن الرؤية للمستخدمين ضعاف البصر وأولئك الذين لديهم حساسية للضوء الساطع ، ويسهل على أي شخص استخدام الجهاز. في بيئة الإضاءة المنخفضة.\n\nنظام المتابعة: يحتوي AutoJs6 على إعدادات الوضع الليلي مثل نظام Android\nيعمل دائمًا: يحافظ AutoJs6 على تشغيل الوضع الليلي (بغض النظر عن إعدادات نظام Android)\nإيقاف التشغيل دائمًا: يقوم AutoJs6 بإيقاف تشغيل الوضع الليلي (بغض النظر عن إعدادات نظام Android)\n\nملاحظة: خيار متابعة النظام متاح فقط لـ Android API Level 28 (Android 9) [P] وما فوق. لتمكين الوضع الليلي في نظام Android:\n- Android API المستوى 29 (Android 10) [Q] وما فوق: الإعدادات -> العرض -> المظهر.\n- Android API المستوى 28 (Android 9) [P]: خيارات المطور -> الوضع الليلي.\n\nيجب استيفاء الشروط التالية لتطبيق الوضع الليلي (المظهر الداكن) على المحتوى المستند إلى الويب باستخدام مكون WebView (مثل صفحة وثائق AutoJs6):\n1.عرض ويب نظام Android (أو متصفحات مثل Google Chrome):\n- Android API المستوى 29 (Android 10) [Q] وما فوق: الإصدار> = 76\n- مستوى واجهة برمجة تطبيقات Android 28 (Android 9) [P]: الإصدار> = 105\n2. تم تكييف المحتوى المستند إلى الويب في مكون WebView مع المظهر الداكن (عن طريق موارد CSS أو Android XML وما إلى ذلك) يسمح إذن \"الوصول إلى الإشعارات\" (أو \"إذن قراءة الإشعارات\") لـ AutoJs6 بقراءة محتوى إشعارات النظام، مما يتيح للسكربتات الاستماع إلى الإشعارات أو الحصول على نص الإشعار وما إلى ذلك. + \"موقع المؤشر\" هي ميزة تصحيح أخطاء ضمن خيارات المطوّر في Android.\nعند تفعيلها، يعرض النظام على الشاشة معلومات نقاط اللمس مثل [الإحداثيات/مسار الحركة/العدد/الحجم/سرعة الحركة/الضغط]، مما يسهل [كتابة/تصحيح/التحقق من] السكربتات ذات الصلة. يسمح إذن \"إرسال الإشعارات\" لـ AutoJs6 بنشر الإشعارات على النظام، مما يتيح للسكربتات نشر وإدارة إشعارات مخصّصة في شريط الإشعارات.\n\nNote: على أجهزة Android 13+، إذا لم يتم منح هذا الإذن فقد لا تظهر بعض الإشعارات، وقد يؤثر ذلك على تشغيل خدمات المقدمة واستقرارها. مع الوصول إلى وسائط المشروع ، لن يطلب منك التحذير الأمني لتسجيل الشاشة. تؤثر استراتيجية إعادة التشغيل فقط في زر إعادة التشغيل في درج الصفحة الرئيسية.\n\nإعادة تشغيل سريعة: تعيد تشغيل التطبيق بسرعة. إذا فشلت عملية إعادة التشغيل أو حدثت حالات غير متوقعة، جرّب التبديل إلى \"إعادة تشغيل مجدولة\".\nإعادة تشغيل مجدولة: تُعدّ مسبقًا مهمة مؤقتة قصيرة. بعد إيقاف التطبيق، سيبدأ مرة أخرى وفق الجدول لتنفيذ إعادة التشغيل. عند تفعيل المفتاح (الوضع الافتراضي): سيتم تغليف القيم المُعادة من أساليب Java من الأنواع Number/Boolean/Character ككائنات Java وإتاحتها للسكريبت (باستثناء String). ستكون typeof هي \"object\" و species هي \"JavaObject\"، ويمكن استدعاء أساليب Java، مما يساعد على الحفاظ على خصائص الأنواع الدقيقة في Java وحل زيادة التحميل (overload).\n\nعند إيقاف المفتاح: لن تُغلف الأنواع المذكورة، وستُعرض مباشرة كقيم أولية في JavaScript (number/boolean/سلسلة ذات حرف واحد). ستكون typeof هي نوع JavaScript الموافق، وهو أقرب لدلالات ونظام JavaScript البيئي. لا يزال بالإمكان إعلان مغلّف Java صراحةً باستخدام new، مثل new java.lang.Boolean(true).\n\nانظر: http://issues.autojs6.com/435 إذا كان لديك جذر غريب أو حالة غير طبيعية للوصول إلى الجذر ، فيمكنك إجبار الجذر على الجذر أو غير الجذر. النوع الثنائي: غير قابل للتحرير ، بامتداد الملف \"تلقائي\"\nنوع جافا سكريبت: يمكن تحريره أو نسخه مباشرة بامتداد الملف \"js\" + عند طلب إذن التقاط الشاشة، قد تحتوي نافذة طلب الإذن المنبثقة على حركة تلاشي عند اختفائها. إذا تم استدعاء `images.captureScreen` مباشرةً، فقد تتضمن لقطة الشاشة الناتجة محتوى نافذة طلب الإذن مما يسبب حجبًا.\n\nتضيف قيمة هذا الخيار مدة تأخير (بالمللي ثانية) قبل التقاط الشاشة مباشرةً بعد الحصول على الإذن، وذلك لتجنب مشكلة الحجب المذكورة أعلاه.\n\nينطبق هذا الخيار فقط على أول عملية التقاط بعد الحصول على الإذن؛ أما عمليات الالتقاط اللاحقة فلن تتأثر بهذه القيمة. يُستخدم وضع الخادم لتمكين AutoJs6 من تشغيل خدمة على الجهاز الحالي والانتظار لاتصالات عملاء خارجيين لتنفيذ [ نقل السكربتات / طباعة السجلات / التحكم عن بُعد ].\n\nيدعم وضع الخادم في AutoJs6 طريقتين للاتصال:\n1. الشبكة المحلية (LAN)\n2. Android Debug Bridge (ADB) يتيح Shizuku استخدام واجهة برمجة تطبيقات النظام مع امتيازات ADB يجعل الوضع المستقر أكثر استقرارًا عند الحصول على حدود تخطيط ، ولكن قد يتم تجاهل بعض النتائج.\nإعادة تشغيل خدمة الوصول المطلوبة. @@ -113,6 +115,8 @@ إعدادات النظام الآمنة ، التي تحتوي على تفضيلات النظام التي يمكن أن تقرأها التطبيقات ولكن لا يُسمح لها بالكتابة.\nهذه هي لتفضيلات يجب على المستخدم تعديلها بشكل صريح من خلال واجهة المستخدم لتطبيق النظام.\nمع إذن إعدادات النظام الآمن ، يمكن للتطبيقات العادية تعديل الإعدادات الآمنة مباشرة (مثل خدمة إمكانية الوصول). يسمح إذن \"تعديل إعدادات النظام\" لـ AutoJs6 بتعديل بعض إعدادات النظام، مما يتيح للسكربتات تعديل إعدادات مثل [ سطوع الشاشة / التدوير التلقائي / مهلة إيقاف الشاشة ]. تخلَّ + إيقاف + إيقاف الاتصال متقدم تصحيح العنوان @string/text_back @@ -130,10 +134,11 @@ تفاصيل معلومات الملف تاريخ + الصفحة الرئيسية يتجاهل - إيقاف الاتصال إنضم للمجموعة المدير + تصغير أكثر فتح لوحة الألوان يترك @@ -193,6 +198,7 @@ تم التخلي عن الأسلوب %s ويجب عدم استخدامه يتعذر إكمال العملية \"%1$s\" لأن المعلمة تحتوي على قيم إحداثيات سالبة (%2$d, %3$d) تتطلب عملية تنفيذ واجهة المستخدم نشاطًا يمكن توفيره من خلال وضع التنفيذ \"ui\" + حدث خطأ لم يتم تنفيذ العملية التطبيق غير مثبت التطبيق غير مثبت: \"%s\" @@ -231,8 +237,10 @@ الارتفاع الزائد: القالب [%1$d] > المنطقة [%2$d] العرض الزائد: القالب [%1$d] > المنطقة [%2$d] فشل في تطبيق سجل اللون الحالي + تعذّر ربط خدمة المكوّن الإضافي %1$s. فشل استدعاء الأسلوب \"%s\" + تعذّر تغيير حالة المفتاح فشل تحويل القيمة %s إلى قابل للرسم فشل فتح صفحة الإعدادات فشل منح Shizuku حق الوصول @@ -276,6 +284,7 @@ قد لا يكون لدى AutoJs6 ملف الجذر لتشغيل ملف \"auto\" %s() دعا مع الوسيطة الفارغة: %s تقبل الطريقة عددًا من الوسائط في النطاق [%1$d..%2$d] + المكوّن الإضافي المطلوب لـ \"%1$s\" مفقود. يُرجى تثبيت المكوّن الإضافي ثم إعادة المحاولة. الوحدة النمطية \"%s\" لا تعمل بسبب عدم توفر ملفات المكتبة الضرورية يتم تعطيل خدمة إمكانية الوصول وتوقف البرنامج النصي لم يتم تنشيط خدمة إمكانية الوصول @@ -286,8 +295,12 @@ لا توجد تطبيقات متاحة لتشغيل هذا الملف لا توجد تطبيقات متاحة لإرسال هذا الملف لا توجد تطبيقات متاحة لعرض هذا الملف + لم يتم العثور على أي متغيرات مفعّلة ومتاحة للمكوّن الإضافي %1$s (%2$s). لم يتم توفير عنوان URL متاح للملحق الحالي لا يوجد إذن \"عرض عبر التطبيقات الأخرى\" + لم يتم العثور على موارد Paddle OCR المضمّنة. يُرجى إعادة الحزم مع تفعيل Paddle OCR. + لا يوجد مكوّن إضافي مفعّل لـ \"%1$s\". يُرجى تفعيل مكوّن إضافي ثم إعادة المحاولة. + لم يتم العثور على أي مكونات Paddle OCR إضافية متاحة لا يوجد إذن للوصول إلى Shizuku لا يوجد إذن \"نشر الإخطارات\" لا يوجد إذن \"اقرأ حالة الهاتف\" @@ -300,6 +313,10 @@ فشل في تحليل أصول الإفراج عن جيثب فشل في تحليل معلومات الإصدار بناء جملة نمط غير صالح + ملف APK للمكوّن الإضافي لا يحتوي على الموارد المطلوبة لـ variant=\"%1$s\": %2$s. + ملف APK للمكوّن الإضافي لا يحتوي على مكتبات native المطلوبة: %1$s. + أعاد المكوّن الإضافي %1$s معلومات فارغة. + أعاد المكوّن الإضافي %1$s variant غير صالح: %2$s. رقم المنفذ أكثر من 65535 ملف البرنامج النصي الرئيسي للمشروع \"%1$s\" غير موجود لا يمكن وضع القيمة %s في JSON @@ -318,6 +335,7 @@ يجب أن يكون رقم إصدار AutoJs6 المحدد أكبر من 461 لا يمكن لمحول الخاصية المطلوبة \"%1$s\" إرجاع قيمة فارغة الموضوع ليس على قيد الحياة + انتهت مهلة الاستعلام عن معلومات المكوّن الإضافي %1$s. غير قادر على استخدام خدمة Shizuku الطابع غير المقبول خطأ غير معروف @@ -347,8 +365,8 @@ يتم دعم IPv4 و IPv6 وأسماء النطاقات. أدخل عنوان URL يشير إلى ملحق (Plugin) بعيد.\nمثال: \"https://example.com/plugin.apk\". آخر استخدام: %1$s - فشل خيط \"blob"\ - نجح خيط \"blob"\ وجرى حفظ التخزين المؤقت دون اتصال + فشل خيط \"blob\" + نجح خيط \"blob\" وجرى حفظ التخزين المؤقت دون اتصال تم تحميل البيانات تم اختيار المحتوى الابتدائي جارٍ إدراج عناصر جديدة @@ -362,10 +380,10 @@ ملف التخزين المؤقت دون اتصال هو أحدث إصدار جارٍ استبدال محتوى التاريخ جارٍ استبدال سجل التحديث - فشل خيط \"raw"\ - نجح خيط \"raw"\ وجرى حفظ التخزين المؤقت دون اتصال - بدء خيط طلب احتياطي \"blob"\ - بدء خيط طلب \"raw"\ + فشل خيط \"raw\" + نجح خيط \"raw\" وجرى حفظ التخزين المؤقت دون اتصال + بدء خيط طلب احتياطي \"blob\" + بدء خيط طلب \"raw\" الألبوم نسبة العرض إلى الارتفاع الصوت @@ -406,6 +424,7 @@ تمكين خدمة إمكانية الوصول مع الوصول إلى الجذر تلقائيًا عند الحاجة تمكين خدمة إمكانية الوصول مع إعدادات آمنة تلقائيًا عند الحاجة قم بزيادة مرونة التعليمات البرمجية وتمكين وظائف أكثر ثراءً من خلال توسيع كائنات JavaScript المضمنة + تتيح خدمة المقدمة الحفاظ على تشغيل التطبيق والبرامج النصية بشكل أكثر استقرارًا في الخلفية منع إجراءات الأتمتة من البرامج النصية عندما يكون AutoJs6 في المقدمة قم بتشغيل البرنامج النصي مباشرة دون إظهار النشاط الرئيسي يسمح لـ AutoJs6 بإنشاء وإرسال الإشعارات @@ -418,10 +437,12 @@ ابدأ أو توقف عن التسجيل الذي يتم التحكم فيه بواسطة مفتاح خفض مستوى الصوت عند عرض الزر العائم اضغط على مفتاح \"رفع الصوت\" لإيقاف تشغيل جميع البرامج النصية عرض سجل إصدارات النُّسَخ والبيانات الإحصائية + وحدة التخزين الداخلية خدمة إمكانية الوصول مطلوب من خلال العملية التلقائية البرنامج النصي (انقر فوق ، اضغط لفترة طويلة ، شريحة ، إلخ). تم تمكين خدمة إمكانية الوصول ولكن لا تعمل (إعادة تمكين أو إعادة تشغيل الجهاز) قد تكون هناك حاجة إلى خدمة إمكانية الوصول + جارٍ الإيقاف... حول حول كل الملفات وصول حول التطبيق والمطور @@ -444,6 +465,7 @@ اسم مستعار الاسم المستعار لا يمكن أن يكون فارغًا كلمة مرور الاسم المستعار + الكل جميع الملفات وصول هناك حاجة إلى \"All Files Access\" للوصول إلى ملفات البرنامج النصي على الهاتف جميع السجلات @@ -496,7 +518,7 @@ كود إصدار التطبيق اسم إصدار التطبيق مظهر - يجب ملء حقل واحد على الأقل من "الاسم، اسم المنظمة، وحدة التنظيم، رمز الدولة، الولاية أو المقاطعة، المدينة أو المنطقة، الشارع" + يجب ملء حقل واحد على الأقل من [الاسم، اسم المنظمة، وحدة التنظيم، رمز الدولة، الولاية أو المقاطعة، المدينة أو المنطقة، الشارع] ينسب تحقق من التحديثات التلقائية تحقق من وجود التحديثات تلقائيًا وعرض تناول وجبة خفيفة على الصفحة الرئيسية @@ -580,7 +602,11 @@ انسخ جميع الملفات إلى دليل جديد نسخ CMD نسخ سجل الأخطاء + نسخ الملف + نسخ المجلد خط النسخ + مسار المصدر هو نفسه مسار الوجهة. هل تريد متابعة النسخ?\n\nالاسم الجديد: \"%1$s\". + نسخ إلى نسخ إلى الحافظة نسخ القيمة رمز الدولة (XX) @@ -603,10 +629,14 @@ تقصير مخزن المفاتيح الافتراضي بادئة افتراضية + مدة التأخير حذف حذف الكل + حذف الملف + حذف المجلد حذف الخط الوصف + الوجهة تفاصيل تفاصيل المطور قيد التطوير خيارات للمطور @@ -619,7 +649,7 @@ اسم منتج الجهاز دقّة شاشة الجهاز التحميل الان - الدليل + دليل معطّل عرض على تطبيقات أخرى يوصى بإذن \"العرض عبر التطبيقات الأخرى\" لعرض جميع عناصر واجهة المستخدم بشكل صحيح @@ -716,6 +746,7 @@ سابق الاسم زر عائم + مجلد توقف إجباري خدمة المقدمة اكتمل التنسيق @@ -757,6 +788,7 @@ التثبيت من \"URL\" تثبيت الملحق من \"URL\" قابل للتثبيت + مثبّت فشل التحقق من السلامة تمت إزالة حرف غير صالح اسم الحزمة غير صالح @@ -812,7 +844,12 @@ لم يتم تثبيت \"Mobile QQ\" أكثر تفاصيل + نقل + مسار المصدر هو نفسه مسار الوجهة، تم إلغاء النقل. انقل جميع الملفات إلى دليل جديد + نقل الملف + نقل المجلد + نقل إلى خيارات متعددة اسم تحتاج إلى تمكين خدمة الوصول @@ -840,6 +877,7 @@ لا الوصول إلى الجذر لا توجد نصوص للتوقف عن الجري لم تمنح + غير مثبّت لا تظهر النشاط الرئيسي تنبيه الوصول إلى الإخطار @@ -854,6 +892,8 @@ افتح من قبل التطبيقات الأخرى فتح النشاط الرئيسي مفتوحة مع + تم الإيقاف + اكتمل تم الانتهاء من العملية خيارات اسم المنظمة @@ -942,6 +982,7 @@ فشل منح الإذن (مع Shizuku) منح إذن (مع الجذر) تم منح الإذن (مع Shizuku) + إدارة الأذونات السماح للتطبيق بالوصول إلى بيانات استخدام التطبيقات الأخرى إلغاء الإذن فشل إلغاء الإذن (مع الجذر) @@ -965,6 +1006,7 @@ موقع المؤشر فشل تبديل \"موقع المؤشر\".\nالوصول إلى الجذر مطلوب. نشر الإخطارات + لضمان عمل خدمات المقدّمة في AutoJs6 وغيرها بشكل طبيعي، وتمكين السكربتات من نشر الإشعارات، يجب منح AutoJs6 إذن \"نشر الإشعارات\". البرنامج النصي مسبقا خطة... محتوى مربع الحوار المعين مسبقاً @@ -979,6 +1021,9 @@ موقع المشروع وصول وسائل الإعلام المشروع مستعجل + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s يترك مُستَحسَن انتهى التسجيل @@ -1047,6 +1092,7 @@ حفظ في المحرّك تأخير البدء + تأخير طلب إذن التقاط الشاشة تسجيل السيناريو البرنامج النصي يبحث @@ -1066,6 +1112,7 @@ انشاء اختصار وضع الخادم خدمة + إدارة الخدمات تعيين كدليل العمل ضبط نقطة توقف إعدادات @@ -1082,6 +1129,10 @@ مقاس تم تصدير %d من العناصر فرز + فرز حسب آخر تحديث + فرز حسب الاسم + فرز حسب حجم الحزمة + المصدر مسار رمز المصدر أذونات خاصة وضع مستقر @@ -1174,36 +1225,4 @@ اكتب إعدادات الأمان كتابة إعدادات النظام النوافذ المنبثقة في الخلفية - لم يتم العثور على أي مكونات Paddle OCR إضافية متاحة - مثبّت - غير مثبّت - الكل - فرز حسب الاسم - فرز حسب آخر تحديث - فرز حسب حجم الحزمة - المكوّن الإضافي المطلوب لـ \"%1$s\" مفقود. يُرجى تثبيت المكوّن الإضافي ثم إعادة المحاولة. - لا يوجد مكوّن إضافي مفعّل لـ \"%1$s\". يُرجى تفعيل مكوّن إضافي ثم إعادة المحاولة. - لم يتم العثور على أي متغيرات مفعّلة ومتاحة للمكوّن الإضافي %1$s (%2$s). - ملف APK للمكوّن الإضافي لا يحتوي على الموارد المطلوبة لـ variant=\"%1$s\": %2$s. - ملف APK للمكوّن الإضافي لا يحتوي على مكتبات native المطلوبة: %1$s. - تعذّر ربط خدمة المكوّن الإضافي %1$s. - انتهت مهلة الاستعلام عن معلومات المكوّن الإضافي %1$s. - أعاد المكوّن الإضافي %1$s معلومات فارغة. - أعاد المكوّن الإضافي %1$s variant غير صالح: %2$s. - لم يتم العثور على موارد Paddle OCR المضمّنة. يُرجى إعادة الحزم مع تفعيل Paddle OCR. - تصغير - %1$s: %2$d%3$s - %1$s: %2$d %3$s - تأخير طلب إذن التقاط الشاشة - عند طلب إذن التقاط الشاشة، قد تحتوي نافذة طلب الإذن المنبثقة على حركة تلاشي عند اختفائها. إذا تم استدعاء `images.captureScreen` مباشرةً، فقد تتضمن لقطة الشاشة الناتجة محتوى نافذة طلب الإذن مما يسبب حجبًا.\n\nتضيف قيمة هذا الخيار مدة تأخير (بالمللي ثانية) قبل التقاط الشاشة مباشرةً بعد الحصول على الإذن، وذلك لتجنب مشكلة الحجب المذكورة أعلاه.\n\nينطبق هذا الخيار فقط على أول عملية التقاط بعد الحصول على الإذن؛ أما عمليات الالتقاط اللاحقة فلن تتأثر بهذه القيمة. - مدة التأخير - الصفحة الرئيسية - تعذّر تغيير حالة المفتاح - لضمان عمل خدمات المقدّمة في AutoJs6 وغيرها بشكل طبيعي، وتمكين السكربتات من نشر الإشعارات، يجب منح AutoJs6 إذن \"نشر الإشعارات\". - \"موقع المؤشر\" هي ميزة تصحيح أخطاء ضمن خيارات المطوّر في Android.\nعند تفعيلها، يعرض النظام على الشاشة معلومات نقاط اللمس مثل [الإحداثيات/مسار الحركة/العدد/الحجم/سرعة الحركة/الضغط]، مما يسهل [كتابة/تصحيح/التحقق من] السكربتات ذات الصلة. - حدث خطأ - إدارة الأذونات - إدارة الخدمات - تتيح خدمة المقدمة الحفاظ على تشغيل التطبيق والبرامج النصية بشكل أكثر استقرارًا في الخلفية - - + \ No newline at end of file diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 834ee337..aad9b0f7 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -2,7 +2,6 @@ - Building... Cleaning... Packaging... @@ -47,7 +46,8 @@ Config \"abi\" contains unavailable options Config \"lib\" contains invalid options Config \"lib\" contains unavailable options - File already exists.\nOverwrite? + Folder already exists. Overwrite? + File already exists. Overwrite? 1. Press and hold the application name (AutoJs6) on the home page to jump to the settings page\n2. Press and hold a certain settings option on the settings page to view detailed information Current theme color %1$s is configured by the color palette A Floating Action Button widget for displaying the manifest @@ -91,23 +91,27 @@ Night mode (also known as Dark theme) applies to both the Android system UI and apps running on the device, which improves visibility for users with low vision and those who are sensitive to bright light, and makes it easier for anyone to use a device in a low-light environment.\n\nFollow system: AutoJs6 has Night mode settings same as Android system\nAlways on: AutoJs6 keeps Night mode on (regardless of Android system settings)\nAlways off: AutoJs6 keeps Night mode off (regardless of Android system settings)\n\nNote: Follow system option is only for Android API Level 28 (Android 9) [P] and above. To enable Night mode in Android system:\n- Android API Level 29 (Android 10) [Q] and above: Settings -> Display -> Theme.\n- Android API Level 28 (Android 9) [P]: Developer options -> Night mode.\n\nThe following conditions must to met for applying a Night mode (Dark theme) to web-based content using a WebView component (like AutoJs6 documentation page):\n1. Android System WebView (or browsers like Google Chrome):\n- Android API Level 29 (Android 10) [Q] and above: version >= 76\n- Android API Level 28 (Android 9) [P]: version >= 105\n2. Web-based content in WebView component is adapted to Dark theme (by CSS or Android XML resources and so forth) The \"notification access\" (or \"notification reading\") permission allows AutoJs6 to read system notification content, so scripts can listen for notifications or retrieve notification text, etc. + \"Pointer location\" is a debugging feature in Android Developer options.\nWhen enabled, the system will display information about touch point(s) on the screen, such as [coordinates/movement trajectory/count/size/movement speed/pressure], which helps with [writing/debugging/verification] of related scripts. The \"post notifications\" permission allows AutoJs6 to publish notifications to the system, so scripts can post and manage custom notifications in the notification shade.\n\nNote: on Android 13+ devices, if this permission is not granted, some notifications may not show, and it may affect foreground service startup and stability. With project media access, security warning for screen recording will not prompt. The restart strategy only affects the restart button in the home page drawer.\n\nQuick restart: Quickly restarts the app. If the restart fails or unexpected situations occur, try switching to \"Scheduled restart\".\nScheduled restart: Sets up a short-timed task in advance. After the app stops, it will start again on schedule to achieve app restart. Switch ON (default): results of Java methods that are instances of Number/Boolean/Character are wrapped as Java objects and exposed to scripts (String excluded). typeof is \"object\", species is \"JavaObject\"; Java methods remain accessible, which helps retain precise Java type traits and overload resolution.\n\nSwitch OFF: the above types are no longer wrapped and are exposed directly as JavaScript primitives (number/boolean/one‑character string). typeof is the corresponding JavaScript type, aligning better with JavaScript semantics and ecosystem. You can still explicitly create a Java wrapper via new, e.g. new java.lang.Boolean(true).\n\nSee: http://issues.autojs6.com/435 If you have exotic root or abnormal state for root access, you can force set root to root or non-root. Binary type: non-editable, with the file extension \"auto\"\nJavaScript type: can be edited or copied directly, with the file extension \"js\" + When requesting screen capture permission, the permission request window may include a fade-out animation when it disappears. If `images.captureScreen` is called immediately, the captured screenshot may contain the permission request window content and be obstructed.\n\nThe current option value adds a delay (in milliseconds) before capturing the screen immediately after permission is granted, which can be used to avoid the obstruction issue described above.\n\nThis option only applies to the first screenshot after screen capture permission is granted; subsequent screenshots are not affected by this value. Server mode allows AutoJs6 to start a service on the current device and wait for external client connections for [ script transfer / log printing / remote control ].\n\nAutoJs6 server mode supports two connection methods:\n1. LAN\n2. Android Debug Bridge (ADB) Shizuku makes it possible to uses system API with ADB privileges Stable mode makes it more stable when getting layout bounds, but some results may be ignored.\nA11y service\'s restart required. Theme color is applied to widgets including but not limited to the following ones:\nStatus bar\nAppbar\nFile icon\nTask item icon\nFAB\nSettings category title\nSwitch button\n\nNote: As of AutoJs6 version 6.2.0, there has been no difference between primary color, primary dark color and accent color yet. - Controls the underlying mechanism for triggering scripts on a schedule.\n\nAlarmManager: With the “Allow setting alarms and reminders” permission granted, scheduled tasks can fire closer to the exact time.\nWorkManager: System-friendly; suitable for non-critical tasks that can tolerate some delay.\nJobScheduler: Legacy implementation kept for compatibility; higher chance of delays. - Use cases and differences:\n\n1. AlarmManager\nBest for time-sensitive tasks, e.g., [reminders/strictly scheduled scripts/...].\nOn Android 12+ with the “Allow setting alarms and reminders” permission, tasks can run more on time even when the screen is off or the device is idle.\nWithout it, the system may degrade exactness or delay execution.\n\n2. WorkManager\nBest for tasks that don’t require strict timing, e.g., [non-critical sync/cleanup/statistics/...].\nScheduling depends on [battery/network/charging/idle policies/...], so execution may be postponed when the screen is off or idle.\nWhile it can’t guarantee exact timing, it excels at [reliable completion/retries/chaining/unique work de-duplication].\n\n3. JobScheduler\nHistorical implementation for compatibility.\nOn newer Android versions, tasks may be delayed more noticeably.\nGenerally not recommended unless required for compatibility. + Controls the underlying mechanism for triggering scripts on a schedule.\n\nAlarmManager: With the \"Allow setting alarms and reminders\" permission granted, scheduled tasks can fire closer to the exact time.\nWorkManager: System-friendly; suitable for non-critical tasks that can tolerate some delay.\nJobScheduler: Legacy implementation kept for compatibility; higher chance of delays. + Use cases and differences:\n\n1. AlarmManager\nBest for time-sensitive tasks, e.g., [reminders/strictly scheduled scripts/...].\nOn Android 12+ with the \"Allow setting alarms and reminders\" permission, tasks can run more on time even when the screen is off or the device is idle.\nWithout it, the system may degrade exactness or delay execution.\n\n2. WorkManager\nBest for tasks that don’t require strict timing, e.g., [non-critical sync/cleanup/statistics/...].\nScheduling depends on [battery/network/charging/idle policies/...], so execution may be postponed when the screen is off or idle.\nWhile it can’t guarantee exact timing, it excels at [reliable completion/retries/chaining/unique work de-duplication].\n\n3. JobScheduler\nHistorical implementation for compatibility.\nOn newer Android versions, tasks may be delayed more noticeably.\nGenerally not recommended unless required for compatibility. Provides access to device usage history and statistics which results in currentPackage() a more accurate result View the release version history and key category statistics of AutoJs6 on GitHub. Secure system settings, containing system preferences that applications can read but are not allowed to write.\nThese are for preferences that the user must explicitly modify through the UI of a system app.\nWith secure system settings permission, normal applications can directly modify the secure settings (such as accessibility service). The \"write system settings\" permission allows AutoJs6 to modify some system settings, so scripts can change system parameters such as [ screen brightness / auto-rotate / screen timeout ]. Abandon + Abort + Abort Advanced Amend @string/text_back @@ -125,10 +129,11 @@ Details File info History + Homepage Ignore - Interrupt Join group Manager + Minimize More Palette Quit @@ -188,6 +193,7 @@ Method %s has been abandoned and should not be used The \"%1$s\" operation cannot be completed because the parameter contains negative coordinate values (%2$d, %3$d) An activity is required, which could be provided by running in \"ui\" execution mode + An error occurred An operation is not implemented App is not installed App is not installed: \"%s\" @@ -226,13 +232,15 @@ Excessive height: template [%1$d] > region [%2$d] Excessive width: template [%1$d] > region [%2$d] Failed to apply current color history - Failed to call method "%s" - + Failed to bind %1$s plugin service. + Failed to call method \"%s\" + + Failed to change the toggle state Failed to convert value %s into a Drawable Failed to open the settings page Failed to grant Shizuku access - Failed to instantiate "%s" - + Failed to instantiate \"%s\" + Failed to launcher manager Failed to launch system settings Failed to load plugins.\nReason: %1$s. @@ -271,6 +279,7 @@ AutoJs6 may not have root access to run \"auto\" file %s() called with null argument: %s Method only accepts a number of arguments in the range [%1$d\.\.%2$d] + Missing required plugin for \"%1$s\". Please install the plugin and try again. The \"%s\" module does not work due to the lack of necessary library files Accessibility service is disabled and the script has stopped Accessibility service is not activated @@ -281,8 +290,12 @@ No applications available for playing this file No applications available for sending this file No applications available for viewing this file + No available enabled %1$s plugin variants found (%2$s). No available URL provided for current plugin No \"display over other apps\" permission + No embedded Paddle OCR assets found. Please re-package with Paddle OCR enabled. + No enabled plugin for \"%1$s\". Please enable a plugin and try again. + No Paddle OCR plugins available No permission to access Shizuku No \"post notifications\" permission No \"read phone state\" permission @@ -295,6 +308,10 @@ Failed to parse GitHub release assets Failed to parse version information Invalid pattern syntax + Plugin APK does not contain required assets for variant=\"%1$s\": %2$s. + Plugin APK does not contain required native libraries: %1$s. + %1$s plugin returned empty info. + %1$s plugin returned invalid variant: %2$s. Port number over 65535 Project main script file \"%1$s\" does not exist Cannot put value %s into JSON @@ -313,6 +330,7 @@ Specified AutoJs6 version number must be greater than 461 The transformer for required property \"%1$s\" cannot return nullish Thread is not alive + Timeout while querying %1$s plugin info. Unable to use Shizuku service Unacceptable character Unknown error @@ -401,6 +419,7 @@ Enable accessibility service with root access automatically when needed Enable accessibility service with secure settings automatically when needed Increase code flexibility and enable richer functionality by extending JavaScript built-in objects + The foreground service helps keep the app and scripts running more reliably in the background Prevent automation actions from scripts when AutoJs6 is in the foreground Run script directly without showing main activity Allows AutoJs6 to create and post notifications @@ -410,13 +429,15 @@ Java primitive types will be wrapped as Java objects in scripts More stable layout analysis but worse code compatibility (a11y service restarting needed) Add shortcuts to launcher - Start or stop recording controlled by “Volume Down” key when floating button is showing + Start or stop recording controlled by \"Volume Down\" key when floating button is showing Press \"Volume Up\" key to stop all running scripts View release version history and statistics + Internal Storage Accessibility service Required by the script automatic operation (click, long press, slide, etc.). Accessibility service enabled but not running (Re-enable or reboot the device) Accessibility service may be needed + Aborting... About About all files access About app and developer @@ -439,12 +460,13 @@ alias Alias cannot be empty Alias Password + All All files access \"All files access\" is needed to access script files on the phone All histories All histories have been cleared All items have been cleared - Granting the “Allow setting alarms and reminders” permission is recommended to help tasks run as punctually as possible even when the screen is off or the device is idle + Granting the \"Allow setting alarms and reminders\" permission is recommended to help tasks run as punctually as possible even when the screen is off or the device is idle Copied to clipboard Already copied to clipboard (only latest %d items) Created @@ -491,7 +513,7 @@ App version code App version name Appearance - At least one field from \"Full Name, Organization Name, Organizational Unit, Country Code, State or Province, City or Locality, Street\" must be filled + At least one field from [Full Name, Organization Name, Organizational Unit, Country Code, State or Province, City or Locality, Street] must be filled Attribute Auto check for updates Check for updates automatically and show a snackbar on homepage @@ -575,7 +597,11 @@ Copy all files to new directory Copy cmd Copy debugging log + Copy file + Copy folder Copy line + Source path is the same as destination path. Continue copying?\n\nNew name: \"%1$s\". + Copy to Copy to clipboard Copy value Country Code (XX) @@ -598,10 +624,14 @@ Default Default Keystore Default prefix + Delay time Delete Delete All + Delete file + Delete folder Delete line Description + Destination Details Developer details is under development Developer options @@ -711,6 +741,7 @@ Prev Full Name Floating button + Folder Force stop Foreground service Formatting completed @@ -752,6 +783,7 @@ Install from \"URL\" Install plugin from \"URL\" Installable + Installed Integrity verification failed Invalid character is removed Invalid package name @@ -807,7 +839,12 @@ \"Mobile QQ\" not installed More Details + Move + Source path is the same as destination path, move aborted. Move all files to new directory + Move file + Move folder + Move to Multiple options Name Need to enable accessibility service @@ -835,6 +872,7 @@ No root access No scripts to stop running Not granted + Not installed Not showing main activity Notification Notification access @@ -849,6 +887,8 @@ Open by other apps Open main activity Open with + Aborted + Completed Operation is completed Options Organization Name @@ -937,6 +977,7 @@ Failed to grant permission (with Shizuku) Permission granted (with root) Permission granted (with Shizuku) + Permission management Allow the app to access usage statistics of other apps Permission revoked Failed to revoked permission (with root) @@ -960,6 +1001,7 @@ Pointer location Toggle \"pointer location\" failed.\nRoot access is required. Post notifications + To ensure that AutoJs6 foreground services, etc. can work properly and that scripts can post notifications, AutoJs6 must be granted the \"post notifications\" permission. Pre-execute script Preparing... Preset dialog content @@ -974,6 +1016,9 @@ Project location Project media access Prompt + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s Quit Recommended Recording finished @@ -1042,6 +1087,7 @@ Save to Backend Start delay + Screen capture permission request delay Script recording Script running Search @@ -1061,6 +1107,7 @@ Create shortcut Server mode Service + Service management Set as working dir Set a breakpoint Settings @@ -1077,6 +1124,10 @@ Size %d items exported Sort + Sort by last update time + Sort by name + Sort by package size + Source Source code path Special permissions Stable mode @@ -1134,7 +1185,7 @@ Usage stats access Use Android 7.0 shortcut Use default icon - Use “Volume Down” key to control recording + Use \"Volume Down\" key to control recording Use \"Volume Up\" key to control the script running Username Username cannot be empty @@ -1169,36 +1220,4 @@ Write security settings Write system settings Display pop-up windows while running in the background - No Paddle OCR plugins available - Installed - Not installed - All - Sort by name - Sort by last update time - Sort by package size - Missing required plugin for \"%1$s\". Please install the plugin and try again. - No enabled plugin for \"%1$s\". Please enable a plugin and try again. - No available enabled %1$s plugin variants found (%2$s). - Plugin APK does not contain required assets for variant=\"%1$s\": %2$s. - Plugin APK does not contain required native libraries: %1$s. - Failed to bind %1$s plugin service. - Timeout while querying %1$s plugin info. - %1$s plugin returned empty info. - %1$s plugin returned invalid variant: %2$s. - No embedded Paddle OCR assets found. Please re-package with Paddle OCR enabled. - Minimize - %1$s: %2$d%3$s - %1$s: %2$d %3$s - Screen capture permission request delay - When requesting screen capture permission, the permission request window may include a fade-out animation when it disappears. If `images.captureScreen` is called immediately, the captured screenshot may contain the permission request window content and be obstructed.\n\nThe current option value adds a delay (in milliseconds) before capturing the screen immediately after permission is granted, which can be used to avoid the obstruction issue described above.\n\nThis option only applies to the first screenshot after screen capture permission is granted; subsequent screenshots are not affected by this value. - Delay time - Homepage - Failed to change the toggle state - To ensure that AutoJs6 foreground services, etc. can work properly and that scripts can post notifications, AutoJs6 must be granted the \"post notifications\" permission. - \"Pointer location\" is a debugging feature in Android Developer options.\nWhen enabled, the system will display information about touch point(s) on the screen, such as [coordinates/movement trajectory/count/size/movement speed/pressure], which helps with [writing/debugging/verification] of related scripts. - An error occurred - Permission management - Service management - The foreground service helps keep the app and scripts running more reliably in the background - - + \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1e8b9bbb..fe831496 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -5,7 +5,6 @@ - Construir... Limpieza... Empaquetando... @@ -50,7 +49,8 @@ La configuración \"abi\" contiene opciones no disponibles La configuración \"lib\" contiene opciones inválidas La configuración \"lib\" contiene opciones no disponibles - El archivo ya existe.\n¿Sobreescribir? + La carpeta ya existe. ¿Sobrescribir? + El archivo ya existe. ¿Sobrescribir? 1. Mantén pulsado el nombre de la aplicación (AutoJs6) en la página de inicio para saltar a la página de configuración\n2. 2. Mantén pulsada una opción de configuración determinada en la página de configuración para ver información detallada El color del tema actual %1$s está configurado por la paleta de colores Un botón de acción flotante para mostrar el manifiesto @@ -94,12 +94,14 @@ El modo nocturno (también conocido como tema oscuro) se aplica tanto a la interfaz de usuario del sistema Android como a las aplicaciones que se ejecutan en el dispositivo, lo que mejora la visibilidad para los usuarios con baja visión y los que son sensibles a la luz brillante, y facilita el uso de un dispositivo en un entorno con poca luz.\n\nSistema de seguimiento: AutoJs6 tiene ajustes de modo nocturno iguales a los del sistema Android\nSiempre activado: AutoJs6 mantiene activado el modo Noche (independientemente de la configuración del sistema Android)\nSiempre desactivado: AutoJs6 mantiene el modo nocturno desactivado (independientemente de la configuración del sistema Android)\n\nNota: La opción de seguir el sistema es sólo para el nivel 28 de la API de Android (Android 9) [P] y superior. Para activar el modo nocturno en el sistema Android:\n- Android API Level 29 (Android 10) [Q] y superior: Ajustes -> Pantalla -> Tema.\n- Android API Level 28 (Android 9) [P]: Opciones de desarrollador -> Modo nocturno.\n\nLas siguientes condiciones deben cumplirse para aplicar un modo nocturno (tema oscuro) al contenido basado en la web utilizando un componente WebView (como la página de documentación de AutoJs6):\n1. Sistema Android WebView (o navegadores como Google Chrome):\n- Android API Level 29 (Android 10) [Q] y superior: versión >= 76\n- Android API Level 28 (Android 9) [P]: versión >= 105\n2. El contenido basado en la web en el componente WebView se adapta al tema oscuro (mediante CSS o recursos XML de Android, etc.) El permiso \"acceso a notificaciones\" (o \"permiso de lectura de notificaciones\") permite que AutoJs6 lea el contenido de las notificaciones del sistema, para que los scripts puedan escuchar notificaciones u obtener el texto de notificaciones, etc. + \"Ubicación del puntero\" es una función de depuración en las opciones de desarrollador de Android.\nAl activarla, el sistema mostrará en pantalla información del/de los punto(s) de toque, como [coordenadas/trayectoria de movimiento/cantidad/tamaño/velocidad de movimiento/presión], lo que facilita la [escritura/depuración/verificación] de los scripts relacionados. El permiso \"enviar notificaciones\" permite que AutoJs6 publique notificaciones en el sistema, de modo que los scripts puedan publicar y administrar notificaciones personalizadas en la barra de notificaciones.\n\nNote: en dispositivos con Android 13+, si este permiso no se concede, algunas notificaciones pueden no mostrarse y esto puede afectar el inicio y la estabilidad de los servicios en primer plano. Con el acceso a los medios del proyecto, la advertencia de seguridad para la grabación de la pantalla no aparecerá. La estrategia de reinicio solo afecta al botón de reinicio del cajón de la página principal.\n\nReinicio rápido: reinicia rápidamente la app. Si el reinicio falla o ocurre alguna situación inesperada, prueba cambiar a \"Reinicio programado\".\nReinicio programado: configura de antemano una tarea de corta duración. Después de que la app se detenga, se iniciará de nuevo según lo programado para lograr el reinicio de la app. Con el interruptor activado (predeterminado): los valores devueltos por métodos Java de tipo Number/Boolean/Character se envuelven como objetos Java y se exponen al script (String excluido). typeof es \"object\", species es \"JavaObject\"; se pueden invocar métodos de Java, lo que ayuda a conservar las características de tipo precisas de Java y la resolución de sobrecargas.\n\nCon el interruptor desactivado: no se envuelven los tipos anteriores y se exponen directamente como primitivos de JavaScript (number/boolean/cadena de un solo carácter). typeof corresponde al tipo de JavaScript respectivo, más acorde con la semántica/ecosistema de JavaScript. Aun así, puede declarar explícitamente un envoltorio de Java con new, por ejemplo new java.lang.Boolean(true).\n\nConsulte: http://issues.autojs6.com/435 Si tiene una raíz exótica o un estado anormal para el acceso a la raíz, puede forzar el establecimiento de la raíz a raíz o no raíz. Tipo binario: no editable, con la extensión de archivo \"auto\"\nTipo JavaScript: se puede editar o copiar directamente, con la extensión de archivo \"js\" + Al solicitar el permiso de captura de pantalla, la ventana de solicitud de permiso mostrada puede tener una animación de desvanecimiento al desaparecer. Si se llama a `images.captureScreen` inmediatamente, la captura obtenida puede incluir el contenido de dicha ventana y quedar obstruida.\n\nEl valor de esta opción añade un tiempo de espera (en milisegundos) antes de capturar la pantalla inmediatamente después de obtener el permiso, para evitar el problema de obstrucción descrito.\n\nEsta opción solo se aplica a la primera captura tras obtener el permiso; las capturas posteriores no se verán afectadas por este valor. El modo servidor permite que AutoJs6 inicie un servicio en el dispositivo actual y espere conexiones de clientes externos para realizar [ transferencia de scripts / impresión de registros / control remoto ].\n\nEl modo servidor de AutoJs6 admite dos métodos de conexión:\n1. Red de área local (LAN)\n2. Android Debug Bridge (ADB) Shizuku te permite obtener privilegios ADB y acceso a las APIs del sistema El modo estable hace que sea más estable al obtener los límites de diseño, pero algunos resultados pueden ser ignorados.\nEs necesario reiniciar el servicio de accesibilidad. @@ -111,6 +113,8 @@ Ajustes de seguridad del sistema, que contienen preferencias del sistema que las aplicaciones pueden leer pero no pueden escribir.\nSe trata de preferencias que el usuario debe modificar explícitamente a través de la interfaz de usuario de una aplicación del sistema.\nCon el permiso de configuración segura del sistema, las aplicaciones normales pueden modificar directamente la configuración segura (como el servicio de accesibilidad). El permiso \"modificar ajustes del sistema\" permite que AutoJs6 cambie algunos ajustes del sistema, de modo que los scripts puedan modificar parámetros como [ brillo de pantalla / rotación automática / tiempo de espera de pantalla ]. Abandonar + Abortar + Interrumpir conexión Avanzado Corregir dirección @string/text_back @@ -128,10 +132,11 @@ Detalles Información del archivo Historial + Inicio Ignorar - Interrumpir conexión Unirse grupo Administrador + Minimizar Más Abrir paleta Salir @@ -191,6 +196,7 @@ El método %s ha sido abandonado y no debe utilizarse La operación \"%1$s\" no puede completarse porque el parámetro contiene valores de coordenadas negativos (%2$d, %3$d) Se requiere una actividad, que podría proporcionarse ejecutando en modo de ejecución \"ui\" + Se produjo un error Una operación no está implementada La aplicación no está instalada La aplicación no está instalada: \"%s\" @@ -229,8 +235,10 @@ Altura excesiva: plantilla [%1$d] > región [%2$d] Anchura excesiva: plantilla [%1$d] > región [%2$d] Error al aplicar el historial de color actual + No se pudo vincular el servicio del plugin %1$s. Fallo al llamar al método \"%s\" + No se pudo cambiar el estado del interruptor Fallo al convertir el valor %s en un Dibujable No se pudo abrir la página de ajustes Fallo en la concesión de permisos Shizuku @@ -274,6 +282,7 @@ AutoJs6 puede no tener acceso a la raíz para ejecutar el archivo \"auto %s() llamada con argumento nulo: %s El método solo acepta una cantidad de argumentos en el rango [%1$d..%2$d] + Falta el plugin requerido para \"%1$s\". Instala el plugin e inténtalo de nuevo. El módulo \"%s\" no funciona debido a la falta de archivos de biblioteca necesarios El servicio de accesibilidad está desactivado y el script se ha detenido El servicio de accesibilidad no está activado @@ -284,8 +293,12 @@ No hay aplicaciones disponibles para reproducir este archivo No hay aplicaciones disponibles para enviar este archivo No hay aplicaciones disponibles para ver este archivo + No se encontraron variantes de plugin %1$s habilitadas y disponibles (%2$s). No se proporcionó ninguna URL disponible para el complemento actual No hay permiso de \"mostrar sobre otras aplicaciones\". + No se encontraron recursos integrados de Paddle OCR. Vuelve a empaquetar con Paddle OCR habilitado. + No hay ningún plugin habilitado para \"%1$s\". Habilita un plugin e inténtalo de nuevo. + No se encontraron plugins de Paddle OCR disponibles No hay permiso para acceder a Shizuku Sin permiso para \"enviar notificaciones\" No hay permiso de \"lectura del estado del teléfono\". @@ -298,6 +311,10 @@ Fallo al analizar los activos de publicación de GitHub Fallo al analizar la información de la versión Sintaxis de patrón no válida + El APK del plugin no contiene los recursos necesarios para variant=\"%1$s\": %2$s. + El APK del plugin no contiene las bibliotecas nativas requeridas: %1$s. + El plugin %1$s devolvió información vacía. + El plugin %1$s devolvió una variante no válida: %2$s. Número de puerto superior a 65535 El archivo de script principal del proyecto \"%1$s\" no existe No se puede poner el valor %s en JSON @@ -316,6 +333,7 @@ El número de versión especificado de AutoJs6 debe ser mayor que 461 El transformador para la propiedad requerida \"%1$s\" no puede devolver un valor nulo El hilo no está vivo + Tiempo de espera agotado al consultar la información del plugin %1$s. No se puede utilizar el servicio Shizuku Carácter inaceptable Error desconocido @@ -404,6 +422,7 @@ Habilitar el servicio de accesibilidad con acceso root automáticamente cuando sea necesario Habilitar el servicio de accesibilidad con configuración segura automáticamente cuando sea necesario Aumentar la flexibilidad del código y permitir una funcionalidad más rica mediante la ampliación de los objetos incorporados de JavaScript + El servicio en primer plano permite mantener la app y los scripts en ejecución de forma más estable en segundo plano Evitar las acciones de automatización de los scripts cuando AutoJs6 está en primer plano Ejecutar el script directamente sin mostrar la actividad principal Permite que AutoJs6 cree y envíe notificaciones @@ -416,10 +435,12 @@ Iniciar o detener la grabación controlada por la tecla de bajar el volumen cuando se muestra el botón flotante Pulse la tecla \"Subir volumen\" para detener todos los scripts en ejecución Ver el historial de versiones publicadas y las estadísticas + Almacenamiento interno Servicio de accesibilidad Requerido por el funcionamiento automático del script (clic, pulsación larga, deslizamiento, etc.). El servicio de accesibilidad está habilitado pero no se está ejecutando (vuelva a habilitarlo o reinicie el dispositivo) El servicio de accesibilidad puede ser necesario + Abortando... Acerca de Sobre el acceso a todos los archivos Sobre la aplicación y el desarrollador @@ -442,6 +463,7 @@ alias El alias no puede estar vacío Contraseña del alias + Todos Acceso a todos los archivos Se necesita \"All files access\" para acceder a los archivos de script en el teléfono Todos los historiales @@ -494,7 +516,7 @@ Código de la versión de la aplicación Nombre de la versión de la aplicación Aspecto - Al menos uno de los campos “Nombre completo, Nombre de la organización, Unidad organizacional, Código de país, Estado o provincia, Ciudad o localidad, Calle” debe estar lleno + Al menos uno de los campos [Nombre completo, Nombre de la organización, Unidad organizacional, Código de país, Estado o provincia, Ciudad o localidad, Calle] debe estar lleno Atributo Comprobación automática de actualizaciones Comprueba las actualizaciones automáticamente y muestra una barra de snacks en la página de inicio @@ -578,7 +600,11 @@ Copiar todos los archivos en el nuevo directorio Copiar cmd Copiar el registro de depuración + Copiar archivo + Copiar carpeta Copiar línea + La ruta de origen es la misma que la de destino. ¿Continuar copiando?\n\nNuevo nombre: \"%1$s\". + Copiar a Copiar al portapapeles Copiar valor Código de país (XX) @@ -601,10 +627,14 @@ Por defecto Almacenamiento de claves predeterminado Prefijo predeterminado + Tiempo de retraso Borrar Eliminar todo + Eliminar archivo + Eliminar carpeta Borrar línea Descripción + Destino Detalles Los detalles del desarrollador están en desarrollo Opciones del desarrollador @@ -714,6 +744,7 @@ Anter Nombre completo Botón flotante + Carpeta Forzar parada Servicio de primer plano Formateo completado @@ -755,6 +786,7 @@ Instalar desde \"URL\" Instalar complemento desde \"URL\" Instalable + Instalado La verificación de integridad falló Carácter inválido ha sido removido Nombre de paquete no válido @@ -810,7 +842,12 @@ \"QQ móvil\" no instalado Más Detalles + Mover + La ruta de origen es la misma que la de destino; movimiento cancelado. Mover todos los archivos a un nuevo directorio + Mover archivo + Mover carpeta + Mover a Opciones múltiples Nombre Necesidad de habilitar el servicio de accesibilidad @@ -838,6 +875,7 @@ Sin acceso root No hay scripts que dejen de ejecutarse No se concede + No instalado No muestra la actividad principal Notificación Acceso a las notificaciones @@ -852,6 +890,8 @@ Abierto por otras aplicaciones Abrir la actividad principal Abrir con + Abortado + Completado La operación se ha completado Opciones Nombre de la organización @@ -940,6 +980,7 @@ Permiso no concedido (con Shizuku) Permiso concedido (con root) Permiso concedido (con Shizuku) + Gestión de permisos Permitir que la aplicación acceda a las estadísticas de uso de otras aplicaciones Permiso revocado Fallo al revocar el permiso (con root) @@ -963,6 +1004,7 @@ Ubicación del puntero Falló la conmutación de la \"ubicación del puntero\".\nSe requiere acceso a la raíz. Notificaciones postales + Para garantizar que los servicios en primer plano de AutoJs6, etc. funcionen correctamente y que los scripts puedan publicar notificaciones, AutoJs6 debe recibir el permiso de \"publicar notificaciones\". Ejecutar previamente el script Preparando... Contenido del diálogo predefinido @@ -977,6 +1019,9 @@ Ubicación del proyecto Acceso a los medios del proyecto Indicación + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s Salga de Recomendado Grabación terminada @@ -1045,6 +1090,7 @@ Guardar en Motor Retraso de inicio + Retraso de solicitud del permiso de captura de pantalla Grabación del script Script en ejecución Buscar en @@ -1064,6 +1110,7 @@ Crear acceso directo Modo servidor Servicio + Gestión de servicios Como directorio de trabajo Establecer un punto de interrupción Configuración @@ -1080,6 +1127,10 @@ Tamaño %d elementos exportados Ordenar + Ordenar por última actualización + Ordenar por nombre + Ordenar por tamaño del paquete + Origen Ruta del código fuente Permisos especiales Modo estable @@ -1172,36 +1223,4 @@ Escribir la configuración de seguridad Escribir la configuración del sistema Ventanas emergentes en segundo plano - No se encontraron plugins de Paddle OCR disponibles - Instalado - No instalado - Todos - Ordenar por nombre - Ordenar por última actualización - Ordenar por tamaño del paquete - Falta el plugin requerido para \"%1$s\". Instala el plugin e inténtalo de nuevo. - No hay ningún plugin habilitado para \"%1$s\". Habilita un plugin e inténtalo de nuevo. - No se encontraron variantes de plugin %1$s habilitadas y disponibles (%2$s). - El APK del plugin no contiene los recursos necesarios para variant=\"%1$s\": %2$s. - El APK del plugin no contiene las bibliotecas nativas requeridas: %1$s. - No se pudo vincular el servicio del plugin %1$s. - Tiempo de espera agotado al consultar la información del plugin %1$s. - El plugin %1$s devolvió información vacía. - El plugin %1$s devolvió una variante no válida: %2$s. - No se encontraron recursos integrados de Paddle OCR. Vuelve a empaquetar con Paddle OCR habilitado. - Minimizar - %1$s: %2$d%3$s - %1$s: %2$d %3$s - Retraso de solicitud del permiso de captura de pantalla - Al solicitar el permiso de captura de pantalla, la ventana de solicitud de permiso mostrada puede tener una animación de desvanecimiento al desaparecer. Si se llama a `images.captureScreen` inmediatamente, la captura obtenida puede incluir el contenido de dicha ventana y quedar obstruida.\n\nEl valor de esta opción añade un tiempo de espera (en milisegundos) antes de capturar la pantalla inmediatamente después de obtener el permiso, para evitar el problema de obstrucción descrito.\n\nEsta opción solo se aplica a la primera captura tras obtener el permiso; las capturas posteriores no se verán afectadas por este valor. - Tiempo de retraso - Inicio - No se pudo cambiar el estado del interruptor - Para garantizar que los servicios en primer plano de AutoJs6, etc. funcionen correctamente y que los scripts puedan publicar notificaciones, AutoJs6 debe recibir el permiso de \"publicar notificaciones\". - \"Ubicación del puntero\" es una función de depuración en las opciones de desarrollador de Android.\nAl activarla, el sistema mostrará en pantalla información del/de los punto(s) de toque, como [coordenadas/trayectoria de movimiento/cantidad/tamaño/velocidad de movimiento/presión], lo que facilita la [escritura/depuración/verificación] de los scripts relacionados. - Se produjo un error - Gestión de permisos - Gestión de servicios - El servicio en primer plano permite mantener la app y los scripts en ejecución de forma más estable en segundo plano - - + \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b356d9a0..79109aaa 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -5,7 +5,6 @@ - Construire... Nettoyage... Emballage... @@ -50,7 +49,8 @@ La configuration \"abi\" contient des options non disponibles La configuration \"lib\" contient des options invalides La configuration \"lib\" contient des options non disponibles - Fichier déjà existant.>Surécrire ? + Le dossier existe deja. Ecraser? + Le fichier existe deja. Ecraser? 1. Appuyez et maintenez le nom de l\'application (AutoJs6) sur la page d\'accueil pour accéder à la page des paramètres.\n2. Appuyez et maintenez une certaine option de paramètres sur la page de paramètres pour afficher des informations détaillées. La couleur du thème actuel %1$s est configurée par la palette de couleurs Un bouton d\'action flottant pour afficher le manifeste @@ -94,12 +94,14 @@ Le mode nuit (également connu sous le nom de thème sombre) s\'applique à la fois à l\'interface utilisateur du système Android et aux applications exécutées sur l\'appareil, ce qui améliore la visibilité pour les utilisateurs malvoyants et ceux qui sont sensibles à la lumière vive, et facilite l\'utilisation d\'un appareil par quiconque dans un environnement à faible luminosité.\n\nSystème de suivi : AutoJs6 possède des paramètres de mode nuit identiques à ceux du système Android\nToujours activé: AutoJs6 maintient le mode Nuit activé (indépendamment des paramètres du système Android).\nToujours désactivé: AutoJs6 désactive le mode Nuit (indépendamment des paramètres du système Android).\n\nRemarque : l\'option Suivre le système n\'est disponible qu\'à partir du niveau 28 de l\'API Android (Android 9) [P]. Pour activer le mode Nuit dans le système Android :\n- Niveau 29 de l\'API Android (Android 10) [Q] et supérieur : Paramètres -> Affichage -> Thème.\n- Niveau 28 de l\'API Android (Android 9) [P]: Options du développeur -> Mode nuit.\n\nLes conditions suivantes doivent être remplies pour appliquer un mode nuit (thème sombre) à un contenu Web à l\'aide d\'un composant WebView (comme la page de documentation AutoJs6) :\n1. WebView du système Android (ou des navigateurs comme Google Chrome) :\n- Android API Level 29 (Android 10) [Q] et plus : version >= 76\n- API Android Niveau 28 (Android 9) [P]: version >= 105\n2. Le contenu Web du composant WebView est adapté au thème sombre (par des ressources CSS ou Android XML, etc.). L\'autorisation \"accès aux notifications\" (ou \"autorisation de lecture des notifications\") permet à AutoJs6 de lire le contenu des notifications système, afin que les scripts puissent écouter des notifications ou récupérer le texte des notifications, etc. + \"Emplacement du pointeur\" est une fonctionnalité de débogage dans les options pour les développeurs d\'Android.\nUne fois activée, le système affiche à l\'écran des informations sur le(s) point(s) de contact, telles que [coordonnées/trajectoire de déplacement/nombre/taille/vitesse de déplacement/pression], ce qui facilite [l\'écriture/le débogage/la vérification] des scripts associés. L\'autorisation \"envoyer des notifications\" permet à AutoJs6 de publier des notifications dans le système, afin que les scripts puissent publier et gérer des notifications personnalisées dans le panneau de notifications.\n\nNote: sur les appareils Android 13+, si cette autorisation n\'est pas accordée, certaines notifications peuvent ne pas s\'afficher, et cela peut affecter le démarrage et la stabilité des services au premier plan. Avec l\'accès aux médias du projet, l\'avertissement de sécurité pour l\'enregistrement d\'écran ne sera pas demandé. La stratégie de redémarrage n\'affecte que le bouton de redémarrage dans le tiroir de la page d\'accueil.\n\nRedémarrage rapide : redémarre rapidement l\'application. Si le redémarrage échoue ou qu\'un comportement inattendu survient, essayez de passer à \"Redémarrage planifié\".\nRedémarrage planifié : configure à l\'avance une tâche de courte durée. Après l\'arrêt de l\'application, elle redémarrera selon la planification afin de relancer l\'application. Interrupteur activé (par défaut) : les valeurs retournées par les méthodes Java de type Number/Boolean/Character sont encapsulées comme objets Java et exposées au script (String exclu). typeof vaut \"object\", species vaut \"JavaObject\" ; les méthodes Java restent accessibles, ce qui permet de conserver les caractéristiques de type précises de Java et la résolution de surcharge.\n\nInterrupteur désactivé : les types ci‑dessus ne sont plus encapsulés et sont exposés directement comme primitives JavaScript (number/boolean/chaîne à un seul caractère). typeof correspond au type JavaScript respectif, plus conforme à la sémantique/à l\'écosystème JavaScript. Il est toujours possible de déclarer explicitement un wrapper Java avec new, par ex. new java.lang.Boolean(true).\n\nVoir : http://issues.autojs6.com/435 Si vous avez un accès exotique à la racine ou un état anormal pour l\'accès à la racine, vous pouvez forcer le réglage de la racine sur racine ou non-racine. Type binaire : non modifiable, avec l\'extension de fichier \"auto\".\nType JavaScript : peut être édité ou copié directement, avec l\'extension de fichier \"js\". + Lors de la demande d\'autorisation de capture d\'écran, la fenêtre de demande affichée peut comporter une animation de fondu lors de sa disparition. Si `images.captureScreen` est appelé immédiatement, la capture obtenue peut contenir le contenu de cette fenêtre et être partiellement masquée.\n\nLa valeur de cette option ajoute un délai (en millisecondes) avant d\'effectuer la capture juste après l\'obtention de l\'autorisation, afin d\'éviter le problème de masquage ci-dessus.\n\nCette option ne s\'applique qu\'à la première capture après l\'obtention de l\'autorisation ; les captures suivantes ne seront plus affectées par cette valeur. Le mode serveur permet à AutoJs6 de démarrer un service sur l\'appareil actuel et d\'attendre des connexions de clients externes afin d\'effectuer [ transfert de scripts / impression des journaux / contrôle à distance ].\n\nLe mode serveur d\'AutoJs6 prend en charge deux modes de connexion:\n1. Réseau local (LAN)\n2. Android Debug Bridge (ADB) Shizuku vous permet d\'obtenir des privilèges ADB et d\'accéder aux API du système Le mode stable le rend plus stable lors de l\'obtention des limites de mise en page, mais certains résultats peuvent être ignorés.\nA11y service\'s restart required. @@ -111,6 +113,8 @@ Paramètres de sécurité du système, contenant les préférences du système que les applications peuvent lire mais ne sont pas autorisées à écrire.\nIl s\'agit des préférences que l\'utilisateur doit explicitement modifier par le biais de l\'interface utilisateur d\'une application système.\nAvec l\'autorisation de paramètres de sécurité du système, les applications normales peuvent directement modifier les paramètres de sécurité (comme le service d\'accessibilité). L\'autorisation \"modifier les paramètres système\" permet à AutoJs6 de modifier certains paramètres système, afin que les scripts puissent changer des réglages tels que [ luminosité de l\'écran / rotation automatique / délai d\'extinction de l\'écran ]. Abandonner + Interrompre + Interrompre la connexion Avancé Corriger l\'adresse @string/text_back @@ -128,10 +132,11 @@ Détails Infos fichier Histoire + Accueil Ignorer - Interrompre la connexion Joindre groupe Gestionnaire + Réduire Plus Palette Quit @@ -191,6 +196,7 @@ La méthode %s a été abandonnée et ne doit pas être utilisée L\'opération \"%1$s\" ne peut pas être terminée car le paramètre contient des valeurs de coordonnées négatives (%2$d, %3$d) Une activité est requise, qui pourrait être fournie en exécutant en mode d\'exécution \"ui\" + Une erreur s\'est produite Une opération n\'est pas mise en œuvre L\'application n\'est pas installée L\'application n\'est pas installée : \"%s\" @@ -229,8 +235,10 @@ Hauteur excessive : modèle [%1$d] > région [%2$d] Largeur excessive : modèle [%1$d] > région [%2$d] Échec de l\'application de l\'historique de la couleur actuelle + Échec de la liaison du service du plugin %1$s. Échec de l\'appel à la méthode \"%s\" + Échec de la modification de l\'état de l\'interrupteur Échec de la conversion de la valeur %s en un objet à dessiner Échec d\'ouverture de la page des paramètres Échec de l\'octroi de la permission de Shizuku @@ -274,6 +282,7 @@ AutoJs6 peut ne pas avoir l\'accès root pour exécuter le fichier \"auto\". %s() appelé avec un argument nul : %s La méthode n\'accepte qu\'un nombre d\'arguments dans la plage [%1$d..%2$d] + Plugin requis manquant pour \"%1$s\". Veuillez installer le plugin et réessayer. Le module \"%s\" ne fonctionne pas en raison de l\'absence des fichiers de bibliothèque nécessaires Le service d\'accessibilité est désactivé et le script s\'est arrêté. Le service d\'accessibilité n\'est pas activé. @@ -284,8 +293,12 @@ Aucune application disponible pour lire ce fichier Aucune application disponible pour envoyer ce fichier Aucune application disponible pour afficher ce fichier + Aucune variante de plugin %1$s activée et disponible n\'a été trouvée (%2$s). Aucune URL disponible n\'a été fournie pour le plug-in actuel Aucune permission \"display over other apps\" + Aucune ressource Paddle OCR intégrée n\'a été trouvée. Veuillez reconditionner avec Paddle OCR activé. + Aucun plugin activé pour \"%1$s\". Veuillez activer un plugin et réessayer. + Aucun plugin Paddle OCR disponible Pas de permission pour accéder à Shizuku Pas d\'autorisation pour les \"notifications d\'envoi\" Aucune autorisation de \"lire l\'état du téléphone\" @@ -298,6 +311,10 @@ Failed to parse GitHub release assets Fail to parse version information Syntaxe de motif invalide + L\'APK du plugin ne contient pas les ressources requises pour variant=\"%1$s\": %2$s. + L\'APK du plugin ne contient pas les bibliothèques natives requises: %1$s. + Le plugin %1$s a renvoyé des informations vides. + Le plugin %1$s a renvoyé une variante invalide: %2$s. Numéro de port supérieur à 65535 Le fichier de script principal du projet \"%1$s\" n\'existe pas Cannot put value %s into JSON @@ -316,6 +333,7 @@ Le numéro de version AutoJs6 spécifié doit être supérieur à 461 Le transformateur pour la propriété requise \"%1$s\" ne peut pas retourner une valeur nulle Thread n\'est pas vivant + Délai d\'attente dépassé lors de la requête des informations du plugin %1$s. Impossible d\'utiliser le service Shizuku Caractère inacceptable Erreur inconnue @@ -404,6 +422,7 @@ Activer le service d\'accessibilité avec accès root automatiquement lorsque cela est nécessaire. Activer le service d\'accessibilité avec des paramètres sécurisés automatiquement lorsque cela est nécessaire. Augmenter la flexibilité du code et permettre une fonctionnalité plus riche en étendant les objets intégrés JavaScript. + Le service au premier plan permet de maintenir l\'application et les scripts en cours d\'exécution de manière plus stable en arrière-plan Prévenir les actions d\'automatisation des scripts lorsque AutoJs6 est au premier plan. Exécutez directement le script sans afficher l\'activité principale. Permet à AutoJs6 de créer et d\'envoyer des notifications @@ -416,10 +435,12 @@ Démarrer ou arrêter l\'enregistrement contrôlé par la touche de réduction du volume lorsque le bouton flottant est affiché. Appuyez sur la touche \"Volume fort\" pour arrêter tous les scripts en cours d\'exécution. Consulter l\'historique des versions publiées et les statistiques + Stockage interne Service d\'accessibilité Requise par le fonctionnement automatique du script (clic, appui long, glissement, etc.). Service d\'accessibilité activé mais non exécuté (réactivation ou redémarrage du périphérique). Un service d\'accessibilité peut être nécessaire + Interruption... A propos A propos de l\'accès à tous les fichiers A propos de l\'application et du développeur @@ -442,6 +463,7 @@ alias L\'alias ne peut pas être vide Mot de passe de l\'alias + Tous Accès à tous les fichiers L\'option \"Accès à tous les fichiers\" est nécessaire pour accéder aux fichiers de script sur le téléphone. Tous les historiques @@ -494,7 +516,7 @@ Code de la version de l\'application Nom de la version de l\'application Appearance - Au moins un champ parmi \"Nom complet, Nom de l\'organisation, Unité organisationnelle, Code du pays, État ou province, Ville ou localité, Rue\" doit être renseigné + Au moins un champ parmi [Nom complet, Nom de l\'organisation, Unité organisationnelle, Code du pays, État ou province, Ville ou localité, Rue] doit être renseigné Attribut Vérification automatique des mises à jour Vérification automatique des mises à jour et affichage d\'un snackbar sur la page d\'accueil @@ -578,7 +600,11 @@ Copier tous les fichiers dans un nouveau répertoire Copie de cmd Copie du journal de débogage + Copier le fichier + Copier le dossier Copie de la ligne + Le chemin source est identique au chemin de destination. Continuer la copie?\n\nNouveau nom: \"%1$s\". + Copier vers Copie vers le presse-papiers Copie de la valeur Code du pays (XX) @@ -601,10 +627,14 @@ Default Magasin de clés par défaut Préfixe par défaut + Délai Suppression Tout supprimer + Supprimer le fichier + Supprimer le dossier Supprimer la ligne Description + Destination Détails Les détails du développeur sont en cours de développement Les options du développeur @@ -617,7 +647,7 @@ Nom du produit de l\'appareil Résolution d\'écran de l\'appareil Téléchargement immédiat - Directory + Repertoire Désactivé Affichage sur les autres apps La permission \"Display over other apps\" est recommandée pour que tous les widgets s\'affichent correctement. @@ -714,6 +744,7 @@ Précé Nom complet Bouton flottant + Dossier Force stop Service d\'avant-plan Formatage terminé @@ -755,6 +786,7 @@ Installer depuis \"URL\" Installer le plugin depuis \"URL\" Installable + Installé Échec de la vérification de l\'intégrité Caractère invalide est supprimé Nom de paquet non valide @@ -810,7 +842,12 @@ \"Mobile QQ\" non installé Plus Détails + Deplacer + Le chemin source est identique au chemin de destination; deplacement annule. Déplacer tous les fichiers dans un nouveau répertoire. + Deplacer le fichier + Deplacer le dossier + Deplacer vers Options multiples Nom Nécessité d\'activer le service d\'accessibilité @@ -838,6 +875,7 @@ Aucun accès root Pas de scripts à arrêter de fonctionner Non accordée + Non installé Not showing main activity Notification Accès à la notification @@ -852,6 +890,8 @@ Ouvrir par d\'autres apps Ouvrir l\'activité principale Ouvrir avec + Interrompu + Termine L\'opération est terminée Options Nom de l\'organisation @@ -940,6 +980,7 @@ L\'autorisation n\'a pas été accordée (avec Shizuku) Permission accordée (avec root) Permission accordée (avec Shizuku) + Gestion des autorisations Autoriser l\'application à accéder aux statistiques d\'utilisation d\'autres applications Permission révoquée Fail to revoked permission (with root). @@ -963,6 +1004,7 @@ L\'emplacement du pointeur Toggle \"pointer location\" failed.\nL\'accès à la racine est nécessaire. Notifications postales + Afin de garantir que les services au premier plan d\'AutoJs6, etc. fonctionnent correctement et que les scripts puissent publier des notifications, AutoJs6 doit se voir accorder l\'autorisation de \"publier des notifications\". Pré-exécution du script Préparation... Contenu de la boîte de dialogue prédéfinie @@ -977,6 +1019,9 @@ Localisation du projet Accès aux médias du projet Prompt + %1$s : %2$s + %1$s : %2$d %3$s + %1$s : %2$d%3$s Quit Recommandé Enregistrement terminé @@ -1045,6 +1090,7 @@ Save to Moteur Délai de démarrage + Délai de demande d\'autorisation de capture d\'écran Enregistrement de scripts Script running Recherche @@ -1064,6 +1110,7 @@ Créer un raccourci Mode serveur Service + Gestion des services Comme répertoire de travail Définir un point d\'arrêt Réglages @@ -1080,6 +1127,10 @@ Taille %d items exported Trier + Trier par dernière mise à jour + Trier par nom + Trier par taille du paquet + Source Chemin du code source Autorisations spéciales Mode stable @@ -1172,36 +1223,4 @@ Écrire les paramètres de sécurité. Écrire les paramètres système Fenêtres contextuelles en arrière-plan - Aucun plugin Paddle OCR disponible - Installé - Non installé - Tous - Trier par nom - Trier par dernière mise à jour - Trier par taille du paquet - Plugin requis manquant pour \"%1$s\". Veuillez installer le plugin et réessayer. - Aucun plugin activé pour \"%1$s\". Veuillez activer un plugin et réessayer. - Aucune variante de plugin %1$s activée et disponible n\'a été trouvée (%2$s). - L\'APK du plugin ne contient pas les ressources requises pour variant=\"%1$s\": %2$s. - L\'APK du plugin ne contient pas les bibliothèques natives requises: %1$s. - Échec de la liaison du service du plugin %1$s. - Délai d\'attente dépassé lors de la requête des informations du plugin %1$s. - Le plugin %1$s a renvoyé des informations vides. - Le plugin %1$s a renvoyé une variante invalide: %2$s. - Aucune ressource Paddle OCR intégrée n\'a été trouvée. Veuillez reconditionner avec Paddle OCR activé. - Réduire - %1$s : %2$d%3$s - %1$s : %2$d %3$s - Délai de demande d\'autorisation de capture d\'écran - Lors de la demande d\'autorisation de capture d\'écran, la fenêtre de demande affichée peut comporter une animation de fondu lors de sa disparition. Si `images.captureScreen` est appelé immédiatement, la capture obtenue peut contenir le contenu de cette fenêtre et être partiellement masquée.\n\nLa valeur de cette option ajoute un délai (en millisecondes) avant d\'effectuer la capture juste après l\'obtention de l\'autorisation, afin d\'éviter le problème de masquage ci-dessus.\n\nCette option ne s\'applique qu\'à la première capture après l\'obtention de l\'autorisation ; les captures suivantes ne seront plus affectées par cette valeur. - Délai - Accueil - Échec de la modification de l\'état de l\'interrupteur - Afin de garantir que les services au premier plan d\'AutoJs6, etc. fonctionnent correctement et que les scripts puissent publier des notifications, AutoJs6 doit se voir accorder l\'autorisation de \"publier des notifications\". - \"Emplacement du pointeur\" est une fonctionnalité de débogage dans les options pour les développeurs d\'Android.\nUne fois activée, le système affiche à l\'écran des informations sur le(s) point(s) de contact, telles que [coordonnées/trajectoire de déplacement/nombre/taille/vitesse de déplacement/pression], ce qui facilite [l\'écriture/le débogage/la vérification] des scripts associés. - Une erreur s\'est produite - Gestion des autorisations - Gestion des services - Le service au premier plan permet de maintenir l\'application et les scripts en cours d\'exécution de manière plus stable en arrière-plan - - + \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index e34e7dca..ccbff6e2 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -6,7 +6,6 @@ - 建築... 洗浄... パッケージング... @@ -51,7 +50,8 @@ 設定 \"abi\" に利用できないオプションが含まれています 設定 \"lib\" に無効なオプションが含まれています 設定 \"lib\" に利用できないオプションが含まれています - ファイルはすでに存在します.\n上書きしますか? + フォルダーは既に存在します. 上書きしますか? + ファイルは既に存在します. 上書きしますか? 1. ホーム画面でアプリケーション名 (AutoJs6) を長押しして, 設定画面にジャンプする\n2. 設定ページで特定の設定オプションを長押しすると, 詳細情報が表示されます 現在のテーマカラー %1$s はカラーパレットで設定されています マニフェストを表示するためのフローティング操作ボタン部品 @@ -67,8 +67,8 @@ スクリプトからの通知 スクリプト通知 /スクリプト - AutoJs6 は, Android 用の JavaScript 自動化ツールで, 「hyb1996/Auto.js」をクローンしたオープンソースです.\n\nヘルプやフィードバックを求めるには, GitHub issues に行くか, Tencent QQ チャットグループ 690946137 に参加してください - 1. アプリと開発者について」ページでアプリのアイコンを長押しすると, AutoJs6 の開発者向けオプションページにジャンプします + AutoJs6 は, Android 用の JavaScript 自動化ツールで, [hyb1996/Auto.js] をクローンしたオープンソースです.\n\nヘルプやフィードバックを求めるには, GitHub issues に行くか, Tencent QQ チャットグループ 690946137 に参加してください + 1. アプリと開発者について ページでアプリのアイコンを長押しすると, AutoJs6 の開発者向けオプションページにジャンプします アクセシビリティサービスは, AutoJs6 が自動化を実現するための中核機能です. 画面上のウィジェット情報を読み取り, [ タップ / スワイプ / 入力 ] などの操作をシミュレートします.\n\n自動化関連の大半の機能やレイアウト解析ツールなどは, アクセシビリティサービスを有効にしないと正常に動作しません. \"すべてのファイルを管理\" (または \"すべてのファイルへのアクセス\") 権限により, AutoJs6 は共有ストレージ上で通常のファイルパスを使って直接 [ 作成 / 読み取り / 変更 / 削除 ] を行えます. これによりスクリプトは \"Internal Storage\" にアクセスでき, ファイルマネージャーもファイルを正常に表示・管理できます.\n\nAndroid 11+ では, フルストレージの読み書きを実現する主要な方法です. この環境設定は, 実行中のスクリプトからの例外メッセージを含む, AutoJs6 の表示言語を変更するためのものです.\n\n注: 言語を期待通りに適用するには, アプリの再起動が必要な場合があります @@ -84,7 +84,7 @@ AutoJs6のファイルエクスプローラーでファイル拡張子を表示するかどうかの設定に使用されます. フローティングボタンは, 画面端にドラッグ可能なクイック入口を表示し, [ スクリプトの開始/停止 / レイアウト解析 / 最近のパッケージ名やアクティビティ名の表示 / ポインター位置の表示 ] などに利用できます.\n\nNote: この機能は通常, \"他のアプリの上に表示\" 権限が必要です. フォアグラウンドサービスは, AutoJs6 をバックグラウンドでもより安定して動作させるための機能で, [ 長時間スクリプト実行 / 接続の維持 / 継続的な監視 ] などの用途に適しています.\n\n有効化すると, システムは \"フォアグラウンドサービス通知\" を表示して AutoJs6 が継続稼働中であることをユーザーに知らせます. この通知は通常, サービスが停止するまで表示され続けます.\n\n通知を \"Silent\" または \"Minimize\" に設定しても, 通知の強さが下がるだけで, 一般的にフォアグラウンドサービス機能には影響しません.\n\n通知チャネルを無効化したり AutoJs6 の通知送信を禁止したりすると, フォアグラウンドサービスの正常な起動や安定性に影響する可能性があります. - AutoJs6 ファイルエクスプローラーで隠しファイルや隠しフォルダ (通常は「.」で始まる) を表示するかどうかを設定するために使用します + AutoJs6 ファイルエクスプローラーで隠しファイルや隠しフォルダ (通常は [.] で始まる) を表示するかどうかを設定するために使用します バッテリー最適化の無視により, AutoJs6 に対するバックグラウンド制限を緩和でき, スケジュールタスクや長時間スクリプトが待機中でも比較的安定して動作しやすくなります.\n\nNote: メーカーにより, 追加の省電力ポリシー (自動起動制限, バックグラウンド凍結など) が存在する場合があります. AutoJs6 が前面にあるときに画面を常時点灯させるかどうかを制御します. AutoJs6 がフォアグラウンドにあるとき, デバイスの画面をオンにして明るく保つための設定です.\nAutoJs6 アプリケーションの全ページのうち, ホームページでのみ使用する場合は, \"ホームページのみ\" オプションを選択します @@ -95,12 +95,14 @@ ナイトモード (ダークテーマとも呼ばれる) は, Android システムの UI と端末上で動作するアプリケーションの両方に適用され, 弱視のユーザーや明るい光に敏感なユーザーの視認性を向上させ, 誰でも簡単に暗い環境下で端末を使用できるようにします.\n\nフォローシステム AutoJs6 では, Android と同じ Night モードが設定できます.\n常にオン Android のシステム設定に関係なく, 常に Night モードが ON になります.\n常にオフ Android のシステム設定に関係なく, AutoJs6 はナイトモードをオフにします.\n\n注: Follow system オプションは, Android API Level 28 (Android 9) [P] 以上の場合のみです Android システムでナイトモードを有効にするには\n- Android API Level 29 (Android 10) [Q] 以上の場合: [設定] -> [ディスプレイ] -> [テーマ].\n- Android API Level 28 (Android 9) [P]: [開発者向けオプション] -> [ナイトモード].\n\nWebView コンポーネント (AutoJs6 のドキュメントページなど) を使って, Web ベースのコンテンツにナイトモード (ダークテーマ) を適用するには, 以下の条件を満たす必要があります.\n1. Android System WebView (または Google Chrome のようなブラウザ) .\n- Android API Level 29 (Android 10) [Q] 以上: バージョン >= 76\n- Android API Level 28 (Android 9) [P]: バージョン >= 105\n2. WebView コンポーネントの Web ベースのコンテンツは, Dark テーマに適合している (CSS や Android XML リソースなどによる) \"通知へのアクセス\" (または \"通知読み取り権限\") により, AutoJs6 はシステム通知の内容を読み取れるようになり, スクリプトで通知を監視したり通知テキストを取得したりできます. + \"ポインタの位置\" は Android の開発者向けオプションにあるデバッグ機能です.\n有効にすると, システムが画面上にタッチポイントの [座標/移動軌跡/数/サイズ/移動速度/圧力] などの情報を表示し, 関連スクリプトの [作成/デバッグ/検証] に役立ちます. \"通知の送信\" 権限により, AutoJs6 はシステムに通知を投稿でき, スクリプトで通知バーへカスタム通知を投稿・管理できます.\n\nNote: Android 13+ 端末でこの権限が付与されていない場合, 一部の通知が表示されない可能性があり, フォアグラウンドサービスの起動や安定性に影響することがあります. プロジェクトのメディアアクセス権を使用すると, 画面録画のセキュリティ警告が表示されなくなります 再起動戦略はホームページのドロワーにある再起動ボタンにのみ適用されます.\n\nクイック再起動: アプリをすばやく再起動します. 再起動に失敗したり予期しない状況が発生した場合は/\"スケジュール再起動\" に切り替えてください.\nスケジュール再起動: あらかじめ短時間のタイマーを設定します. アプリが停止した後/スケジュールに従って再度起動し/アプリの再起動を実現します. スイッチ有効 (デフォルト): Java メソッドが返す Number/Boolean/Character は Java オブジェクトとしてラップされ/スクリプトに公開されます (String は除外). typeof は \"object\"/species は \"JavaObject\". Java のメソッドを呼び出せるため/Java の厳密な型特性やオーバーロード解決を保持しやすくなります.\n\nスイッチ無効: 上記の型はラップされず/JavaScript のプリミティブ値 (number/boolean/1 文字の文字列) として直接公開されます. typeof は対応する JavaScript 型となり/JavaScript のセマンティクス/エコシステムにより沿います. 必要なら new によって明示的に Java ラッパーを生成できます (例: new java.lang.Boolean(true)).\n\n参照: http://issues.autojs6.com/435 異国の root や root アクセスに異常がある場合, root を強制的に root または non-root に設定することができます バイナリタイプ: 編集不可, ファイル拡張子は \"auto\"\nJavaScript タイプ: 直接編集またはコピー可能, ファイル拡張子は \"js\" + 画面キャプチャ権限を要求する際, 表示される権限リクエスト画面が閉じるときにフェード等のアニメーションが発生する場合があります. この直後に `images.captureScreen` を呼び出すと, 取得したスクリーンショットに権限リクエスト画面の内容が写り込み, 遮蔽が発生することがあります. \n\nこの設定値は, 権限取得直後に最初のスクリーンショットを取得する前に遅延時間(ミリ秒)を追加し, 上記の遮蔽問題を回避するために使用します. \n\nこの設定は権限取得後の最初のスクリーンショットにのみ適用され, 以降のスクリーンショットには影響しません. サーバーモードは, AutoJs6 が端末上でサービスを起動して外部クライアントからの接続を待ち, [ スクリプト転送 / ログ出力 / リモート制御 ] などを行うための機能です.\n\nAutoJs6 のサーバーモードは 2 つの接続方式に対応しています:\n1. LAN\n2. Android Debug Bridge (ADB) Shizuku を使用すると, ADB 権限を取得し, システム API にアクセスできるようになります 安定モードにするとレイアウト境界を取得する際に安定しますが, 一部の結果が無視されることがあります.\nアクセシビリティサービスの再起動が必要です @@ -112,6 +114,8 @@ アプリケーションが読み取ることはできるが, 書き込むことはできないシステム環境設定を含む, 安全なシステム設定です.\nこれは, ユーザーがシステムアプリの UI を通じて明示的に変更する必要がある環境設定のためのものです.\nセキュアなシステム設定を許可すると, 通常のアプリケーションはセキュアな設定 (アクセシビリティサービスなど) を直接変更できるようになります \"システム設定の変更\" 権限により, AutoJs6 は一部のシステム設定を変更でき, スクリプトで [ 画面の明るさ / 自動回転 / 画面タイムアウト ] などを調整できます. 放棄 + 中止 + 接続を中止 詳細 アドレスを修正 @string/text_back @@ -129,10 +133,11 @@ 詳細 ファイル情報 履歴 + ホームページ 無視する - 接続を中止 グループ参加 マネージャー + 最小化 詳細 パレットを開く 終了する @@ -171,7 +176,7 @@ すべてのファイル拡張子を隠す すべてのファイル拡張子を表示する 実行可能ファイル (*.js / *.auto を除く) の拡張子を表示する - 「隠しファイルや隠しフォルダーを表示しない + 隠しファイルや隠しフォルダーを表示しない 隠しファイルや隠しフォルダーを表示する 全ページ 使用不可 @@ -192,6 +197,7 @@ メソッド %s は放棄されたので, 使用しないでください \"%1$s\" 操作はパラメータに負の座標値 (%2$d, %3$d) が含まれているため, 完了できません UI 実行モードに必要なアクティビティが不足しています + エラーが発生しました 操作が実装されていません アプリがインストールされていません \"%s\" アプリがインストールされていません @@ -230,8 +236,10 @@ 高さ超過: テンプレート [%1$d] > 領域 [%2$d] 幅が超過しています: テンプレート [%1$d] > 領域 [%2$d] 現在のカラー履歴の適用に失敗しました + %1$s プラグインサービスのバインドに失敗しました. メソッド \"%s\" の呼び出しに失敗しました + スイッチの状態の変更に失敗しました 値 %s を Drawable に変換するのに失敗しました 設定画面を開けませんでした Shizuku の権限付与に失敗しました @@ -251,10 +259,10 @@ パス \"%1$s\" にファイルが存在しません \"UI スレッドをブロックできません. サブスレッドまたはサブスクリプトで %s() を実行してみてください %s() が複数回呼び出されました - 「最新の GitHub リリースを取得できません + 最新の GitHub リリースを取得できません ハンドシェイクは %d ms 後にタイムアウトしました 不正な引数 %s: %s - 「ベース URL がないと相対 URL を使用できません + ベース URL がないと相対 URL を使用できません 結果タイプ \"%s\" は UiObject ではサポートされません URL は \"https://\" などのようにプロトコルで開始する必要があります パラメータ %s (%s) は, %s 型にキャストする必要があるか, キャストできます @@ -275,6 +283,7 @@ AutoJs6 は \"auto\" ファイルを実行するためのルート・アクセス権を持っていない可能性があります null 引数で %s() が呼び出されました: %s メソッドは [%1$d..%2$d] の範囲の引数しか受け付けません + \"%1$s\" に必要なプラグインが見つかりません. プラグインをインストールしてから再試行してください. 必要なライブラリ・ファイルがないため, \"%s\" モジュールが動作しません アクセシビリティサービスが無効で, スクリプトが停止しています アクセシビリティサービスが有効になっていない @@ -285,11 +294,15 @@ このファイルを再生できるアプリがありません このファイルを送信できるアプリがありません このファイルを表示できるアプリがありません + 利用可能で有効化された %1$s プラグインの variant が見つかりません (%2$s). 現在のプラグインに利用可能な URL は提供されていません - 他のアプリの上に表示する」権限がない + 他のアプリの上に表示する 権限がない + 埋め込みの Paddle OCR assets が見つかりません. Paddle OCR を有効にして再パッケージしてください. + \"%1$s\" に有効化されたプラグインがありません. プラグインを有効化してから再試行してください. + 利用可能な Paddle OCR プラグインが見つかりません Shizuku にアクセスする権限がありません \"投稿通知\" 許可なし - 電話の状態を読む」権限がない + 電話の状態を読む 権限がない 画面キャプチャ許可がありません \"ストレージ R/W\" 権限なし そのようなセレクタ・メソッドはありません %s(%s: %s) @@ -299,6 +312,10 @@ GitHub リリース・アセットの解析に失敗しました バージョン情報の解析に失敗しました 無効なパターン構文 + プラグイン APK に variant=\"%1$s\" に必要な assets が含まれていません: %2$s. + プラグイン APK に必要な native ライブラリが含まれていません: %1$s. + %1$s プラグインが空の info を返しました. + %1$s プラグインが無効な variant を返しました: %2$s. 65535 を超えるポート番号 プロジェクトのメインスクリプトファイル \"%1$s\" が存在しません \"値 %s を JSON に入れることができません\" というメッセージが表示されます @@ -317,6 +334,7 @@ 指定された AutoJs6 のバージョン番号は 461 より大きくなければなりません 必要なプロパティ \"%1$s\" のトランスフォーマーは null を返すことができません スレッドが生きていない + %1$s プラグイン情報の取得がタイムアウトしました. Shizuku サービスが使用できない 使用できない文字 不明なエラー @@ -340,7 +358,7 @@ ファイルは %s にダウンロードされました アクセシビリティサービス -> AutoJs6 [を有効にする]]> Regex に対応しています. キャプチャしたグループには, \"$1\" 〜 \"$9\" を使用します - 実行」ボタン長押しでデバッグ + 実行 ボタン長押しでデバッグ ループ前の遅延時間 無限ループの場合は 0 IPv4/IPv6/およびドメイン名に対応しています. @@ -405,6 +423,7 @@ 必要なときに自動的に root 権限でアクセシビリティサービスを有効にする 必要なときに自動的にセキュアな設定のアクセシビリティサービスを有効にする JavaScript の組み込みオブジェクトを拡張することで, コードの柔軟性を高め, より豊かな機能を実現します + フォアグラウンドサービスは, バックグラウンドでアプリとスクリプトの実行をより安定して維持します AutoJs6 がフォアグラウンドにあるときにスクリプトから自動化アクションが実行されないようにする メインのアクティビティを表示せずにスクリプトを直接実行 AutoJs6 が通知を作成して送信することを許可します @@ -417,10 +436,12 @@ フローティングボタンが表示されているときに, \"Volume Down\" キーで録画の開始/停止を制御できるようになりました \"Volume Up\" キーを押すと, 実行中のスクリプトをすべて停止します リリース版の変更履歴と統計データを確認する + 内部ストレージ アクセシビリティサービス スクリプトの自動操作 (クリック, 長押し, スライドなど) で必要です アクセシビリティサービスが有効だが, 実行されていない (デバイスを再有効化または再起動する) アクセシビリティサービスが必要な場合がある + 中止しています... について 全ファイルのアクセスについて アプリと開発者について @@ -443,6 +464,7 @@ 別名 エイリアスは空にできません エイリアスのパスワード + すべて 全ファイルアクセス 携帯電話上のスクリプトファイルにアクセスするために, \"すべてのファイルへのアクセス\" が必要です すべての履歴 @@ -495,7 +517,7 @@ アプリバージョンコード アプリのバージョン名 外観 - 「氏名, 組織名, 組織単位, 国コード, 州または省, 市区町村, 街」のいずれかの項目を入力する必要があります + [氏名, 組織名, 組織単位, 国コード, 州または省, 市区町村, 街] のいずれかの項目を入力する必要があります 属性 更新の自動チェック 自動的に更新をチェックし, ホームページにスナックバーを表示します @@ -579,7 +601,11 @@ すべてのファイルを新しいディレクトリにコピーします cmd をコピー デバッグログをコピー + ファイルをコピー + フォルダーをコピー 行をコピー + ソースパスと宛先パスが同じです. コピーを続行しますか?\n\n新しい名前: \"%1$s\". + コピー先 クリップボードにコピーする 値をコピーする 国コード (XX) @@ -602,10 +628,14 @@ デフォルト デフォルトのキーストア デフォルトのプレフィックス + 遅延時間 削除 すべて削除 + ファイルを削除 + フォルダーを削除 行削除 説明 + 宛先 詳細 デベロッパーの詳細については, 現在開発中です デベロッパーオプション @@ -715,6 +745,7 @@ 前へ 氏名 フローティングボタン + フォルダー 強制停止 フォアグラウンドサービス フォーマット完了 @@ -756,6 +787,7 @@ \"URL\" からインストール \"URL\" からプラグインをインストール インストール可 + インストール済み 整合性の検証に失敗しました 無効な文字が削除されました パッケージ名が無効です @@ -808,10 +840,15 @@ キーストアを管理 最小バージョン VSCode 拡張機能の最小バージョン - 「モバイル QQ がインストールされていない + モバイル QQ がインストールされていない 詳細 詳細 + 移動 + ソースパスと宛先パスが同じです. 移動を中止しました. すべてのファイルを新しいディレクトリに移動する + ファイルを移動 + フォルダーを移動 + 移動先 複数のオプション 名称 アクセシビリティサービスを有効にする必要があります @@ -839,6 +876,7 @@ ルートアクセス不可 実行を停止するスクリプトなし 許可されない + 未インストール メインのアクティビティが表示されない 通知 通知へのアクセス @@ -853,6 +891,8 @@ 他のアプリで開く メインのアクティビティを開く で開く + 中止 + 完了 操作が完了しました オプション 組織名 @@ -941,6 +981,7 @@ 許可に失敗しました (Shizuku を使用) 許可された (root で) 権限が付与されました (Shizuku を使用) + 権限管理 アプリに他のアプリの使用統計情報にアクセスする権限を与える 許可取り消し 権限の取り消しに失敗しました (ルート) @@ -962,8 +1003,9 @@ プラグイン詳細 Plugins ポインターの位置 - トグル「ポインターの位置」に失敗しました.\nroot 権限が必要です + トグル [ポインターの位置] に失敗しました.\nroot 権限が必要です ゆうびんけいほう + AutoJs6 のフォアグラウンドサービス等が正常に動作し, スクリプトが通知を投稿できるようにするため, AutoJs6 には \"通知の送信\" 権限を付与する必要があります. スクリプトの事前実行 準備中... プリセット・ダイアログ・内容 @@ -978,6 +1020,9 @@ プロジェクトの場所 プロジェクト・メディア・アクセス プロンプト + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s 終了 推奨 記録終了 @@ -1046,6 +1091,7 @@ 保存先 エンジン 開始遅延 + 画面キャプチャ権限リクエスト遅延 スクリプトの記録 スクリプトの実行 検索 @@ -1065,13 +1111,14 @@ ショートカットの作成 サーバーモード サービス + サービス管理 作業ディレクトリに設定する ブレークポイントの設定 設定 SHA-256 が一致しません.\n\n期待値: %1$s\n実際: %2$s Shizuku のパーミッション 最初に Shizuku サービスを実行する必要があるかもしれない - 「テキストを空にすることはできません + テキストを空にすることはできません レイアウト境界内のビュー レイアウト階層内の表示 ウィジェット情報を表示する @@ -1081,6 +1128,10 @@ サイズ エクスポートされた項目 %d 並べ替え + 最終更新日で並べ替え + 名前で並べ替え + パッケージサイズで並べ替え + ソース ソースコードのパス 特殊な権限 安定モード @@ -1141,7 +1192,7 @@ \"Volume Down\" キーで録音を制御 \"Volume Up\" キーでスクリプトの実行を制御します ユーザー名 - 「ユーザー名を空にすることはできません + ユーザー名を空にすることはできません 降順セレクタを使用する ID セレクタを使用する テキストセレクタを使用する @@ -1173,36 +1224,4 @@ セキュリティ設定の書き込み システム設定の書き込み バックグラウンドでのポップアップ表示 - 利用可能な Paddle OCR プラグインが見つかりません - インストール済み - 未インストール - すべて - 名前で並べ替え - 最終更新日で並べ替え - パッケージサイズで並べ替え - \"%1$s\" に必要なプラグインが見つかりません. プラグインをインストールしてから再試行してください. - \"%1$s\" に有効化されたプラグインがありません. プラグインを有効化してから再試行してください. - 利用可能で有効化された %1$s プラグインの variant が見つかりません (%2$s). - プラグイン APK に variant=\"%1$s\" に必要な assets が含まれていません: %2$s. - プラグイン APK に必要な native ライブラリが含まれていません: %1$s. - %1$s プラグインサービスのバインドに失敗しました. - %1$s プラグイン情報の取得がタイムアウトしました. - %1$s プラグインが空の info を返しました. - %1$s プラグインが無効な variant を返しました: %2$s. - 埋め込みの Paddle OCR assets が見つかりません. Paddle OCR を有効にして再パッケージしてください. - 最小化 - %1$s: %2$d%3$s - %1$s: %2$d %3$s - 画面キャプチャ権限リクエスト遅延 - 画面キャプチャ権限を要求する際, 表示される権限リクエスト画面が閉じるときにフェード等のアニメーションが発生する場合があります. この直後に `images.captureScreen` を呼び出すと, 取得したスクリーンショットに権限リクエスト画面の内容が写り込み, 遮蔽が発生することがあります. \n\nこの設定値は, 権限取得直後に最初のスクリーンショットを取得する前に遅延時間(ミリ秒)を追加し, 上記の遮蔽問題を回避するために使用します. \n\nこの設定は権限取得後の最初のスクリーンショットにのみ適用され, 以降のスクリーンショットには影響しません. - 遅延時間 - ホームページ - スイッチの状態の変更に失敗しました - AutoJs6 のフォアグラウンドサービス等が正常に動作し, スクリプトが通知を投稿できるようにするため, AutoJs6 には \"通知の送信\" 権限を付与する必要があります. - \"ポインタの位置\" は Android の開発者向けオプションにあるデバッグ機能です.\n有効にすると, システムが画面上にタッチポイントの [座標/移動軌跡/数/サイズ/移動速度/圧力] などの情報を表示し, 関連スクリプトの [作成/デバッグ/検証] に役立ちます. - エラーが発生しました - 権限管理 - サービス管理 - フォアグラウンドサービスは, バックグラウンドでアプリとスクリプトの実行をより安定して維持します - - + \ No newline at end of file diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 33f2c935..550dc7d4 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -7,7 +7,6 @@ - 건물... 청소... 포장... @@ -52,7 +51,8 @@ 설정 \"abi\" 에 사용할 수 없는 옵션이 포함되어 있습니다 설정 \"lib\" 에 잘못된 옵션이 포함되어 있습니다 설정 \"lib\" 에 사용할 수 없는 옵션이 포함되어 있습니다 - 존재하는 파일입니다.\n덮어 쓰기? + 폴더가 이미 존재합니다. 덮어쓰시겠습니까? + 파일이 이미 존재합니다. 덮어쓰시겠습니까? 1. 홈 페이지에서 애플리케이션 이름 (AutoJs6) 을 길게 눌러 설정 페이지로 이동합니다.\n2. 설정 페이지에서 특정 설정 옵션을 길게 누르면 자세한 정보를 볼 수 있습니다. 현재 테마 색상 %1$s 는 색상 팔레트로 설정되어 있습니다 매니페스트를 표시하기 위한 플로팅 액션 버튼 위젯 @@ -96,12 +96,14 @@ 야간 모드 (다크 테마라고도 함) 는 Android 시스템 UI 와 장치에서 실행되는 앱 모두에 적용되어 저시력 사용자와 밝은 빛에 민감한 사용자의 가시성을 향상시키고 누구나 쉽게 장치를 사용할 수 있습니다. 저조도 환경에서.\n\n시스템 따르기: AutoJs6 에는 Android 시스템과 동일한 야간 모드 설정이 있습니다.\n항상 켜짐: AutoJs6 은 Android 시스템 설정에 관계없이 야간 모드를 유지합니다.\n항상 끄기: AutoJs6 은 야간 모드를 끈 상태로 유지합니다(Android 시스템 설정에 관계없이).\n\n참고: 팔로우 시스템 옵션은 Android API 레벨 28 (Android 9) [P] 이상에만 적용됩니다. Android 시스템에서 야간 모드를 활성화하려면:\n- Android API 레벨 29 (Android 10) [Q] 이상: 설정 -> 디스플레이 -> 테마.\n- Android API 레벨 28 (Android 9) [P]: 개발자 옵션 -> 야간 모드.\n\nWebView 구성 요소(예: AutoJs6 설명서 페이지)를 사용하여 웹 기반 콘텐츠에 야간 모드 (어두운 테마) 를 적용하려면 다음 조건을 충족해야 합니다.\n1. Android 시스템 WebView (또는 Google Chrome 과 같은 브라우저):\n- Android API 레벨 29 (Android 10) [Q] 이상: 버전 >= 76\n- Android API 레벨 28 (Android 9) [P]: 버전 >= 105\n2. WebView 구성 요소의 웹 기반 콘텐츠는 Dark 테마에 맞게 조정됩니다 (CSS 또는 Android XML 리소스 등). \"알림 접근\" (또는 \"알림 읽기 권한\") 은 AutoJs6 가 시스템 알림 내용을 읽을 수 있게 하여, 스크립트가 알림을 감지하거나 알림 텍스트를 가져올 수 있도록 합니다. + \"포인터 위치\" 는 Android 개발자 옵션에 있는 디버깅 기능입니다.\n활성화하면 시스템이 화면에 터치 지점의 [좌표/이동 궤적/개수/크기/이동 속도/압력] 등의 정보를 표시하여 관련 스크립트의 [작성/디버깅/검증] 에 도움이 됩니다. \"알림 전송\" 권한은 AutoJs6 가 시스템에 알림을 게시할 수 있게 하여, 스크립트가 알림 영역에서 사용자 지정 알림을 게시하고 관리할 수 있도록 합니다.\n\nNote: Android 13+ 기기에서 이 권한이 부여되지 않으면 일부 알림이 표시되지 않을 수 있으며, 포그라운드 서비스의 시작 및 안정성에 영향을 줄 수 있습니다. 프로젝트 미디어 액세스를 사용하면 화면 기록에 대한 보안 경고가 중요하지 않습니다. 재시작 전략은 홈 페이지 드로어의 재시작 버튼에만 적용됩니다.\n\n빠른 재시작: 앱을 빠르게 다시 시작합니다. 재시작이 실패하거나 예기치 않은 상황이 발생하면 \"예약 재시작\"으로 전환해 보세요.\n예약 재시작: 미리 짧은 시간의 예약 작업을 설정합니다. 앱이 중지된 후 예약에 따라 다시 시작하여 앱 재시작을 수행합니다. 스위치 활성화(기본값): Java 메서드가 반환하는 Number/Boolean/Character 값은 Java 객체로 래핑되어 스크립트에 노출됩니다(String 제외). typeof 는 \"object\", species 는 \"JavaObject\"이며, Java 메서드 호출이 가능해 Java의 정밀한 타입 특성과 오버로드 해석을 보존하는 데 도움이 됩니다.\n\n스위치 비활성화: 위 타입들을 더 이상 래핑하지 않고 JavaScript 원시 값(number/boolean/한 글자 문자열)으로 직접 노출합니다. typeof 는 해당 JavaScript 타입이 되며, JavaScript의 의미론/생태계에 더 가깝습니다. 필요 시 new 키워드로 Java 래퍼를 명시적으로 생성할 수 있습니다(예: new java.lang.Boolean(true)).\n\n참고: http://issues.autojs6.com/435 뿌리 접근을 위해 이국적인 뿌리 또는 비정상 상태가있는 경우 루트를 루트 또는 뿌리가 아닌 것으로 강제로 설정할 수 있습니다. 바이너리 유형: 편집 불가능, 파일 확장자는 \"auto\"\nJavaScript 유형: 파일 확장자가 \"js\"인 경우 직접 편집하거나 복사할 수 있습니다. + 화면 캡처 권한을 요청할 때 표시되는 권한 요청 창은 사라질 때 페이드 등의 전환 애니메이션이 있을 수 있습니다. 이때 `images.captureScreen` 메서드를 즉시 호출하면, 얻은 스크린샷에 권한 요청 창의 내용이 포함되어 화면이 가려질 수 있습니다.\n\n이 설정 값은 권한을 획득한 직후 첫 스크린샷을 캡처하기 전에 지연 시간(밀리초)을 추가하여, 위와 같은 가림 문제를 방지하는 데 사용할 수 있습니다.\n\n이 설정은 권한 획득 후 첫 번째 캡처에만 적용되며, 이후 캡처에는 더 이상 영향을 주지 않습니다. 서버 모드는 AutoJs6 가 현재 기기에서 서비스를 실행하고 외부 클라이언트 연결을 대기하여 [ 스크립트 전송 / 로그 출력 / 원격 제어 ] 등을 수행할 수 있도록 합니다.\n\nAutoJs6 서버 모드는 두 가지 연결 방식을 지원합니다:\n1. LAN\n2. Android Debug Bridge (ADB) Shizuku 를 사용하면 ADB 권한과 시스템 API 에 대한 액세스 권한을 얻을 수 있습니다 안정 모드는 레이아웃 경계를 얻을 때 더 안정적이지만 일부 결과는 무시할 수 있습니다.\n접근성 서비스의 재시작이 필요합니다. @@ -113,6 +115,8 @@ 애플리케이션이 읽을 수 있지만 쓸 수없는 시스템 환경 설정을 포함하는 보안 시스템 설정.\n이들은 사용자가 시스템 앱의 UI 를 통해 명시 적으로 수정 해야하는 선호도입니다.\n보안 시스템 설정 권한을 사용하면 일반 애플리케이션이 보안 설정 (예: 접근성 서비스)을 직접 수정할 수 있습니다. \"시스템 설정 수정\" 권한은 AutoJs6 가 일부 시스템 설정을 변경할 수 있게 하여, 스크립트가 [ 화면 밝기 / 자동 회전 / 화면 시간 제한 ] 등의 설정을 변경할 수 있도록 합니다. 포기 + 중지 + 연결 중지 고급 주소 수정 @string/text_back @@ -130,10 +134,11 @@ 자세히 파일 정보 역사 + 홈페이지 무시하다 - 연결 중단 그룹 가입 관리자 + 최소화 팔레트 열기 그만두다 @@ -193,6 +198,7 @@ %s 메서드는 중단되었으며 사용해서는 안 됩니다 매개 변수에 음수 좌표 값 (%2$d, %3$d)이 포함되어 있으므로 \"%1$s\" 작업을 완료할 수 없습니다 UI 실행 모드를 위한 활동이 필요합니다 + 오류가 발생했습니다 작업이 구현되지 않았습니다 앱이 설치되지 않았습니다 앱이 설치되지 않았습니다: \"%s\" @@ -231,8 +237,10 @@ 높이 초과: 템플릿 [%1$d] > 영역 [%2$d] 너비 초과: 템플릿 [%1$d] > 영역 [%2$d] 현재 색상 기록 적용에 실패했습니다 + %1$s 플러그인 서비스 바인딩에 실패했습니다. 메서드 \"%s\"를 호출하지 못했습니다 + 스위치 상태 변경에 실패했습니다 %s 값을 Drawable 로 변환하지 못했습니다 설정 페이지를 열지 못했습니다 Shizuku 권한을 부여하지 못했습니다 @@ -276,6 +284,7 @@ AutoJs6 은 \"auto\" 파일을 실행할 루트 액세스 권한이 없을 수 있습니다. 널 인수로 호출 된 %s(): %s 메소드는 [%1$d..%2$d] 범위의 인수만 허용합니다 + \"%1$s\"에 필요한 플러그인이 없습니다. 플러그인을 설치한 후 다시 시도해 주세요. 필요한 라이브러리 파일이 부족하여 \"%s\" 모듈이 작동하지 않습니다 접근성 서비스가 비활성화되고 스크립트가 중지되었습니다 접근성 서비스는 활성화되지 않습니다 @@ -286,8 +295,12 @@ 이 파일을 재생할 수 있는 앱이 없습니다 이 파일을 전송할 수 있는 앱이 없습니다 이 파일을 볼 수 있는 앱이 없습니다 + 사용 가능하며 활성화된 %1$s 플러그인 variant를 찾을 수 없습니다 (%2$s). 현재 플러그인에 사용 가능한 URL 이 제공되지 않았습니다 \"다른 앱 위에 표시\"권한이 없습니다 + 내장된 Paddle OCR assets를 찾을 수 없습니다. Paddle OCR을 활성화하여 다시 패키징해 주세요. + \"%1$s\"에 활성화된 플러그인이 없습니다. 플러그인을 활성화한 후 다시 시도해 주세요. + 사용 가능한 Paddle OCR 플러그인을 찾을 수 없습니다 Shizuku 에 액세스할 수 있는 권한이 없습니다 \"게시물 알림\" 권한 없음 \"전화 상태 읽기\"권한이 없습니다 @@ -300,6 +313,10 @@ GitHub 릴리스 자산을 구문 분석하지 못했습니다 버전 정보를 구문 분석하지 못했습니다 잘못된 패턴 구문 + 플러그인 APK에 variant=\"%1$s\"에 필요한 assets가 포함되어 있지 않습니다: %2$s. + 플러그인 APK에 필요한 native 라이브러리가 포함되어 있지 않습니다: %1$s. + %1$s 플러그인이 빈 info를 반환했습니다. + %1$s 플러그인이 잘못된 variant를 반환했습니다: %2$s. 65535 이상의 포트 번호 프로젝트 메인 스크립트 파일 \"%1$s\" 이 존재하지 않습니다 가치 %s 를 JSON 에 넣을 수 없습니다 @@ -318,6 +335,7 @@ 지정된 AutoJs6 버전 번호는 461보다 커야 합니다 필수 속성 \"%1$s\" 에 대한 변환기는 null 값을 반환할 수 없습니다 스레드는 살아 있지 않습니다 + %1$s 플러그인 정보 조회가 시간 초과되었습니다. Shizuku 서비스를 사용할 수 없음 허용되지 않는 문자 알수없는 오류 @@ -406,6 +424,7 @@ 필요할 때 루트 액세스로 접근성 서비스를 자동으로 활성화하십시오 필요할 때 안전한 설정으로 접근성 서비스를 활성화하십시오 JavaScript 내장 개체를 확장하여 코드 유연성을 높이고 더 풍부한 기능을 활성화합니다. + 포그라운드 서비스는 백그라운드에서 앱과 스크립트 실행을 더 안정적으로 유지합니다 AutoJs6 이 전경에있을 때 스크립트의 자동화 조치 방지 주요 활동을 표시하지 않고 직접 스크립트를 실행하십시오 AutoJs6 가 알림을 생성하고 보낼 수 있도록 허용합니다 @@ -418,10 +437,12 @@ 부동 버튼이 표시 될 때 볼륨 다운 키로 제어 된 녹음 시작 또는 중지 실행 중인 모든 스크립트를 중지하려면 \"볼륨 크게\" 키를 누르십시오. 릴리스 버전의 변경 기록 및 통계 데이터를 확인하기 + 내부 저장소 접근성 서비스 스크립트 자동 작동에 필요합니다 (클릭, 긴 프레스, 슬라이드 등). 접근성 서비스가 활성화되었지만 실행되지 않음 (장치를 다시 활성화 또는 재부팅) 접근성 서비스가 필요할 수 있습니다 + 중지하는 중... 에 대한 모든 파일 액세스에 대해 앱과 개발자에 대해 @@ -444,6 +465,7 @@ 별칭 별칭은 비워둘 수 없습니다 별칭 비밀번호 + 전체 모든 파일에 액세스합니다 \"모든 파일 액세스\"는 전화기의 스크립트 파일에 액세스하려면 필요합니다. 모든 기록 @@ -496,7 +518,7 @@ 앱 버전 코드 앱 버전 이름 모습 - "성명, 조직명, 조직 단위, 국가 코드, 주 또는 도, 시 또는 지역, 거리" 중 하나 이상을 입력해야 합니다 + [성명, 조직명, 조직 단위, 국가 코드, 주 또는 도, 시 또는 지역, 거리] 중 하나 이상을 입력해야 합니다 기인하다 자동 확인 업데이트 자동으로 업데이트를 확인하고 홈페이지에 스낵바를 표시합니다. @@ -580,7 +602,11 @@ 모든 파일을 새 디렉토리로 복사하십시오 CMD 를 복사하십시오 디버깅 로그를 복사하십시오 + 파일 복사 + 폴더 복사 사본 라인 + 원본 경로와 대상 경로가 같습니다. 계속 복사하시겠습니까?\n\n새 이름: \"%1$s\". + 복사 위치 클립 보드에 복사 값을 복사하십시오 국가 코드 (XX) @@ -603,10 +629,14 @@ 기본 기본 키 저장소 기본 접두사 + 지연 시간 삭제 모두 삭제 + 파일 삭제 + 폴더 삭제 라인 삭제 설명 + 대상 세부 개발자 세부 사항이 개발 중입니다 개발자 옵션 @@ -619,7 +649,7 @@ 장치 제품 이름 기기 화면 해상도 지금 다운로드하십시오 - 예배 규칙서 + 디렉터리 비활성화됨 다른 앱에 표시됩니다 \"다른 앱 위의 디스플레이\"권한은 모든 위젯을 올바르게 표시하는 것이 좋습니다. @@ -716,6 +746,7 @@ 이전을 성명 플로팅 버튼 + 폴더 강제 정지 전경 서비스 포맷 완료 @@ -757,6 +788,7 @@ \"URL\"에서 설치 \"URL\"에서 플러그인 설치 설치 가능 + 설치됨 무결성 검증에 실패했습니다 잘못된 문자가 제거되었습니다 잘못된 패키지 이름 @@ -812,7 +844,12 @@ \"모바일 QQ\" 가 설치되지 않았습니다 세부 + 이동 + 원본 경로와 대상 경로가 같습니다. 이동이 중지되었습니다. 모든 파일을 새 디렉토리로 이동하십시오 + 파일 이동 + 폴더 이동 + 이동 위치 여러 옵션 이름 접근성 서비스를 활성화해야합니다 @@ -840,6 +877,7 @@ 루트 액세스가 없습니다 실행을 멈출 스크립트가 없습니다 부여되지 않았습니다 + 설치되지 않음 주요 활동을 보여주지 않습니다 공고 알림 액세스 @@ -854,6 +892,8 @@ 다른 앱으로 열립니다 열린 주요 활동 함께 열립니다 + 중지됨 + 완료 작동이 완료되었습니다 옵션 조직명 @@ -942,6 +982,7 @@ 권한을 부여하지 못함 (Shizuku 사용) 부여 된 권한 (루트 포함) 권한 부여됨 (Shizuku 사용) + 권한 관리 앱이 다른 앱의 사용 통계를 볼 수 있도록 허용 허가가 취소되었습니다 허가를 철회하지 못했습니다 (루트 포함) @@ -965,6 +1006,7 @@ 포인터 위치 \"포인터 위치\"토글이 실패했습니다.\n루트 액세스가 필요합니다. 게시물 알림 + AutoJs6 포그라운드 서비스 등이 정상적으로 동작하고 스크립트가 알림을 게시할 수 있도록 하려면, AutoJs6 에 \"알림 게시\" 권한을 부여해야 합니다. 사전 배제 스크립트 준비 ... 사전 설정 대화 상자 내용 @@ -979,6 +1021,9 @@ 프로젝트 위치 프로젝트 미디어 액세스 즉각적인 + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s 그만두다 권장 녹음 완료 @@ -1047,6 +1092,7 @@ 저장 엔진 시작 지연 + 화면 캡처 권한 요청 지연 스크립트 녹음 스크립트 실행 검색 @@ -1066,6 +1112,7 @@ 바로 가기를 만듭니다 서버 모드 서비스 + 서비스 관리 작업 디렉토리로 중단 점을 설정하십시오 설정 @@ -1082,6 +1129,10 @@ 크기 내보낸 %d 항목 정렬 + 최근 업데이트순 정렬 + 이름순 정렬 + 패키지 크기순 정렬 + 원본 소스 코드 경로 특수 권한 안정적인 모드 @@ -1174,36 +1225,4 @@ 보안 설정을 작성하십시오 시스템 설정을 작성하십시오 백그라운드 팝업 - 사용 가능한 Paddle OCR 플러그인을 찾을 수 없습니다 - 설치됨 - 설치되지 않음 - 전체 - 이름순 정렬 - 최근 업데이트순 정렬 - 패키지 크기순 정렬 - \"%1$s\"에 필요한 플러그인이 없습니다. 플러그인을 설치한 후 다시 시도해 주세요. - \"%1$s\"에 활성화된 플러그인이 없습니다. 플러그인을 활성화한 후 다시 시도해 주세요. - 사용 가능하며 활성화된 %1$s 플러그인 variant를 찾을 수 없습니다 (%2$s). - 플러그인 APK에 variant=\"%1$s\"에 필요한 assets가 포함되어 있지 않습니다: %2$s. - 플러그인 APK에 필요한 native 라이브러리가 포함되어 있지 않습니다: %1$s. - %1$s 플러그인 서비스 바인딩에 실패했습니다. - %1$s 플러그인 정보 조회가 시간 초과되었습니다. - %1$s 플러그인이 빈 info를 반환했습니다. - %1$s 플러그인이 잘못된 variant를 반환했습니다: %2$s. - 내장된 Paddle OCR assets를 찾을 수 없습니다. Paddle OCR을 활성화하여 다시 패키징해 주세요. - 최소화 - %1$s: %2$d%3$s - %1$s: %2$d %3$s - 화면 캡처 권한 요청 지연 - 화면 캡처 권한을 요청할 때 표시되는 권한 요청 창은 사라질 때 페이드 등의 전환 애니메이션이 있을 수 있습니다. 이때 `images.captureScreen` 메서드를 즉시 호출하면, 얻은 스크린샷에 권한 요청 창의 내용이 포함되어 화면이 가려질 수 있습니다.\n\n이 설정 값은 권한을 획득한 직후 첫 스크린샷을 캡처하기 전에 지연 시간(밀리초)을 추가하여, 위와 같은 가림 문제를 방지하는 데 사용할 수 있습니다.\n\n이 설정은 권한 획득 후 첫 번째 캡처에만 적용되며, 이후 캡처에는 더 이상 영향을 주지 않습니다. - 지연 시간 - 홈페이지 - 스위치 상태 변경에 실패했습니다 - AutoJs6 포그라운드 서비스 등이 정상적으로 동작하고 스크립트가 알림을 게시할 수 있도록 하려면, AutoJs6 에 \"알림 게시\" 권한을 부여해야 합니다. - \"포인터 위치\" 는 Android 개발자 옵션에 있는 디버깅 기능입니다.\n활성화하면 시스템이 화면에 터치 지점의 [좌표/이동 궤적/개수/크기/이동 속도/압력] 등의 정보를 표시하여 관련 스크립트의 [작성/디버깅/검증] 에 도움이 됩니다. - 오류가 발생했습니다 - 권한 관리 - 서비스 관리 - 포그라운드 서비스는 백그라운드에서 앱과 스크립트 실행을 더 안정적으로 유지합니다 - - + \ No newline at end of file diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 401bab09..02284a06 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -42,6 +42,8 @@ #4FC3F7 @color/dialog_button_error + @color/md_gray_700 + #DEA9A9A9 #333333 diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index fbb41aca..03276a52 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -50,7 +50,8 @@ Конфигурация \"abi\" содержит недоступные параметры Конфигурация \"lib\" содержит недопустимые параметры Конфигурация \"lib\" содержит недоступные параметры - Файл уже существует.\nПерезаписать? + Папка уже существует. Перезаписать? + Файл уже существует. Перезаписать? 1. Нажмите и удерживайте название приложения (AutoJs6) на главной странице, чтобы перейти на страницу настроек.\n2. Нажмите и удерживайте определенную опцию настроек на странице настроек, чтобы просмотреть подробную информацию. Текущий цвет темы %1$s настроен через цветовую палитру Плавающая кнопка действий для отображения манифеста @@ -94,23 +95,27 @@ Ночной режим (также известный как темная тема) применяется как к системному пользовательскому интерфейсу Android, так и к приложениям, запущенным на устройстве, что улучшает видимость для пользователей со слабым зрением и тех, кто чувствителен к яркому свету, а также облегчает любому человеку использование устройства в условиях недостаточной освещенности.\n\nСистема слежения: AutoJs6 имеет настройки ночного режима, такие же, как и система Android\nВсегда включен: AutoJs6 держит Ночной режим включенным (независимо от настроек системы Android)\nВсегда выключен: AutoJs6 отключает ночной режим (независимо от настроек системы Android)\n\nПримечание: Опция \"Следовать за системой\" доступна только для Android API Level 28 (Android 9) [P] и выше. Чтобы включить Ночной режим в системе Android:\n- Android API Level 29 (Android 10) [Q] и выше: Настройки -> Дисплей -> Тема.\n- Android API Уровень 28 (Android 9) [P]: Параметры разработчика -> Ночной режим.\n\nДля применения ночного режима (темной темы) к веб-контенту с помощью компонента WebView (например, страницы документации AutoJs6) должны быть выполнены следующие условия:\n1. Android System WebView (или браузеры типа Google Chrome):\n- Android API Level 29 (Android 10) [Q] и выше: версия >= 76\n- Android API Level 28 (Android 9) [P]: версия >= 105\n2. Веб-содержимое в компоненте WebView адаптировано к теме Dark (с помощью CSS или ресурсов Android XML и т.д.). Разрешение \"доступ к уведомлениям\" (или \"разрешение на чтение уведомлений\") позволяет AutoJs6 читать содержимое системных уведомлений, чтобы скрипты могли отслеживать уведомления или получать их текст и т. п. + \"Положение указателя\" - это отладочная функция в параметрах разработчика Android.\nПосле включения система будет отображать на экране сведения о точке(ах) касания, такие как [координаты/траектория движения/количество/размер/скорость движения/давление], что упрощает [написание/отладку/проверку] соответствующих скриптов. Разрешение \"отправка уведомлений\" позволяет AutoJs6 публиковать уведомления в системе, чтобы скрипты могли создавать и управлять пользовательскими уведомлениями в шторке уведомлений.\n\nNote: на устройствах Android 13+ без этого разрешения некоторые уведомления могут не отображаться, а также это может повлиять на запуск и стабильность служб на переднем плане. При наличии доступа к медиафайлам проекта предупреждение о безопасности при записи экрана не выдается. Стратегия перезагрузки влияет только на кнопку перезапуска в выдвижном меню главной страницы.\n\nБыстрая перезагрузка: быстро перезапускает приложение. Если перезапуск не удался или возникли непредвиденные ситуации, попробуйте переключиться на \"Запланированную перезагрузку\".\nЗапланированная перезагрузка: заранее настраивает краткосрочную задачу. После остановки приложение будет запущено по расписанию для выполнения перезапуска. Переключатель включён (по умолчанию): значения, возвращаемые методами Java типов Number/Boolean/Character, оборачиваются в объекты Java и доступны в скрипте (String исключается). typeof = \"object\", species = \"JavaObject\"; доступны методы Java, что помогает сохранять точные типовые характеристики Java и корректную резолюцию перегрузок.\n\nПереключатель выключен: перечисленные типы больше не оборачиваются и передаются напрямую как примитивы JavaScript (number/boolean/строка из одного символа). typeof соответствует соответствующему типу JavaScript, что ближе к семантике/экосистеме JavaScript. При необходимости можно явно создать Java‑обёртку через new, например new java.lang.Boolean(true).\n\nСм.: http://issues.autojs6.com/435 Если у вас есть экзотический root или аномальное состояние для root-доступа, вы можете принудительно установить root на root или non-root. Бинарный тип: не редактируемый, с расширением файла \"auto\"\nТип JavaScript: может быть отредактирован или скопирован напрямую, с расширением файла \"js\". + При запросе разрешения на захват экрана отображаемое окно запроса может иметь анимацию затухания при исчезновении. Если сразу вызвать `images.captureScreen`, полученный снимок может содержать содержимое этого окна и быть частично перекрыт.\n\nЗначение этой опции добавляет задержку (в миллисекундах) перед выполнением снимка экрана сразу после получения разрешения, что позволяет избежать описанной выше проблемы перекрытия.\n\nЭта опция применяется только к первому снимку после получения разрешения; последующие снимки не будут зависеть от этого значения. Серверный режим позволяет AutoJs6 запускать службу на текущем устройстве и ожидать подключения внешних клиентов для выполнения [ передачи скриптов / вывода логов / удалённого управления ].\n\nСерверный режим AutoJs6 поддерживает два способа подключения:\n1. Локальная сеть (LAN)\n2. Android Debug Bridge (ADB) Shizuku позволяет получить привилегии ADB и доступ к системным API. Стабильный режим повышает стабильность при получении границ макета, но некоторые результаты могут быть проигнорированы.\nТребуется перезапуск службы доступности. Цвет темы применяется к виджетам, включая следующие, но не ограничиваясь ими:\nСтрока состояния\nПанель приложений\nЗначок файла\nЗначок элемента задачи\nFAB\nЗаголовок каталога настроек\nКнопка переключения\n\nПримечание: Начиная с версии AutoJs6 6.2.0, пока не существует различий между основным цветом, основным темным цветом и цветом акцента. - Управляет базовым механизмом по расписанию запуска скриптов.\n\nAlarmManager: При выдаче разрешения "Разрешить настройку будильников и напоминаний" задачи выполняются более точно по времени.\nWorkManager: Дружелюбен к системе; подходит для некритичных задач, допускающих задержку.\nJobScheduler: Устаревшая реализация, сохранена для совместимости; вероятность задержек выше. - Сценарии и отличия:\n\n1. AlarmManager\nПодходит для задач, чувствительных к точности времени, например [напоминания/строго по расписанию/...].\nВ Android 12+ при наличии разрешения "Разрешить настройку будильников и напоминаний" задачи запускаются более точно даже при выключенном экране/в ожидании.\nБез него система может понизить точность или отложить выполнение.\n\n2. WorkManager\nПодходит для задач без строгих требований к времени, например [некритичная синхронизация/очистка/статистика/...].\nПланирование учитывает [батарею/сеть/зарядку/политику сна/...], возможны задержки при выключенном экране или в ожидании.\nХотя точность не гарантируется, он силён в [надёжном завершении/повторных попытках/цепочках/дедупликации работ].\n\n3. JobScheduler\nИсторическая реализация для совместимости.\nНа новых версиях Android возможны более существенные задержки.\nНе рекомендуется, если это не необходимо ради совместимости. + Управляет базовым механизмом по расписанию запуска скриптов.\n\nAlarmManager: При выдаче разрешения \"Разрешить настройку будильников и напоминаний\" задачи выполняются более точно по времени.\nWorkManager: Дружелюбен к системе; подходит для некритичных задач, допускающих задержку.\nJobScheduler: Устаревшая реализация, сохранена для совместимости; вероятность задержек выше. + Сценарии и отличия:\n\n1. AlarmManager\nПодходит для задач, чувствительных к точности времени, например [напоминания/строго по расписанию/...].\nВ Android 12+ при наличии разрешения \"Разрешить настройку будильников и напоминаний\" задачи запускаются более точно даже при выключенном экране/в ожидании.\nБез него система может понизить точность или отложить выполнение.\n\n2. WorkManager\nПодходит для задач без строгих требований к времени, например [некритичная синхронизация/очистка/статистика/...].\nПланирование учитывает [батарею/сеть/зарядку/политику сна/...], возможны задержки при выключенном экране или в ожидании.\nХотя точность не гарантируется, он силён в [надёжном завершении/повторных попытках/цепочках/дедупликации работ].\n\n3. JobScheduler\nИсторическая реализация для совместимости.\nНа новых версиях Android возможны более существенные задержки.\nНе рекомендуется, если это не необходимо ради совместимости. Предоставляет доступ к истории использования устройства и статистике, что позволяет получить более точный результат в функции currentPackage() Просмотреть историю выпусков AutoJs6 на GitHub и статистику по основным категориям. Настройки безопасности системы, содержащие системные предпочтения, которые приложения могут читать, но не имеют права записывать.\nОни предназначены для параметров, которые пользователь должен явно изменить через пользовательский интерфейс системного приложения.\nПри наличии разрешения на безопасные системные настройки обычные приложения могут напрямую изменять безопасные настройки (например, служба доступности). Разрешение \"изменение системных настроек\" позволяет AutoJs6 изменять некоторые параметры системы, чтобы скрипты могли менять такие настройки, как [ яркость экрана / автоповорот / тайм-аут экрана ]. Отказаться + Прервать + Прервать соединение Доп. Исправить адрес @string/text_back @@ -128,10 +133,11 @@ Детали Информация о файле История + Главная Игнорировать - Прервать соединение Вступить группу Менеджер + Свернуть Еще Открыть палитру Выйти @@ -191,6 +197,7 @@ Метод %s был отменен и не должен использоваться Операция \"%1$s\" не может быть завершена, так как параметр содержит отрицательные значения координат (%2$d, %3$d) Требуется активность, которую можно предоставить, выполняя в режиме выполнения \"ui\" + Произошла ошибка Операция не выполняется Приложение не установлено Приложение не установлено: \"%s\" @@ -229,8 +236,10 @@ Чрезмерная высота: шаблон [%1$d] > регион [%2$d] Чрезмерная ширина: шаблон [%1$d] > регион [%2$d] Не удалось применить текущую историю цветов + Не удалось привязаться к службе плагина %1$s. Не удалось вызвать метод \"%s\" + Не удалось изменить состояние переключателя Не удалось преобразовать значение %s в Drawable Не удалось открыть страницу настроек Не удалось предоставить права на использование Shizuku @@ -274,6 +283,7 @@ AutoJs6 может не иметь root-доступа для запуска файла \"auto\" %s() вызвана с нулевым аргументом: %s Метод принимает только количество аргументов в диапазоне [%1$d..%2$d] + Отсутствует требуемый плагин для \"%1$s\". Установите плагин и повторите попытку. Модуль \"%s\" не работает из-за отсутствия необходимых библиотечных файлов Служба доступности отключена, и сценарий остановлен Служба доступности не активирована @@ -284,8 +294,12 @@ Нет приложений для воспроизведения этого файла Нет приложений для отправки этого файла Нет приложений для просмотра этого файла + Не найдено доступных и включённых вариантов плагина %1$s (%2$s). Для текущего плагина не указан доступный URL-адрес Нет разрешения \"отображать поверх других приложений\" + Не найдены встроенные ресурсы Paddle OCR. Перепакуйте приложение с включённым Paddle OCR. + Для \"%1$s\" нет включённого плагина. Включите плагин и повторите попытку. + Доступные плагины Paddle OCR не найдены Нет разрешения на доступ к Shizuku Нет разрешения на \"уведомления о сообщениях\" Нет разрешения \"читать состояние телефона\" @@ -298,6 +312,10 @@ Не удалось разобрать активы релиза GitHub Не удалось разобрать информацию о версии Неверный синтаксис шаблона + APK плагина не содержит требуемые ресурсы для variant=\"%1$s\": %2$s. + APK плагина не содержит требуемые native-библиотеки: %1$s. + Плагин %1$s вернул пустую информацию. + Плагин %1$s вернул недопустимый variant: %2$s. Номер порта более 65535 Основной файл скрипта проекта \"%1$s\" не существует Не удается поместить значение %s в JSON @@ -316,6 +334,7 @@ Указанный номер версии AutoJs6 должен быть больше 461 Преобразователь для требуемого свойства \"%1$s\" не может возвращать пустое значение Нить не жива + Тайм-аут при запросе информации о плагине %1$s. Невозможно использовать службу Shizuku Недопустимый символ Неизвестная ошибка @@ -404,6 +423,7 @@ Автоматическое включение службы доступности с корневым доступом при необходимости Автоматическое включение службы доступности с безопасными настройками при необходимости Повысить гибкость кода и обеспечить более богатую функциональность за счет расширения встроенных объектов JavaScript + Служба на переднем плане позволяет более стабильно поддерживать работу приложения и скриптов в фоновом режиме Предотвращение действий автоматизации из скриптов, когда AutoJs6 находится на переднем плане Выполнять скрипт напрямую, не показывая основную активность Позволяет AutoJs6 создавать и отправлять уведомления @@ -416,10 +436,12 @@ Запуск или остановка записи, управляемая клавишей уменьшения громкости, когда отображается плавающая кнопка Нажмите клавишу \"Громкость вверх\", чтобы остановить все запущенные скрипты Просмотреть историю выпусков и статистические данные + Внутреннее хранилище Служба доступности Требуется для автоматической работы сценария (щелчок, длительное нажатие, скольжение и т.д.). Служба доступности включена, но не работает (Включите или перезагрузите устройство) Может потребоваться служба доступности + Прерывание... Об О доступе ко всем файлам О приложении и разработчике @@ -442,12 +464,13 @@ псевдоним Псевдоним не может быть пустым Пароль псевдонима + Все Доступ ко всем файлам \"Доступ ко всем файлам\" необходим для доступа к файлам сценариев на телефоне Вся история Вся история очищена Все элементы удалены - Рекомендуется выдать разрешение "Разрешить настройку будильников и напоминаний", чтобы обеспечить максимально точный запуск задач даже при выключенном экране или в режиме ожидания + Рекомендуется выдать разрешение \"Разрешить настройку будильников и напоминаний\", чтобы обеспечить максимально точный запуск задач даже при выключенном экране или в режиме ожидания Скопировано в буфер обмена Уже скопировано в буфер обмена (только последние %d элементов) Создано @@ -494,7 +517,7 @@ Код версии приложения Название версии приложения Внешний вид - Необходимо заполнить хотя бы одно поле из: "Полное имя, Название организации, Организационная единица, Код страны, Штат или провинция, Город или населенный пункт, Улица" + Необходимо заполнить хотя бы одно поле из: [Полное имя, Название организации, Организационная единица, Код страны, Штат или провинция, Город или населенный пункт, Улица] Атрибут Автоматическая проверка обновлений Автоматическая проверка обновлений и отображение закуски на домашней странице @@ -578,7 +601,11 @@ Скопировать все файлы в новый каталог Копировать cmd Копировать журнал отладки + Копировать файл + Копировать папку Копировать строку + Исходный путь совпадает с путем назначения. Продолжить копирование?\n\nНовое имя: \"%1$s\". + Копировать в Копировать в буфер обмена Копировать значение Код страны (XX) @@ -601,10 +628,14 @@ По умолчанию По умолчанию хранилище ключей Префикс по умолчанию + Время задержки Удалить Удалить все + Удалить файл + Удалить папку Удалить строку Описание + Назначение Детали Детали разработчика находятся в стадии разработки Параметры разработчика @@ -714,6 +745,7 @@ Преды Полное имя Плавающая кнопка + Папка Принудительная остановка Служба переднего плана Форматирование завершено @@ -755,6 +787,7 @@ Установить из \"URL\" Установить плагин из \"URL\" Устанавливаемый + Установлено Сбой проверки целостности Недопустимый символ удален Неверное имя пакета @@ -810,7 +843,12 @@ \"Мобильный QQ\" не установлен Больше Подробнее + Переместить + Исходный путь совпадает с путем назначения; перемещение отменено. Переместить все файлы в новый каталог + Переместить файл + Переместить папку + Переместить в Несколько вариантов Имя Необходимо включить службу доступности @@ -838,6 +876,7 @@ Нет root-доступа Нет скриптов для остановки выполнения Не предоставляется + Не установлено Не показывает основную деятельность Уведомление Доступ к уведомлениям @@ -852,6 +891,8 @@ Открыто другими приложениями Открыть основную деятельность Открыть с + Прервано + Завершено Операция завершена Опции Название организации @@ -940,6 +981,7 @@ Не удалось предоставить разрешение (с Shizuku) Разрешение предоставлено (с root) Разрешение получено (с Shizuku) + Управление разрешениями Разрешить приложению доступ к статистике использования других приложений Разрешение отозвано Не удалось отозвать разрешение (с root) @@ -963,6 +1005,7 @@ Расположение указателя Переключение \"Расположение указателя\" не удалось.\nТребуется корневой доступ. почтовые уведомления + Чтобы обеспечить корректную работу фоновых служб переднего плана AutoJs6 и возможность публикации уведомлений скриптами, AutoJs6 необходимо предоставить разрешение \"публикации уведомлений\". Предварительное выполнение сценария Подготовка... Содержимое предустановленного диалога @@ -977,6 +1020,9 @@ Расположение проекта Доступ к носителям проекта Запрос + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s Выйти Рекомендуемый Запись завершена @@ -1045,6 +1091,7 @@ Сохранить в Движок Задержка старта + Задержка запроса разрешения на захват экрана Запись сценария Выполнение сценария Поиск @@ -1064,6 +1111,7 @@ Создать ярлык Режим сервера Сервис + Управление службами Как рабочий каталог Установить точку останова Настройки @@ -1080,6 +1128,10 @@ Размер Экспортировано %d элементов Сортировать + Сортировать по времени последнего обновления + Сортировать по имени + Сортировать по размеру пакета + Источник Путь к исходному коду Специальные разрешения Стабильный режим @@ -1172,36 +1224,5 @@ Параметры безопасности записи Запись системных настроек Всплывающие окна в фоне - Доступные плагины Paddle OCR не найдены - Установлено - Не установлено - Все - Сортировать по имени - Сортировать по времени последнего обновления - Сортировать по размеру пакета - Отсутствует требуемый плагин для \"%1$s\". Установите плагин и повторите попытку. - Для \"%1$s\" нет включённого плагина. Включите плагин и повторите попытку. - Не найдено доступных и включённых вариантов плагина %1$s (%2$s). - APK плагина не содержит требуемые ресурсы для variant=\"%1$s\": %2$s. - APK плагина не содержит требуемые native-библиотеки: %1$s. - Не удалось привязаться к службе плагина %1$s. - Тайм-аут при запросе информации о плагине %1$s. - Плагин %1$s вернул пустую информацию. - Плагин %1$s вернул недопустимый variant: %2$s. - Не найдены встроенные ресурсы Paddle OCR. Перепакуйте приложение с включённым Paddle OCR. - Свернуть - %1$s: %2$d%3$s - %1$s: %2$d %3$s - Задержка запроса разрешения на захват экрана - При запросе разрешения на захват экрана отображаемое окно запроса может иметь анимацию затухания при исчезновении. Если сразу вызвать `images.captureScreen`, полученный снимок может содержать содержимое этого окна и быть частично перекрыт.\n\nЗначение этой опции добавляет задержку (в миллисекундах) перед выполнением снимка экрана сразу после получения разрешения, что позволяет избежать описанной выше проблемы перекрытия.\n\nЭта опция применяется только к первому снимку после получения разрешения; последующие снимки не будут зависеть от этого значения. - Время задержки - Главная - Не удалось изменить состояние переключателя - Чтобы обеспечить корректную работу фоновых служб переднего плана AutoJs6 и возможность публикации уведомлений скриптами, AutoJs6 необходимо предоставить разрешение \"публикации уведомлений\". - \"Положение указателя\" - это отладочная функция в параметрах разработчика Android.\nПосле включения система будет отображать на экране сведения о точке(ах) касания, такие как [координаты/траектория движения/количество/размер/скорость движения/давление], что упрощает [написание/отладку/проверку] соответствующих скриптов. - Произошла ошибка - Управление разрешениями - Управление службами - Служба на переднем плане позволяет более стабильно поддерживать работу приложения и скриптов в фоновом режиме diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 66bae75d..77aee88e 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -4,7 +4,6 @@ - 構建中... 清理臨時文件... 打包中... @@ -49,7 +48,8 @@ 配置 \"abi\" 含不可用選項 配置 \"lib\" 含無效選項 配置 \"lib\" 含不可用選項 - 文件已存在, 是否覆蓋 + 文件夾已存在, 是否覆蓋. + 文件已存在, 是否覆蓋. 1. 長按主頁應用名稱 (AutoJs6) 可跳轉至設置頁面\n2. 設置頁面長按設置選項可查看詳細信息 當前主題色 %1$s 由調色盤配置 用於顯示清單內容的浮動操作按鈕控件 @@ -92,12 +92,14 @@ 夜間模式, 亦稱 [ 暗黑模式 / 深色主題 ] 等.\n夜間模式應用於安卓系統 UI (如通知欄和導航欄) 及 AutoJs6 應用頁面.\n夜間模式可提升設備在低光環境下的易用性, 同時有助於提升弱視或光敏感用户的視覺體驗.\n\n跟隨系統: AutoJs6 與安卓操作系統的夜間模式設置一致\n總是開啓: AutoJs6 保持開啓夜間模式 (忽略操作系統設置)\n總是關閉: AutoJs6 保持關閉夜間模式 (忽略操作系統設置)\n\n注: 跟隨系統功能僅支持安卓 API 級別 28 (安卓 9) [P] 及以上操作系統. 啓用安卓系統的夜間模式:\n- API 級別 29 (安卓 10) [Q] 及以上: 通過 [ 設置 -> 顯示 -> 主題 ] 開啓.\n- API 級別 28 (安卓 9) [P]: 通過 [ 開發者選項 -> 夜間模式 ] 開啓.\n\n對於基於 WebView 組件的內容 (如 AutoJs6 的文檔頁面), 夜間模式支持需要滿足以下條件:\n1. WebView (或 Google Chrome 等瀏覽器) 版本要求:\n- API 級別 29 (安卓 10) [Q] 及以上: 版本不低於 76\n- API 級別 28 (安卓 9) [P]: 版本不低於 105\n2. WebView 組件頁面內容可適配夜間模式 (通過 CSS 或 安卓 XML 資源等方式實現) \"通知使用權\" (或 \"通知讀取權限\") 允許 AutoJs6 讀取系統通知內容, 使腳本可以監聽通知或獲取通知文本等. + \"指針位置\" 是安卓開發者選項中的調試功能.\n開啓後, 系統會在屏幕上顯示觸摸點的 [座標/移動軌跡/數量/大小/移動速度/壓力] 等信息, 便於相關腳本的 [編寫/調試/校對] 等. \"發送通知\" 權限允許 AutoJs6 向系統發佈通知, 使腳本可以在通知欄發佈並管理自定義通知等.\n\n注: 在 Android 13+ 設備上未授予該權限時, 部分通知可能無法顯示, 並可能影響前台服務的啓動與穩定性. 被授予 \"投影媒體權限\" 後, 錄製屏幕的安全提示窗口將不再彈出. 重啓策略僅作用於主頁抽屜欄的重啓按鈕.\n\n快速重啓: 快速重啓應用, 如果重啓失敗或出現非預期情況, 可嘗試切換至 \"計劃重啓\".\n計劃重啓: 提前設置一個短時定時任務, 應用停止後會再次定時啓動, 以實現應用重啓. 開關啓用 (默認): 將 Java 方法返回的 Number/Boolean/Character 包裝為 Java 對象暴露到腳本 (String 除外). typeof 為 \"object\", species 為 \"JavaObject\", 可訪問這些對象的 Java 方法, 利於保留 Java 精確類型特徵與方法重載行為.\n\n開關禁用: 不再包裝上述類型, 直接作為 JavaScript 基元值 (number/boolean/單字符字符串). typeof 為相應 JavaScript 類型, 更貼近 JavaScript 語義與生態. 但仍可通過 new 關鍵字顯式聲明一個 Java 包裝類型, 如 new java.lang.Boolean(true).\n\n參閲: http://issues.autojs6.com/435 如果設備使用非常規 Root 方式或 Root 權限檢測結果異常, 可設置 \"強制 Root 模式\" 或 \"強制非 Root 模式\". 二進制文件: 不可編輯, 文件擴展名為 \"auto\"\nJavaScript 文件: 可編輯或直接複製, 文件擴展名為 \"js\" + 申請屏幕捕獲權限時, 彈出的權限申請窗口消失時可能存在漸變動畫, 此時如果立即調用 `images.captureScreen` 方法, 獲取的屏幕截圖中會出現權限申請的窗口內容而造成遮擋.\n\n當前設置選項值用於在截圖權限申請後立即獲取屏幕截圖前增加一個延遲時間 (單位為毫秒), 可用於避免上述遮擋問題.\n\n當前設置選項僅適用於獲取截圖權限後的首次截圖操作, 後續截圖操作不再受此設置值影響. 服務端模式用於讓 AutoJs6 在當前設備開啓服務並等待外部客户端連接, 以便進行 [ 腳本傳輸 / 打印日誌 / 遠程控制 ] 等.\n\nAutoJs6 服務端模式支持兩種連接方式:\n1. 局域網 (LAN)\n2. 安卓調試橋 (ADB) 通過 Shizuku 可以獲得 ADB 特權並使用系統 API 穩定模式省略佈局細節, 腳本分析佈局時更穩定, 但可能影響獲取的控件總量.\n需重啓無障礙服務. @@ -109,6 +111,8 @@ 安全設置包含應用程序可讀但不可寫入的設置選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設置權限\" 後, 普通應用可直接修改上述安全設置 (例如無障礙服務). \"修改系統設置\" 權限允許 AutoJs6 修改部分系統設置項, 使腳本可以修改 [ 屏幕亮度 / 自動旋轉 / 屏幕超時 ] 等系統設置參數. 放棄 + 中止 + 中止連接 高級設置 修正地址 @string/text_back @@ -126,10 +130,11 @@ 異常詳情 文件信息 歷史記錄 + 主頁 忽略此版本 - 中止連接 加入羣組 管理器 + 最小化 瞭解更多 打開調色盤 放棄 @@ -189,6 +194,7 @@ 方法 %s 已被廢棄, 應避免使用 無法完成 \"%1$s\" 操作, 因為參數中包含負數座標值 (%2$d,%3$d) 缺少必要的 activity 對象, 可通過 \"ui\" 執行模式來提供 + 發生錯誤 操作尚未實現 應用未安裝 應用未安裝: \"%s\" @@ -227,8 +233,10 @@ 高度超限: 模板圖像 [%1$d] > 限定區域 [%2$d] 寬度超限: 模板圖像 [%1$d] > 限定區域 [%2$d] 應用當前歷史顏色失敗 + 綁定 %1$s 插件服務失敗. 方法 \"%s\" 調用失敗 + 開關狀態改變失敗 無法將值 %s 轉換為 Drawable 實例 跳轉設置頁面失敗 Shizuku 權限授予失敗 @@ -272,6 +280,7 @@ AutoJs6 可能因缺少 Root 權限而無法運行 \"auto\" 文件 %s() 傳入的 %s 參數為空 方法僅可接受參數數量位於 [%1$d\.\.%2$d] 區間內 + 缺少 \"%1$s\" 所需的插件. 請先安裝插件, 然後重試. 由於缺少必要的庫文件, 模塊 \"%s\" 無法正常加載 無障礙服務未啓用 無障礙服務未啓用 @@ -282,8 +291,12 @@ 未找到用於播放該文件的應用 未找到用於發送該文件的應用 未找到用於查看該文件的應用 + 未找到可用且已啓用的 %1$s 插件變體 (%2$s). 當前插件未提供可用的 URL 缺少 \"顯示在其他應用上層\" 權限 + 未找到內置 Paddle OCR 資源, 請在打包時勾選並注入 Paddle OCR 後重試. + \"%1$s\" 沒有已啓用的插件. 請先啓用插件, 然後重試. + 未找到可用的 Paddle OCR 插件 缺少 Shizuku 訪問權限 缺少 \"發佈通知\" 權限 缺少 \"讀取手機狀態\" 權限 @@ -296,13 +309,17 @@ 解析 GitHub 發行版資源信息失敗 無法解析版本信息 正則表達式句法錯誤 + 插件 APK 不包含變體 \"%1$s\" 所需的資源文件: %2$s. + 插件 APK 不包含所需的 native 庫文件: %1$s. + %1$s 插件返回的 info 為空. + %1$s 插件返回的 variant 無效: %2$s. 端口號超過 65535 項目主腳本文件 \"%1$s\" 不存在 無法將值 %s 存入 JSON 正則表達式不支持向前查找 重複的分號符號 重複的句點符號 - 必需屬性 "%1$s" 為空或不存在 + 必需屬性 \"%1$s\" 為空或不存在 解析後的路徑 \"%1$s\" 不可為 null 腳本正在退出中 選擇器方法需調用而不可作為參數直接傳入: %s @@ -312,8 +329,9 @@ Shizuku 服務可能未運行 Shizuku 版本不支持 指定的 AutoJs6 應用版本號需大於 461 - 必需屬性 "%1$s" 的轉換器不能返回空值 + 必需屬性 \"%1$s\" 的轉換器不能返回空值 線程處於非活動狀態 + 查詢 %1$s 插件信息超時. 無法使用 Shizuku 服務 不接受的字符 未知錯誤 @@ -343,8 +361,8 @@ 支持 IPv4, IPv6 及域名. 輸入一個指向遠程插件地址的 URL.\n例如 \"https://example.com/plugin.apk\". 最近使用: %1$s - 線程 "blob" 請求失敗 - 線程 "blob" 請求成功, 寫入離線緩存 + 線程 \"blob\" 請求失敗 + 線程 \"blob\" 請求成功, 寫入離線緩存 數據加載完畢 初始內容選用 插入新條目 @@ -358,10 +376,10 @@ 離線緩存文件最新版本 覆寫日期內容 覆寫更新記錄 - 線程 "raw" 請求失敗 - 線程 "raw" 請求成功, 寫入離線緩存 - 啓動 "blob" 備用請求線程 - 啓動 "raw" 請求線程 + 線程 \"raw\" 請求失敗 + 線程 \"raw\" 請求成功, 寫入離線緩存 + 啓動 \"blob\" 備用請求線程 + 啓動 \"raw\" 請求線程 專輯 縱橫比 音頻 @@ -402,6 +420,7 @@ 自動嘗試使用 root 權限啓用無障礙服務 自動嘗試使用修改安全設置權限啓用無障礙服務 擴展 JavaScript 內置對象以增加代碼靈活性 + 前台服務用於在後台更穩定地保持應用及腳本運行 當 AutoJs6 前置時禁用自動化行為以避免誤操作 啓動應用後直接運行腳本 允許 AutoJs6 創建併發送通知 @@ -414,10 +433,12 @@ 按 \"音量減\" 鍵開始或停止腳本錄製 (需開啓浮動按鈕) 按 \"音量加\" 鍵停止所有正在運行的腳本 查看發行版本歷史更新記錄與統計數據 + 內部存儲 無障礙服務 腳本自動操作 (點擊/長按/滑動等) 所需 無障礙服務已啓用但未運行 (嘗試重新啓用或重啓設備) 可能需要啓用無障礙服務 + 正在中止... 關於 關於所有文件訪問權限 關於應用與開發者 @@ -440,6 +461,7 @@ 別名 別名不能為空 別名密碼 + 全部 所有文件管理權限 需要授予 \"所有文件管理權限\" 才能正常讀寫腳本文件 全部歷史記錄 @@ -492,7 +514,7 @@ 應用版本號 應用版本名 外觀 - “姓名、組織名稱、組織單位、國家代碼、州或省份、城市或區域、街道”至少填寫一個 + [姓名, 組織名稱, 組織單位, 國家代碼, 州或省份, 城市或區域, 街道] 至少填寫一個 屬性 自動檢查更新 自動檢查更新並在首頁下方顯示通知條 @@ -576,7 +598,11 @@ 複製原目錄文件到新目錄 複製指令 複製調試信息 + 複製文件 + 複製文件夾 複製行 + 源路徑與目標路徑相同, 是否繼續複製.\n\n新名稱: \"%1$s\" + 複製到 複製到剪貼板 複製值 國家代碼 (XX) @@ -599,10 +625,14 @@ 默認 預設密鑰庫 默認前綴 + 延遲時間 刪除 刪除全部 + 刪除文件 + 刪除文件夾 刪除行 描述 + 目標 詳情 \"開發者詳情\" 正在開發中... 開發者選項 @@ -615,7 +645,7 @@ 設備產品名稱 設備屏幕分辨率 直接下載 - 文件夾 + 目錄 已禁用 顯示在其他應用上層 建議授予 \"顯示在其他應用上層\" 權限以確保應用窗口組件正常顯示 @@ -712,6 +742,7 @@ 上一個 姓名 浮動按鈕 + 文件夾 強制停止 前台服務 格式化已完成 @@ -753,6 +784,7 @@ 從 \"URL\" 安裝 從 \"URL\" 安裝插件 可安裝 + 已安裝 完整性驗證失敗 無效字符已被移除 無效包名 @@ -808,7 +840,12 @@ 未安裝 \"手機QQ\" 更多 瞭解詳情 + 移動 + 源路徑與目標路徑相同, 移動操作中止 移動原目錄文件到新目錄 + 移動文件 + 移動文件夾 + 移動到 多個可選項 名稱 需要啓用無障礙服務 @@ -836,6 +873,7 @@ 無 root 權限 無運行中的腳本 未授予 + 未安裝 不顯示主界面 通知 通知讀取權限 @@ -850,6 +888,8 @@ 用其他應用打開 打開主界面 打開方式 + 已中止 + 已完成 操作已完成 選項 組織名稱 @@ -938,6 +978,7 @@ 權限授予失敗 (使用 Shizuku) 已授予權限 (使用 root) 已授予權限 (使用 Shizuku) + 權限管理 允許應用程式訪問其他應用程式的使用統計數據 已撤消授權 權限撤消失敗 (使用 root) @@ -961,6 +1002,7 @@ 指針位置 切換 \"指針位置\" 顯示狀態失敗\n可能缺少 root 權限 發佈通知權限 + 為確保 AutoJs6 前台服務等能夠正常運行, 腳本能夠發佈通知, AutoJs6 需要被授予 \"發佈通知權限\". 預執行腳本 準備中... 預設對話框內容 @@ -975,6 +1017,9 @@ 項目位置 投影媒體權限 提示 + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s 放棄 推薦 錄製完成 @@ -1043,6 +1088,7 @@ 保存到 調度引擎 啓動延遲 + 屏幕捕獲權限申請延遲 錄製腳本 腳本運行 搜索 @@ -1062,6 +1108,7 @@ 創建快捷方式 服務端模式 服務 + 服務管理 用作工作路徑 設置斷點 設置 @@ -1078,6 +1125,10 @@ 大小 已導出 %d 個條目 排序 + 按最近更新排序 + 按名稱排序 + 按安裝包大小排序 + 來源 源代碼路徑 特殊權限 穩定模式 @@ -1170,36 +1221,4 @@ 修改安全設置 修改系統設置 後台彈出界面 - 未找到可用的 Paddle OCR 插件 - 已安裝 - 未安裝 - 全部 - 按名稱排序 - 按最近更新排序 - 按安裝包大小排序 - 缺少 \"%1$s\" 所需的插件. 請先安裝插件, 然後重試. - \"%1$s\" 沒有已啓用的插件. 請先啓用插件, 然後重試. - 未找到可用且已啓用的 %1$s 插件變體 (%2$s). - 插件 APK 不包含變體 \"%1$s\" 所需的資源文件: %2$s. - 插件 APK 不包含所需的 native 庫文件: %1$s. - 綁定 %1$s 插件服務失敗. - 查詢 %1$s 插件信息超時. - %1$s 插件返回的 info 為空. - %1$s 插件返回的 variant 無效: %2$s. - 未找到內置 Paddle OCR 資源, 請在打包時勾選並注入 Paddle OCR 後重試. - 最小化 - %1$s: %2$d%3$s - %1$s: %2$d %3$s - 屏幕捕獲權限申請延遲 - 申請屏幕捕獲權限時, 彈出的權限申請窗口消失時可能存在漸變動畫, 此時如果立即調用 `images.captureScreen` 方法, 獲取的屏幕截圖中會出現權限申請的窗口內容而造成遮擋.\n\n當前設置選項值用於在截圖權限申請後立即獲取屏幕截圖前增加一個延遲時間 (單位為毫秒), 可用於避免上述遮擋問題.\n\n當前設置選項僅適用於獲取截圖權限後的首次截圖操作, 後續截圖操作不再受此設置值影響. - 延遲時間 - 主頁 - 開關狀態改變失敗 - 為確保 AutoJs6 前台服務等能夠正常運行, 腳本能夠發佈通知, AutoJs6 需要被授予 \"發佈通知權限\". - \"指針位置\" 是安卓開發者選項中的調試功能.\n開啓後, 系統會在屏幕上顯示觸摸點的 [座標/移動軌跡/數量/大小/移動速度/壓力] 等信息, 便於相關腳本的 [編寫/調試/校對] 等. - 發生錯誤 - 權限管理 - 服務管理 - 前台服務用於在後台更穩定地保持應用及腳本運行 - - + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index a643acf2..748f8124 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -4,7 +4,6 @@ - 構建中... 清理臨時檔案... 打包中... @@ -49,7 +48,8 @@ 配置 \"abi\" 含不可用選項 配置 \"lib\" 含無效選項 配置 \"lib\" 含不可用選項 - 檔案已存在, 是否覆蓋 + 資料夾已存在, 是否覆蓋. + 檔案已存在, 是否覆蓋. 1. 長按主頁應用名稱 (AutoJs6) 可跳轉至設定頁面\n2. 設定頁面長按設定選項可檢視詳細資訊 當前主題色 %1$s 由調色盤配置 用於顯示清單內容的浮動操作按鈕控制元件 @@ -92,12 +92,14 @@ 夜間模式, 亦稱 [ 暗黑模式 / 深色主題 ] 等.\n夜間模式應用於安卓系統 UI (如通知欄和導航欄) 及 AutoJs6 應用頁面.\n夜間模式可提升裝置在低光環境下的易用性, 同時有助於提升弱視或光敏感使用者的視覺體驗.\n\n跟隨系統: AutoJs6 與安卓作業系統的夜間模式設定一致\n總是開啟: AutoJs6 保持開啟夜間模式 (忽略作業系統設定)\n總是關閉: AutoJs6 保持關閉夜間模式 (忽略作業系統設定)\n\n注: 跟隨系統功能僅支援安卓 API 級別 28 (安卓 9) [P] 及以上作業系統. 啟用安卓系統的夜間模式:\n- API 級別 29 (安卓 10) [Q] 及以上: 透過 [ 設定 -> 顯示 -> 主題 ] 開啟.\n- API 級別 28 (安卓 9) [P]: 透過 [ 開發者選項 -> 夜間模式 ] 開啟.\n\n對於基於 WebView 元件的內容 (如 AutoJs6 的文件頁面), 夜間模式支援需要滿足以下條件:\n1. WebView (或 Google Chrome 等瀏覽器) 版本要求:\n- API 級別 29 (安卓 10) [Q] 及以上: 版本不低於 76\n- API 級別 28 (安卓 9) [P]: 版本不低於 105\n2. WebView 元件頁面內容可適配夜間模式 (透過 CSS 或 安卓 XML 資源等方式實現) \"通知使用權\" (或 \"通知讀取許可權\") 允許 AutoJs6 讀取系統通知內容, 使指令碼可以監聽通知或獲取通知文字等. + \"指標位置\" 是安卓開發者選項中的除錯功能.\n開啟後, 系統會在螢幕上顯示觸控點的 [座標/移動軌跡/數量/大小/移動速度/壓力] 等資訊, 便於相關指令碼的 [編寫/除錯/校對] 等. \"傳送通知\" 許可權允許 AutoJs6 向系統釋出通知, 使指令碼可以在通知欄釋出並管理自定義通知等.\n\n注: 在 Android 13+ 裝置上未授予該許可權時, 部分通知可能無法顯示, 並可能影響前臺服務的啟動與穩定性. 被授予 \"投影媒體許可權\" 後, 錄製螢幕的安全提示視窗將不再彈出. 重啟策略僅作用於主頁抽屜欄的重啟按鈕.\n\n快速重啟: 快速重啟應用, 如果重啟失敗或出現非預期情況, 可嘗試切換至 \"計劃重啟\".\n計劃重啟: 提前設定一個短時定時任務, 應用停止後會再次定時啟動, 以實現應用重啟. 開關啟用 (預設): 將 Java 方法返回的 Number/Boolean/Character 包裝為 Java 物件暴露到指令碼 (String 除外). typeof 為 \"object\", species 為 \"JavaObject\", 可訪問這些物件的 Java 方法, 利於保留 Java 精確型別特徵與方法過載行為.\n\n開關禁用: 不再包裝上述型別, 直接作為 JavaScript 基元值 (number/boolean/單字元字串). typeof 為相應 JavaScript 型別, 更貼近 JavaScript 語義與生態. 但仍可透過 new 關鍵字顯式宣告一個 Java 包裝型別, 如 new java.lang.Boolean(true).\n\n參閱: http://issues.autojs6.com/435 如果裝置使用非常規 Root 方式或 Root 許可權檢測結果異常, 可設定 \"強制 Root 模式\" 或 \"強制非 Root 模式\". 二進位制檔案: 不可編輯, 副檔名為 \"auto\"\nJavaScript 檔案: 可編輯或直接複製, 副檔名為 \"js\" + 申請螢幕捕獲許可權時, 彈出的許可權申請視窗消失時可能存在漸變動畫, 此時如果立即呼叫 `images.captureScreen` 方法, 獲取的螢幕截圖中會出現許可權申請的視窗內容而造成遮擋.\n\n當前設定選項值用於在截圖許可權申請後立即獲取螢幕截圖前增加一個延遲時間 (單位為毫秒), 可用於避免上述遮擋問題.\n\n當前設定選項僅適用於獲取截圖許可權後的首次截圖操作, 後續截圖操作不再受此設定值影響. 服務端模式用於讓 AutoJs6 在當前裝置開啟服務並等待外部客戶端連線, 以便進行 [ 指令碼傳輸 / 列印日誌 / 遠端控制 ] 等.\n\nAutoJs6 服務端模式支援兩種連線方式:\n1. 區域網 (LAN)\n2. 安卓除錯橋 (ADB) 透過 Shizuku 可以獲得 ADB 特權並使用系統 API 穩定模式省略佈局細節, 指令碼分析佈局時更穩定, 但可能影響獲取的控制元件總量.\n需重啟無障礙服務. @@ -109,6 +111,8 @@ 安全設定包含應用程式可讀但不可寫入的設定選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設定許可權\" 後, 普通應用可直接修改上述安全設定 (例如無障礙服務). \"修改系統設定\" 許可權允許 AutoJs6 修改部分系統設定項, 使指令碼可以修改 [ 螢幕亮度 / 自動旋轉 / 螢幕超時 ] 等系統設定引數. 放棄 + 中止 + 中止連線 高階設定 修正地址 @string/text_back @@ -126,10 +130,11 @@ 異常詳情 檔案資訊 歷史記錄 + 主頁 忽略此版本 - 中止連線 加入群組 管理器 + 最小化 瞭解更多 開啟調色盤 放棄 @@ -189,6 +194,7 @@ 方法 %s 已被廢棄, 應避免使用 無法完成 \"%1$s\" 操作, 因為引數中包含負數座標值 (%2$d,%3$d) 缺少必要的 activity 物件, 可透過 \"ui\" 執行模式來提供 + 發生錯誤 操作尚未實現 應用未安裝 應用未安裝: \"%s\" @@ -227,8 +233,10 @@ 高度超限: 模板影象 [%1$d] > 限定區域 [%2$d] 寬度超限: 模板影象 [%1$d] > 限定區域 [%2$d] 應用當前歷史顏色失敗 + 繫結 %1$s 外掛服務失敗. 方法 \"%s\" 呼叫失敗 + 開關狀態改變失敗 無法將值 %s 轉換為 Drawable 例項 跳轉設定頁面失敗 Shizuku 許可權授予失敗 @@ -272,6 +280,7 @@ AutoJs6 可能因缺少 Root 許可權而無法執行 \"auto\" 檔案 %s() 傳入的 %s 引數為空 方法僅可接受引數數量位於 [%1$d\.\.%2$d] 區間內 + 缺少 \"%1$s\" 所需的外掛. 請先安裝外掛, 然後重試. 由於缺少必要的庫檔案, 模組 \"%s\" 無法正常載入 無障礙服務未啟用 無障礙服務未啟用 @@ -282,8 +291,12 @@ 未找到用於播放該檔案的應用 未找到用於傳送該檔案的應用 未找到用於檢視該檔案的應用 + 未找到可用且已啟用的 %1$s 外掛變體 (%2$s). 當前外掛未提供可用的 URL 缺少 \"顯示在其他應用上層\" 許可權 + 未找到內建 Paddle OCR 資源, 請在打包時勾選並注入 Paddle OCR 後重試. + \"%1$s\" 沒有已啟用的外掛. 請先啟用外掛, 然後重試. + 未找到可用的 Paddle OCR 外掛 缺少 Shizuku 訪問許可權 缺少 \"釋出通知\" 許可權 缺少 \"讀取手機狀態\" 許可權 @@ -296,13 +309,17 @@ 解析 GitHub 發行版資源資訊失敗 無法解析版本資訊 正則表示式句法錯誤 + 外掛 APK 不包含變體 \"%1$s\" 所需的資原始檔: %2$s. + 外掛 APK 不包含所需的 native 庫檔案: %1$s. + %1$s 外掛返回的 info 為空. + %1$s 外掛返回的 variant 無效: %2$s. 埠號超過 65535 專案主指令碼檔案 \"%1$s\" 不存在 無法將值 %s 存入 JSON 正則表示式不支援向前查詢 重複的分號符號 重複的句點符號 - 必需屬性 "%1$s" 為空或不存在 + 必需屬性 \"%1$s\" 為空或不存在 解析後的路徑 \"%1$s\" 不可為 null 指令碼正在退出中 選擇器方法需呼叫而不可作為引數直接傳入: %s @@ -312,8 +329,9 @@ Shizuku 服務可能未執行 Shizuku 版本不支援 指定的 AutoJs6 應用版本號需大於 461 - 必需屬性 "%1$s" 的轉換器不能返回空值 + 必需屬性 \"%1$s\" 的轉換器不能返回空值 執行緒處於非活動狀態 + 查詢 %1$s 外掛資訊超時. 無法使用 Shizuku 服務 不接受的字元 未知錯誤 @@ -343,8 +361,8 @@ 支援 IPv4, IPv6 及域名. 輸入一個指向遠端外掛地址的 URL.\n例如 \"https://example.com/plugin.apk\". 最近使用: %1$s - 執行緒 "blob" 請求失敗 - 執行緒 "blob" 請求成功, 寫入離線快取 + 執行緒 \"blob\" 請求失敗 + 執行緒 \"blob\" 請求成功, 寫入離線快取 資料載入完畢 初始內容選用 插入新條目 @@ -358,10 +376,10 @@ 離線快取檔案最新版本 覆寫日期內容 覆寫更新記錄 - 執行緒 "raw" 請求失敗 - 執行緒 "raw" 請求成功, 寫入離線快取 - 啟動 "blob" 備用請求執行緒 - 啟動 "raw" 請求執行緒 + 執行緒 \"raw\" 請求失敗 + 執行緒 \"raw\" 請求成功, 寫入離線快取 + 啟動 \"blob\" 備用請求執行緒 + 啟動 \"raw\" 請求執行緒 專輯 縱橫比 音訊 @@ -402,6 +420,7 @@ 自動嘗試使用 root 許可權啟用無障礙服務 自動嘗試使用修改安全設定許可權啟用無障礙服務 擴充套件 JavaScript 內建物件以增加程式碼靈活性 + 前臺服務用於在後臺更穩定地保持應用及指令碼執行 當 AutoJs6 前置時禁用自動化行為以避免誤操作 啟動應用後直接執行指令碼 允許 AutoJs6 建立併發送通知 @@ -414,10 +433,12 @@ 按 \"音量減\" 鍵開始或停止指令碼錄製 (需開啟浮動按鈕) 按 \"音量加\" 鍵停止所有正在執行的指令碼 檢視發行版本歷史更新記錄與統計資料 + 內部儲存 無障礙服務 指令碼自動操作 (點選/長按/滑動等) 所需 無障礙服務已啟用但未執行 (嘗試重新啟用或重啟裝置) 可能需要啟用無障礙服務 + 正在中止... 關於 關於所有檔案訪問許可權 關於應用與開發者 @@ -440,6 +461,7 @@ 別名 別名不能為空 別名密碼 + 全部 所有檔案管理許可權 需要授予 \"所有檔案管理許可權\" 才能正常讀寫指令碼檔案 全部歷史記錄 @@ -492,7 +514,7 @@ 應用版本號 應用版本名 外觀 - “姓名、組織名稱、組織單位、國家代碼、州或省份、城市或區域、街道”至少填寫一個 + [姓名, 組織名稱, 組織單位, 國家代碼, 州或省份, 城市或區域, 街道] 至少填寫一個 屬性 自動檢查更新 自動檢查更新並在首頁下方顯示通知條 @@ -576,7 +598,11 @@ 複製原目錄檔案到新目錄 複製指令 複製除錯資訊 + 複製檔案 + 複製資料夾 複製行 + 源路徑與目標路徑相同, 是否繼續複製.\n\n新名稱: \"%1$s\" + 複製到 複製到剪貼簿 複製值 國家代碼 (XX) @@ -599,10 +625,14 @@ 預設 預設密鑰庫 預設字首 + 延遲時間 刪除 刪除全部 + 刪除檔案 + 刪除資料夾 刪除行 描述 + 目標 詳情 \"開發者詳情\" 正在開發中... 開發者選項 @@ -615,7 +645,7 @@ 裝置產品名稱 裝置螢幕解析度 直接下載 - 資料夾 + 目錄 已禁用 顯示在其他應用上層 建議授予 \"顯示在其他應用上層\" 許可權以確保應用視窗元件正常顯示 @@ -712,6 +742,7 @@ 上一個 姓名 浮動按鈕 + 資料夾 強制停止 前臺服務 格式化已完成 @@ -753,6 +784,7 @@ 從 \"URL\" 安裝 從 \"URL\" 安裝外掛 可安裝 + 已安裝 完整性驗證失敗 無效字元已被移除 無效包名 @@ -808,7 +840,12 @@ 未安裝 \"手機QQ\" 更多 瞭解詳情 + 移動 + 源路徑與目標路徑相同, 移動操作中止 移動原目錄檔案到新目錄 + 移動檔案 + 移動資料夾 + 移動到 多個可選項 名稱 需要啟用無障礙服務 @@ -836,6 +873,7 @@ 無 root 許可權 無執行中的指令碼 未授予 + 未安裝 不顯示主介面 通知 通知讀取許可權 @@ -850,6 +888,8 @@ 用其他應用開啟 開啟主介面 開啟方式 + 已中止 + 已完成 操作已完成 選項 組織名稱 @@ -938,6 +978,7 @@ 許可權授予失敗 (使用 Shizuku) 已授予許可權 (使用 root) 已授予許可權 (使用 Shizuku) + 許可權管理 允許應用程式訪問其他應用程式的使用統計數據 已撤消授權 許可權撤消失敗 (使用 root) @@ -961,6 +1002,7 @@ 指標位置 切換 \"指標位置\" 顯示狀態失敗\n可能缺少 root 許可權 釋出通知許可權 + 為確保 AutoJs6 前臺服務等能夠正常執行, 指令碼能夠釋出通知, AutoJs6 需要被授予 \"釋出通知許可權\". 預執行指令碼 準備中... 預設對話方塊內容 @@ -975,6 +1017,9 @@ 專案位置 投影媒體許可權 提示 + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s 放棄 推薦 錄製完成 @@ -1043,6 +1088,7 @@ 儲存到 排程引擎 啟動延遲 + 螢幕捕獲許可權申請延遲 錄製指令碼 指令碼執行 搜尋 @@ -1062,6 +1108,7 @@ 建立快捷方式 服務端模式 服務 + 服務管理 用作工作路徑 設定斷點 設定 @@ -1078,6 +1125,10 @@ 大小 已匯出 %d 個條目 排序 + 按最近更新排序 + 按名稱排序 + 按安裝包大小排序 + 來源 原始碼路徑 特殊許可權 穩定模式 @@ -1170,36 +1221,4 @@ 修改安全設定 修改系統設定 後臺彈出介面 - 未找到可用的 Paddle OCR 外掛 - 已安裝 - 未安裝 - 全部 - 按名稱排序 - 按最近更新排序 - 按安裝包大小排序 - 缺少 \"%1$s\" 所需的外掛. 請先安裝外掛, 然後重試. - \"%1$s\" 沒有已啟用的外掛. 請先啟用外掛, 然後重試. - 未找到可用且已啟用的 %1$s 外掛變體 (%2$s). - 外掛 APK 不包含變體 \"%1$s\" 所需的資原始檔: %2$s. - 外掛 APK 不包含所需的 native 庫檔案: %1$s. - 繫結 %1$s 外掛服務失敗. - 查詢 %1$s 外掛資訊超時. - %1$s 外掛返回的 info 為空. - %1$s 外掛返回的 variant 無效: %2$s. - 未找到內建 Paddle OCR 資源, 請在打包時勾選並注入 Paddle OCR 後重試. - 最小化 - %1$s: %2$d%3$s - %1$s: %2$d %3$s - 螢幕捕獲許可權申請延遲 - 申請螢幕捕獲許可權時, 彈出的許可權申請視窗消失時可能存在漸變動畫, 此時如果立即呼叫 `images.captureScreen` 方法, 獲取的螢幕截圖中會出現許可權申請的視窗內容而造成遮擋.\n\n當前設定選項值用於在截圖許可權申請後立即獲取螢幕截圖前增加一個延遲時間 (單位為毫秒), 可用於避免上述遮擋問題.\n\n當前設定選項僅適用於獲取截圖許可權後的首次截圖操作, 後續截圖操作不再受此設定值影響. - 延遲時間 - 主頁 - 開關狀態改變失敗 - 為確保 AutoJs6 前臺服務等能夠正常執行, 指令碼能夠釋出通知, AutoJs6 需要被授予 \"釋出通知許可權\". - \"指標位置\" 是安卓開發者選項中的除錯功能.\n開啟後, 系統會在螢幕上顯示觸控點的 [座標/移動軌跡/數量/大小/移動速度/壓力] 等資訊, 便於相關指令碼的 [編寫/除錯/校對] 等. - 發生錯誤 - 許可權管理 - 服務管理 - 前臺服務用於在後臺更穩定地保持應用及指令碼執行 - - + \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index e7fc6acb..f79e01d5 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -3,7 +3,6 @@ - 构建中... 清理临时文件... 打包中... @@ -48,7 +47,8 @@ 配置 \"abi\" 含不可用选项 配置 \"lib\" 含无效选项 配置 \"lib\" 含不可用选项 - 文件已存在, 是否覆盖 + 文件夹已存在, 是否覆盖. + 文件已存在, 是否覆盖. 1. 长按主页应用名称 (AutoJs6) 可跳转至设置页面\n2. 设置页面长按设置选项可查看详细信息 当前主题色 %1$s 由调色盘配置 用于显示清单内容的浮动操作按钮控件 @@ -92,12 +92,14 @@ 夜间模式, 亦称 [ 暗黑模式 / 深色主题 ] 等.\n夜间模式应用于安卓系统 UI (如通知栏和导航栏) 及 AutoJs6 应用页面.\n夜间模式可提升设备在低光环境下的易用性, 同时有助于提升弱视或光敏感用户的视觉体验.\n\n跟随系统: AutoJs6 与安卓操作系统的夜间模式设置一致\n总是开启: AutoJs6 保持开启夜间模式 (忽略操作系统设置)\n总是关闭: AutoJs6 保持关闭夜间模式 (忽略操作系统设置)\n\n注: 跟随系统功能仅支持安卓 API 级别 28 (安卓 9) [P] 及以上操作系统. 启用安卓系统的夜间模式:\n- API 级别 29 (安卓 10) [Q] 及以上: 通过 [ 设置 -> 显示 -> 主题 ] 开启.\n- API 级别 28 (安卓 9) [P]: 通过 [ 开发者选项 -> 夜间模式 ] 开启.\n\n对于基于 WebView 组件的内容 (如 AutoJs6 的文档页面), 夜间模式支持需要满足以下条件:\n1. WebView (或 Google Chrome 等浏览器) 版本要求:\n- API 级别 29 (安卓 10) [Q] 及以上: 版本不低于 76\n- API 级别 28 (安卓 9) [P]: 版本不低于 105\n2. WebView 组件页面内容可适配夜间模式 (通过 CSS 或 安卓 XML 资源等方式实现) \"通知使用权\" (或 \"通知读取权限\") 允许 AutoJs6 读取系统通知内容, 使脚本可以监听通知或获取通知文本等. + \"指针位置\" 是安卓开发者选项中的调试功能.\n开启后, 系统会在屏幕上显示触摸点的 [坐标/移动轨迹/数量/大小/移动速度/压力] 等信息, 便于相关脚本的 [编写/调试/校对] 等. \"发送通知\" 权限允许 AutoJs6 向系统发布通知, 使脚本可以在通知栏发布并管理自定义通知等.\n\n注: 在 Android 13+ 设备上未授予该权限时, 部分通知可能无法显示, 并可能影响前台服务的启动与稳定性. 被授予 \"投影媒体权限\" 后, 录制屏幕的安全提示窗口将不再弹出. 重启策略仅作用于主页抽屉栏的重启按钮.\n\n快速重启: 快速重启应用, 如果重启失败或出现非预期情况, 可尝试切换至 \"计划重启\".\n计划重启: 提前设置一个短时定时任务, 应用停止后会再次定时启动, 以实现应用重启. 开关启用 (默认): 将 Java 方法返回的 Number/Boolean/Character 包装为 Java 对象暴露到脚本 (String 除外). typeof 为 \"object\", species 为 \"JavaObject\", 可访问这些对象的 Java 方法, 利于保留 Java 精确类型特征与方法重载行为.\n\n开关禁用: 不再包装上述类型, 直接作为 JavaScript 基元值 (number/boolean/单字符字符串). typeof 为相应 JavaScript 类型, 更贴近 JavaScript 语义与生态. 但仍可通过 new 关键字显式声明一个 Java 包装类型, 如 new java.lang.Boolean(true).\n\n参阅: http://issues.autojs6.com/435 如果设备使用非常规 Root 方式或 Root 权限检测结果异常, 可设置 \"强制 Root 模式\" 或 \"强制非 Root 模式\". 二进制文件: 不可编辑, 文件扩展名为 \"auto\"\nJavaScript 文件: 可编辑或直接复制, 文件扩展名为 \"js\" + 申请屏幕捕获权限时, 弹出的权限申请窗口消失时可能存在渐变动画, 此时如果立即调用 `images.captureScreen` 方法, 获取的屏幕截图中会出现权限申请的窗口内容而造成遮挡.\n\n当前设置选项值用于在截图权限申请后立即获取屏幕截图前增加一个延迟时间 (单位为毫秒), 可用于避免上述遮挡问题.\n\n当前设置选项仅适用于获取截图权限后的首次截图操作, 后续截图操作不再受此设置值影响. 服务端模式用于让 AutoJs6 在当前设备开启服务并等待外部客户端连接, 以便进行 [ 脚本传输 / 打印日志 / 远程控制 ] 等.\n\nAutoJs6 服务端模式支持两种连接方式:\n1. 局域网 (LAN)\n2. 安卓调试桥 (ADB) 通过 Shizuku 可以获得 ADB 特权并使用系统 API 稳定模式省略布局细节, 脚本分析布局时更稳定, 但可能影响获取的控件总量.\n需重启无障碍服务. @@ -109,6 +111,8 @@ 安全设置包含应用程序可读但不可写入的设置选项, 这些选项只能由 UI 或系统级别应用修改.\n被授予 \"修改安全设置权限\" 后, 普通应用可直接修改上述安全设置 (例如无障碍服务). \"修改系统设置\" 权限允许 AutoJs6 修改部分系统设置项, 使脚本可以修改 [ 屏幕亮度 / 自动旋转 / 屏幕超时 ] 等系统设置参数. 放弃 + 中止 + 中止连接 高级设置 修正地址 @string/text_back @@ -126,10 +130,11 @@ 异常详情 文件信息 历史记录 + 主页 忽略此版本 - 中止连接 加入群组 管理器 + 最小化 了解更多 打开调色盘 放弃 @@ -189,6 +194,7 @@ 方法 %s 已被废弃, 应避免使用 无法完成 \"%1$s\" 操作, 因为参数中包含负数坐标值 (%2$d,%3$d) 缺少必要的 activity 对象, 可通过 \"ui\" 执行模式来提供 + 发生错误 操作尚未实现 应用未安装 应用未安装: \"%s\" @@ -227,8 +233,10 @@ 高度超限: 模板图像 [%1$d] > 限定区域 [%2$d] 宽度超限: 模板图像 [%1$d] > 限定区域 [%2$d] 应用当前历史颜色失败 + 绑定 %1$s 插件服务失败. 方法 \"%s\" 调用失败 + 开关状态改变失败 无法将值 %s 转换为 Drawable 实例 跳转设置页面失败 Shizuku 权限授予失败 @@ -272,6 +280,7 @@ AutoJs6 可能因缺少 Root 权限而无法运行 \"auto\" 文件 %s() 传入的 %s 参数为空 方法仅可接受参数数量位于 [%1$d\.\.%2$d] 区间内 + 缺少 \"%1$s\" 所需的插件. 请先安装插件, 然后重试. 由于缺少必要的库文件, 模块 \"%s\" 无法正常加载 无障碍服务未启用 无障碍服务未启用 @@ -282,8 +291,12 @@ 未找到用于播放该文件的应用 未找到用于发送该文件的应用 未找到用于查看该文件的应用 + 未找到可用且已启用的 %1$s 插件变体 (%2$s). 当前插件未提供可用的 URL 缺少 \"显示在其他应用上层\" 权限 + 未找到内置 Paddle OCR 资源, 请在打包时勾选并注入 Paddle OCR 后重试. + \"%1$s\" 没有已启用的插件. 请先启用插件, 然后重试. + 未找到可用的 Paddle OCR 插件 缺少 Shizuku 访问权限 缺少 \"发布通知\" 权限 缺少 \"读取手机状态\" 权限 @@ -296,13 +309,17 @@ 解析 GitHub 发行版资源信息失败 无法解析版本信息 正则表达式句法错误 + 插件 APK 不包含变体 \"%1$s\" 所需的资源文件: %2$s. + 插件 APK 不包含所需的 native 库文件: %1$s. + %1$s 插件返回的 info 为空. + %1$s 插件返回的 variant 无效: %2$s. 端口号超过 65535 项目主脚本文件 \"%1$s\" 不存在 无法将值 %s 存入 JSON 正则表达式不支持向前查找 重复的分号符号 重复的句点符号 - 必需属性 "%1$s" 为空或不存在 + 必需属性 \"%1$s\" 为空或不存在 解析后的路径 \"%1$s\" 不可为 null 脚本正在退出中 选择器方法需调用而不可作为参数直接传入: %s @@ -312,8 +329,9 @@ Shizuku 服务可能未运行 Shizuku 版本不支持 指定的 AutoJs6 应用版本号需大于 461 - 必需属性 "%1$s" 的转换器不能返回空值 + 必需属性 \"%1$s\" 的转换器不能返回空值 线程处于非活动状态 + 查询 %1$s 插件信息超时. 无法使用 Shizuku 服务 不接受的字符 未知错误 @@ -402,6 +420,7 @@ 自动尝试使用 root 权限启用无障碍服务 自动尝试使用修改安全设置权限启用无障碍服务 扩展 JavaScript 内置对象以增加代码灵活性 + 前台服务用于在后台更稳定地保持应用及脚本运行 当 AutoJs6 前置时禁用自动化行为以避免误操作 启动应用后直接运行脚本 允许 AutoJs6 创建并发送通知 @@ -414,10 +433,12 @@ 按 \"音量减\" 键开始或停止脚本录制 (需开启浮动按钮) 按 \"音量加\" 键停止所有正在运行的脚本 查看发行版本历史更新记录与统计数据 + 内部存储 无障碍服务 脚本自动操作 (点击/长按/滑动等) 所需 无障碍服务已启用但未运行 (尝试重新启用或重启设备) 可能需要启用无障碍服务 + 正在中止... 关于 关于所有文件访问权限 关于应用与开发者 @@ -440,6 +461,7 @@ 别名 别名不能为空 别名密码 + 全部 所有文件管理权限 需要授予 \"所有文件管理权限\" 才能正常读写脚本文件 全部历史记录 @@ -492,7 +514,7 @@ 应用版本号 应用版本名 外观 - “姓名、组织名称、组织单位、国家代码、州或省份、城市或区域、街道”至少填写一个 + [姓名, 组织名称, 组织单位, 国家代码, 州或省份, 城市或区域, 街道] 至少填写一个 属性 自动检查更新 自动检查更新并在首页下方显示通知条 @@ -576,7 +598,11 @@ 复制原目录文件到新目录 复制指令 复制调试信息 + 复制文件 + 复制文件夹 复制行 + 源路径与目标路径相同, 是否继续复制.\n\n新名称: \"%1$s\" + 复制到 复制到剪贴板 复制值 国家代码 (XX) @@ -599,10 +625,14 @@ 默认 默认密钥库 默认前缀 + 延迟时间 删除 删除全部 + 删除文件 + 删除文件夹 删除行 描述 + 目标 详情 \"开发者详情\" 正在开发中... 开发者选项 @@ -615,7 +645,7 @@ 设备产品名称 设备屏幕分辨率 直接下载 - 文件夹 + 目录 已禁用 显示在其他应用上层 建议授予 \"显示在其他应用上层\" 权限以确保应用窗口组件正常显示 @@ -712,6 +742,7 @@ 上一个 姓名 浮动按钮 + 文件夹 强制停止 前台服务 格式化已完成 @@ -753,6 +784,7 @@ 从 \"URL\" 安装 从 \"URL\" 安装插件 可安装 + 已安装 完整性验证失败 无效字符已被移除 无效包名 @@ -808,7 +840,12 @@ 未安装 \"手机QQ\" 更多 了解详情 + 移动 + 源路径与目标路径相同, 移动操作中止 移动原目录文件到新目录 + 移动文件 + 移动文件夹 + 移动到 多个可选项 名称 需要启用无障碍服务 @@ -836,6 +873,7 @@ 无 root 权限 无运行中的脚本 未授予 + 未安装 不显示主界面 通知 通知读取权限 @@ -850,6 +888,8 @@ 用其他应用打开 打开主界面 打开方式 + 已中止 + 已完成 操作已完成 选项 组织名称 @@ -938,6 +978,7 @@ 权限授予失败 (使用 Shizuku) 已授予权限 (使用 root) 已授予权限 (使用 Shizuku) + 权限管理 允许应用访问其他应用的使用统计数据 已撤消授权 权限撤消失败 (使用 root) @@ -961,6 +1002,7 @@ 指针位置 切换 \"指针位置\" 显示状态失败\n可能缺少 root 权限 发布通知权限 + 为确保 AutoJs6 前台服务等能够正常运行, 脚本能够发布通知, AutoJs6 需要被授予 \"发布通知权限\". 预执行脚本 准备中... 预设对话框内容 @@ -975,6 +1017,9 @@ 项目位置 投影媒体权限 提示 + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s 放弃 推荐 录制完成 @@ -1043,6 +1088,7 @@ 保存到 调度引擎 启动延迟 + 屏幕捕获权限申请延迟 录制脚本 脚本运行 搜索 @@ -1062,6 +1108,7 @@ 创建快捷方式 服务端模式 服务 + 服务管理 用作工作路径 设置断点 设置 @@ -1078,6 +1125,10 @@ 大小 已导出 %d 个条目 排序 + 按最近更新排序 + 按名称排序 + 按安装包大小排序 + 来源 源代码路径 特殊权限 稳定模式 @@ -1170,36 +1221,4 @@ 修改安全设置 修改系统设置 后台弹出界面 - 未找到可用的 Paddle OCR 插件 - 已安装 - 未安装 - 全部 - 按名称排序 - 按最近更新排序 - 按安装包大小排序 - 缺少 \"%1$s\" 所需的插件. 请先安装插件, 然后重试. - \"%1$s\" 没有已启用的插件. 请先启用插件, 然后重试. - 未找到可用且已启用的 %1$s 插件变体 (%2$s). - 插件 APK 不包含变体 \"%1$s\" 所需的资源文件: %2$s. - 插件 APK 不包含所需的 native 库文件: %1$s. - 绑定 %1$s 插件服务失败. - 查询 %1$s 插件信息超时. - %1$s 插件返回的 info 为空. - %1$s 插件返回的 variant 无效: %2$s. - 未找到内置 Paddle OCR 资源, 请在打包时勾选并注入 Paddle OCR 后重试. - 最小化 - %1$s: %2$d%3$s - %1$s: %2$d %3$s - 屏幕捕获权限申请延迟 - 申请屏幕捕获权限时, 弹出的权限申请窗口消失时可能存在渐变动画, 此时如果立即调用 `images.captureScreen` 方法, 获取的屏幕截图中会出现权限申请的窗口内容而造成遮挡.\n\n当前设置选项值用于在截图权限申请后立即获取屏幕截图前增加一个延迟时间 (单位为毫秒), 可用于避免上述遮挡问题.\n\n当前设置选项仅适用于获取截图权限后的首次截图操作, 后续截图操作不再受此设置值影响. - 延迟时间 - 主页 - 开关状态改变失败 - 为确保 AutoJs6 前台服务等能够正常运行, 脚本能够发布通知, AutoJs6 需要被授予 \"发布通知权限\". - \"指针位置\" 是安卓开发者选项中的调试功能.\n开启后, 系统会在屏幕上显示触摸点的 [坐标/移动轨迹/数量/大小/移动速度/压力] 等信息, 便于相关脚本的 [编写/调试/校对] 等. - 发生错误 - 权限管理 - 服务管理 - 前台服务用于在后台更稳定地保持应用及脚本运行 - - + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 896efa75..79f48d29 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -120,6 +120,7 @@ #009624 #DCEDC8 #00C853 + @color/md_gray_300 @color/day diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f57cd567..8c0fe811 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -304,7 +304,8 @@ Config \"abi\" contains unavailable options Config \"lib\" contains invalid options Config \"lib\" contains unavailable options - File already exists.\nOverwrite? + Folder already exists. Overwrite? + File already exists. Overwrite? 1. Press and hold the application name (AutoJs6) on the home page to jump to the settings page\n2. Press and hold a certain settings option on the settings page to view detailed information Current theme color %1$s is configured by the color palette A Floating Action Button widget for displaying the manifest @@ -348,23 +349,27 @@ Night mode (also known as Dark theme) applies to both the Android system UI and apps running on the device, which improves visibility for users with low vision and those who are sensitive to bright light, and makes it easier for anyone to use a device in a low-light environment.\n\nFollow system: AutoJs6 has Night mode settings same as Android system\nAlways on: AutoJs6 keeps Night mode on (regardless of Android system settings)\nAlways off: AutoJs6 keeps Night mode off (regardless of Android system settings)\n\nNote: Follow system option is only for Android API Level 28 (Android 9) [P] and above. To enable Night mode in Android system:\n- Android API Level 29 (Android 10) [Q] and above: Settings -> Display -> Theme.\n- Android API Level 28 (Android 9) [P]: Developer options -> Night mode.\n\nThe following conditions must to met for applying a Night mode (Dark theme) to web-based content using a WebView component (like AutoJs6 documentation page):\n1. Android System WebView (or browsers like Google Chrome):\n- Android API Level 29 (Android 10) [Q] and above: version >= 76\n- Android API Level 28 (Android 9) [P]: version >= 105\n2. Web-based content in WebView component is adapted to Dark theme (by CSS or Android XML resources and so forth) The \"notification access\" (or \"notification reading\") permission allows AutoJs6 to read system notification content, so scripts can listen for notifications or retrieve notification text, etc. + \"Pointer location\" is a debugging feature in Android Developer options.\nWhen enabled, the system will display information about touch point(s) on the screen, such as [coordinates/movement trajectory/count/size/movement speed/pressure], which helps with [writing/debugging/verification] of related scripts. The \"post notifications\" permission allows AutoJs6 to publish notifications to the system, so scripts can post and manage custom notifications in the notification shade.\n\nNote: on Android 13+ devices, if this permission is not granted, some notifications may not show, and it may affect foreground service startup and stability. With project media access, security warning for screen recording will not prompt. The restart strategy only affects the restart button in the home page drawer.\n\nQuick restart: Quickly restarts the app. If the restart fails or unexpected situations occur, try switching to \"Scheduled restart\".\nScheduled restart: Sets up a short-timed task in advance. After the app stops, it will start again on schedule to achieve app restart. Switch ON (default): results of Java methods that are instances of Number/Boolean/Character are wrapped as Java objects and exposed to scripts (String excluded). typeof is \"object\", species is \"JavaObject\"; Java methods remain accessible, which helps retain precise Java type traits and overload resolution.\n\nSwitch OFF: the above types are no longer wrapped and are exposed directly as JavaScript primitives (number/boolean/one‑character string). typeof is the corresponding JavaScript type, aligning better with JavaScript semantics and ecosystem. You can still explicitly create a Java wrapper via new, e.g. new java.lang.Boolean(true).\n\nSee: http://issues.autojs6.com/435 If you have exotic root or abnormal state for root access, you can force set root to root or non-root. Binary type: non-editable, with the file extension \"auto\"\nJavaScript type: can be edited or copied directly, with the file extension \"js\" + When requesting screen capture permission, the permission request window may include a fade-out animation when it disappears. If `images.captureScreen` is called immediately, the captured screenshot may contain the permission request window content and be obstructed.\n\nThe current option value adds a delay (in milliseconds) before capturing the screen immediately after permission is granted, which can be used to avoid the obstruction issue described above.\n\nThis option only applies to the first screenshot after screen capture permission is granted; subsequent screenshots are not affected by this value. Server mode allows AutoJs6 to start a service on the current device and wait for external client connections for [ script transfer / log printing / remote control ].\n\nAutoJs6 server mode supports two connection methods:\n1. LAN\n2. Android Debug Bridge (ADB) Shizuku makes it possible to uses system API with ADB privileges Stable mode makes it more stable when getting layout bounds, but some results may be ignored.\nA11y service\'s restart required. Theme color is applied to widgets including but not limited to the following ones:\nStatus bar\nAppbar\nFile icon\nTask item icon\nFAB\nSettings category title\nSwitch button\n\nNote: As of AutoJs6 version 6.2.0, there has been no difference between primary color, primary dark color and accent color yet. - Controls the underlying mechanism for triggering scripts on a schedule.\n\nAlarmManager: With the “Allow setting alarms and reminders” permission granted, scheduled tasks can fire closer to the exact time.\nWorkManager: System-friendly; suitable for non-critical tasks that can tolerate some delay.\nJobScheduler: Legacy implementation kept for compatibility; higher chance of delays. - Use cases and differences:\n\n1. AlarmManager\nBest for time-sensitive tasks, e.g., [reminders/strictly scheduled scripts/...].\nOn Android 12+ with the “Allow setting alarms and reminders” permission, tasks can run more on time even when the screen is off or the device is idle.\nWithout it, the system may degrade exactness or delay execution.\n\n2. WorkManager\nBest for tasks that don’t require strict timing, e.g., [non-critical sync/cleanup/statistics/...].\nScheduling depends on [battery/network/charging/idle policies/...], so execution may be postponed when the screen is off or idle.\nWhile it can’t guarantee exact timing, it excels at [reliable completion/retries/chaining/unique work de-duplication].\n\n3. JobScheduler\nHistorical implementation for compatibility.\nOn newer Android versions, tasks may be delayed more noticeably.\nGenerally not recommended unless required for compatibility. + Controls the underlying mechanism for triggering scripts on a schedule.\n\nAlarmManager: With the \"Allow setting alarms and reminders\" permission granted, scheduled tasks can fire closer to the exact time.\nWorkManager: System-friendly; suitable for non-critical tasks that can tolerate some delay.\nJobScheduler: Legacy implementation kept for compatibility; higher chance of delays. + Use cases and differences:\n\n1. AlarmManager\nBest for time-sensitive tasks, e.g., [reminders/strictly scheduled scripts/...].\nOn Android 12+ with the \"Allow setting alarms and reminders\" permission, tasks can run more on time even when the screen is off or the device is idle.\nWithout it, the system may degrade exactness or delay execution.\n\n2. WorkManager\nBest for tasks that don’t require strict timing, e.g., [non-critical sync/cleanup/statistics/...].\nScheduling depends on [battery/network/charging/idle policies/...], so execution may be postponed when the screen is off or idle.\nWhile it can’t guarantee exact timing, it excels at [reliable completion/retries/chaining/unique work de-duplication].\n\n3. JobScheduler\nHistorical implementation for compatibility.\nOn newer Android versions, tasks may be delayed more noticeably.\nGenerally not recommended unless required for compatibility. Provides access to device usage history and statistics which results in currentPackage() a more accurate result View the release version history and key category statistics of AutoJs6 on GitHub. Secure system settings, containing system preferences that applications can read but are not allowed to write.\nThese are for preferences that the user must explicitly modify through the UI of a system app.\nWith secure system settings permission, normal applications can directly modify the secure settings (such as accessibility service). The \"write system settings\" permission allows AutoJs6 to modify some system settings, so scripts can change system parameters such as [ screen brightness / auto-rotate / screen timeout ]. Abandon + Abort + Abort Advanced Amend @string/text_back @@ -382,10 +387,11 @@ Details File info History + Homepage Ignore - Interrupt Join group Manager + Minimize More Palette Quit @@ -448,6 +454,7 @@ Method %s has been abandoned and should not be used The \"%1$s\" operation cannot be completed because the parameter contains negative coordinate values (%2$d, %3$d) An activity is required, which could be provided by running in \"ui\" execution mode + An error occurred An operation is not implemented App is not installed App is not installed: \"%s\" @@ -486,13 +493,15 @@ Excessive height: template [%1$d] > region [%2$d] Excessive width: template [%1$d] > region [%2$d] Failed to apply current color history - Failed to call method "%s" - + Failed to bind %1$s plugin service. + Failed to call method \"%s\" + + Failed to change the toggle state Failed to convert value %s into a Drawable Failed to open the settings page Failed to grant Shizuku access - Failed to instantiate "%s" - + Failed to instantiate \"%s\" + Failed to launcher manager Failed to launch system settings Failed to load plugins.\nReason: %1$s. @@ -531,6 +540,7 @@ AutoJs6 may not have root access to run \"auto\" file %s() called with null argument: %s Method only accepts a number of arguments in the range [%1$d\.\.%2$d] + Missing required plugin for \"%1$s\". Please install the plugin and try again. The \"%s\" module does not work due to the lack of necessary library files Accessibility service is disabled and the script has stopped Accessibility service is not activated @@ -541,8 +551,12 @@ No applications available for playing this file No applications available for sending this file No applications available for viewing this file + No available enabled %1$s plugin variants found (%2$s). No available URL provided for current plugin No \"display over other apps\" permission + No embedded Paddle OCR assets found. Please re-package with Paddle OCR enabled. + No enabled plugin for \"%1$s\". Please enable a plugin and try again. + No Paddle OCR plugins available No permission to access Shizuku No \"post notifications\" permission No \"read phone state\" permission @@ -555,6 +569,10 @@ Failed to parse GitHub release assets Failed to parse version information Invalid pattern syntax + Plugin APK does not contain required assets for variant=\"%1$s\": %2$s. + Plugin APK does not contain required native libraries: %1$s. + %1$s plugin returned empty info. + %1$s plugin returned invalid variant: %2$s. Port number over 65535 Project main script file \"%1$s\" does not exist Cannot put value %s into JSON @@ -573,6 +591,7 @@ Specified AutoJs6 version number must be greater than 461 The transformer for required property \"%1$s\" cannot return nullish Thread is not alive + Timeout while querying %1$s plugin info. Unable to use Shizuku service Unacceptable character Unknown error @@ -661,6 +680,7 @@ Enable accessibility service with root access automatically when needed Enable accessibility service with secure settings automatically when needed Increase code flexibility and enable richer functionality by extending JavaScript built-in objects + The foreground service helps keep the app and scripts running more reliably in the background Prevent automation actions from scripts when AutoJs6 is in the foreground Run script directly without showing main activity Allows AutoJs6 to create and post notifications @@ -670,13 +690,15 @@ Java primitive types will be wrapped as Java objects in scripts More stable layout analysis but worse code compatibility (a11y service restarting needed) Add shortcuts to launcher - Start or stop recording controlled by "Volume Down" key when floating button is showing + Start or stop recording controlled by \"Volume Down\" key when floating button is showing Press \"Volume Up\" key to stop all running scripts View release version history and statistics + Internal Storage Accessibility service Required by the script automatic operation (click, long press, slide, etc.). Accessibility service enabled but not running (Re-enable or reboot the device) Accessibility service may be needed + Aborting... About About all files access About app and developer @@ -699,12 +721,13 @@ alias Alias cannot be empty Alias Password + All All files access \"All files access\" is needed to access script files on the phone All histories All histories have been cleared All items have been cleared - Granting the “Allow setting alarms and reminders” permission is recommended to help tasks run as punctually as possible even when the screen is off or the device is idle + Granting the \"Allow setting alarms and reminders\" permission is recommended to help tasks run as punctually as possible even when the screen is off or the device is idle Copied to clipboard Already copied to clipboard (only latest %d items) Created @@ -751,7 +774,7 @@ App version code App version name Appearance - At least one field from \"Full Name, Organization Name, Organizational Unit, Country Code, State or Province, City or Locality, Street\" must be filled + At least one field from [Full Name, Organization Name, Organizational Unit, Country Code, State or Province, City or Locality, Street] must be filled Attribute Auto check for updates Check for updates automatically and show a snackbar on homepage @@ -835,7 +858,11 @@ Copy all files to new directory Copy cmd Copy debugging log + Copy file + Copy folder Copy line + Source path is the same as destination path. Continue copying?\n\nNew name: \"%1$s\". + Copy to Copy to clipboard Copy value Country Code (XX) @@ -858,10 +885,14 @@ Default Default Keystore Default prefix + Delay time Delete Delete All + Delete file + Delete folder Delete line Description + Destination Details Developer details is under development Developer options @@ -971,6 +1002,7 @@ Prev Full Name Floating button + Folder Force stop Foreground service Formatting completed @@ -1012,6 +1044,7 @@ Install from \"URL\" Install plugin from \"URL\" Installable + Installed Integrity verification failed Invalid character is removed Invalid package name @@ -1067,7 +1100,12 @@ \"Mobile QQ\" not installed More Details + Move + Source path is the same as destination path, move aborted. Move all files to new directory + Move file + Move folder + Move to Multiple options Name Need to enable accessibility service @@ -1095,6 +1133,7 @@ No root access No scripts to stop running Not granted + Not installed Not showing main activity Notification Notification access @@ -1109,6 +1148,8 @@ Open by other apps Open main activity Open with + Aborted + Completed Operation is completed Options Organization Name @@ -1197,6 +1238,7 @@ Failed to grant permission (with Shizuku) Permission granted (with root) Permission granted (with Shizuku) + Permission management Allow the app to access usage statistics of other apps Permission revoked Failed to revoke permission (with root) @@ -1220,6 +1262,7 @@ Pointer location Toggle \"pointer location\" failed.\nRoot access is required. Post notifications + To ensure that AutoJs6 foreground services, etc. can work properly and that scripts can post notifications, AutoJs6 must be granted the \"post notifications\" permission. Pre-execute script Preparing... Preset dialog content @@ -1234,6 +1277,9 @@ Project location Project media access Prompt + %1$s: %2$s + %1$s: %2$d %3$s + %1$s: %2$d%3$s Quit Recommended Recording finished @@ -1302,6 +1348,7 @@ Save to Backend Start delay + Screen capture permission request delay Script recording Script running Search @@ -1321,6 +1368,7 @@ Create shortcut Server mode Service + Service management Set as working dir Set a breakpoint Settings @@ -1337,6 +1385,10 @@ Size %d items exported Sort + Sort by last update time + Sort by name + Sort by package size + Source Source code path Special permissions Stable mode @@ -1394,7 +1446,7 @@ Usage stats access Use Android 7.0 shortcut Use default icon - Use "Volume Down" key to control recording + Use \"Volume Down\" key to control recording Use \"Volume Up\" key to control the script running Username Username cannot be empty @@ -1429,36 +1481,4 @@ Write security settings Write system settings Display pop-up windows while running in the background - No Paddle OCR plugins available - Installed - Not installed - All - Sort by name - Sort by last update time - Sort by package size - Missing required plugin for \"%1$s\". Please install the plugin and try again. - No enabled plugin for \"%1$s\". Please enable a plugin and try again. - No available enabled %1$s plugin variants found (%2$s). - Plugin APK does not contain required assets for variant=\"%1$s\": %2$s. - Plugin APK does not contain required native libraries: %1$s. - Failed to bind %1$s plugin service. - Timeout while querying %1$s plugin info. - %1$s plugin returned empty info. - %1$s plugin returned invalid variant: %2$s. - No embedded Paddle OCR assets found. Please re-package with Paddle OCR enabled. - Minimize - %1$s: %2$d%3$s - %1$s: %2$d %3$s - Screen capture permission request delay - When requesting screen capture permission, the permission request window may include a fade-out animation when it disappears. If `images.captureScreen` is called immediately, the captured screenshot may contain the permission request window content and be obstructed.\n\nThe current option value adds a delay (in milliseconds) before capturing the screen immediately after permission is granted, which can be used to avoid the obstruction issue described above.\n\nThis option only applies to the first screenshot after screen capture permission is granted; subsequent screenshots are not affected by this value. - Delay time - Homepage - Failed to change the toggle state - To ensure that AutoJs6 foreground services, etc. can work properly and that scripts can post notifications, AutoJs6 must be granted the \"post notifications\" permission. - \"Pointer location\" is a debugging feature in Android Developer options.\nWhen enabled, the system will display information about touch point(s) on the screen, such as [coordinates/movement trajectory/count/size/movement speed/pressure], which helps with [writing/debugging/verification] of related scripts. - An error occurred - Permission management - Service management - The foreground service helps keep the app and scripts running more reliably in the background - - + \ No newline at end of file diff --git a/version.properties b/version.properties index 0cf870c4..cf6452f1 100644 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ -#Sat Jan 31 18:47:47 CST 2026 -BUILD_TIME=1769856467115 +#Mon Feb 02 21:31:36 CST 2026 +BUILD_TIME=1770039096757 COMPILE_SDK_VERSION=36 IMAGE_QUANT_CMAKE_VERSION=3.22.1 IMAGE_QUANT_NDK_VERSION=26.1.10909125 @@ -27,6 +27,6 @@ RAPID_OCR_OPENCV_MOBILE_LABEL_VERSION=13 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3 TARGET_SDK_VERSION=36 TARGET_SDK_VERSION_INRT=29 -VERSION_BUILD=3679 +VERSION_BUILD=3687 VERSION_NAME=6.7.0 Alpha19 VSCODE_EXT_REQUIRED_VERSION=1.0.13