From 068f8473e7fe955fb33f826e2d660cfbc89047b3 Mon Sep 17 00:00:00 2001 From: SuperMonster003 Date: Tue, 20 Jan 2026 17:20:58 +0800 Subject: [PATCH] =?UTF-8?q?6.7.0=20-=20Alpha17=20-=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=B5=AE=E5=8A=A8=E6=8C=89=E9=92=AE=20"=E8=BF=90=E8=A1=8C?= =?UTF-8?q?=E8=84=9A=E6=9C=AC"=20=E5=AF=B9=E8=AF=9D=E6=A1=86=E5=90=8E?= =?UTF-8?q?=E5=8F=B0=E6=93=8D=E4=BD=9C=E5=B4=A9=E6=BA=83=E5=B9=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=8A=B6=E6=80=81=E6=81=A2=E5=A4=8D;=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E5=90=8E=E5=8F=B0=E5=90=AF=E5=8A=A8=20Activity=20?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changelog/lang_zh-Hans.json | 4 +- .../ezy/assist/compat/SettingsCompat.java | 6 +- .../java/org/autojs/autojs/app/DialogUtils.kt | 190 +++++++++++++++--- .../core/accessibility/AccessibilityTool.kt | 3 +- .../core/activity/StartForResultActivity.kt | 5 +- .../autojs/autojs/core/console/ConsoleImpl.kt | 5 +- .../autojs/core/permission/Permissions.java | 7 +- .../plugin/center/PluginCenterActivity.kt | 4 +- .../core/plugin/center/PluginCenterItem.kt | 4 +- .../plugin/center/PluginInfoDialogManager.kt | 7 +- .../core/plugin/center/PluginInstaller.kt | 7 +- .../core/record/GlobalActionRecorder.java | 3 +- .../external/tasker/FireSettingReceiver.java | 10 +- .../inrt/launch/AssetsProjectLauncher.kt | 8 +- .../permission/AllFilesAccessPermission.kt | 12 +- .../IgnoreBatteryOptimizationsPermission.kt | 18 +- .../WriteSystemSettingsPermission.kt | 9 +- .../org/autojs/autojs/runtime/api/AppUtils.kt | 7 +- .../org/autojs/autojs/runtime/api/Events.java | 6 +- .../autojs/autojs/runtime/api/Permissions.kt | 24 ++- .../autojs/runtime/api/WrappedShizuku.kt | 3 +- .../autojs/runtime/api/augment/app/App.kt | 6 +- .../autojs/service/NotificationService.kt | 3 +- .../theme/app/ColorInfoDialogManager.kt | 3 +- .../theme/app/ColorSelectBaseActivity.kt | 6 +- .../timing/ExactAlarmPermissionHelper.kt | 6 +- .../org/autojs/autojs/tool/CrashHandler.kt | 8 +- .../autojs/ui/common/ScriptLoopDialog.java | 2 +- .../autojs/ui/common/ScriptOperations.java | 19 +- .../org/autojs/autojs/ui/doc/ManualDialog.kt | 3 +- .../org/autojs/autojs/ui/edit/EditActivity.kt | 49 +++-- .../util/FloatingWindowPermissionUtil.java | 6 +- .../autojs/ui/error/CrashReportActivity.kt | 5 +- .../autojs/ui/error/ErrorDialogActivity.java | 7 +- .../ui/explorer/ExplorerProjectToolbar.java | 6 +- .../autojs/autojs/ui/explorer/ExplorerView.kt | 45 ++++- .../autojs/ui/floating/CircularMenu.java | 127 ++++++++---- .../ui/floating/CodeGenerateDialog.java | 4 +- .../autojs/ui/floating/LayoutFloatyWindow.kt | 6 +- .../ui/keystore/ManageKeyStoreActivity.kt | 3 +- .../org/autojs/autojs/ui/log/LogActivity.kt | 5 +- .../org/autojs/autojs/ui/main/MainActivity.kt | 3 +- .../autojs/ui/main/drawer/DrawerFragment.kt | 31 ++- .../ui/main/scripts/ApkInfoDialogManager.kt | 26 ++- .../main/scripts/DisplayManifestActivity.kt | 3 +- .../main/scripts/DisplayMediaInfoActivity.kt | 8 +- .../scripts/EditableFileInfoDialogManager.kt | 5 +- .../ui/main/scripts/ExplorerFragment.kt | 18 +- .../ui/main/scripts/MediaInfoDialogManager.kt | 27 ++- .../ui/main/task/TaskListRecyclerView.java | 3 +- .../autojs/ui/project/BuildActivity.java | 2 +- .../autojs/ui/settings/AboutActivity.kt | 9 +- .../AboutAppAndDeveloperPreference.kt | 22 +- .../ui/settings/AppLanguagePreference.kt | 5 +- .../DisplayVersionHistoriesActivity.kt | 6 +- .../autojs/ui/settings/PreferencesActivity.kt | 4 +- .../ScheduledRestartSettingsDialogBuilder.kt | 4 +- .../autojs/ui/widget/CommonMarkdownView.kt | 5 +- .../org/autojs/autojs/ui/widget/EWebView.java | 18 +- .../org/autojs/autojs/util/IntentUtils.kt | 22 ++ .../autojs/autojs/util/NotificationUtils.kt | 3 +- app/src/main/res/values-ar/strings.xml | 1 + app/src/main/res/values-en/strings.xml | 1 + app/src/main/res/values-es/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-ja/strings.xml | 1 + app/src/main/res/values-ko/strings.xml | 1 + app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-zh-rHK/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + version.properties | 8 +- 73 files changed, 594 insertions(+), 310 deletions(-) diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index 99a7b1bb..6b59f115 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -88,7 +88,7 @@ "版本历史页面部分系统因字体差别导致统计数据显示不完整的问题", "部分设备无法正常初始化 MLKit Google OCR 的问题 (试修) _[`issue #8`](http://issues.autojs6.com/8#issuecomment-3117061768)_", "部分设备无法正常触发文件管理器功能按钮点击事件的问题 (试修) _[`issue #465`](http://issues.autojs6.com/465)_", - "ErrorDialogActivity 可能无法正常启动或短时间自动消失的问题 _[`issue #471`](http://issues.autojs6.com/471)_ _[`issue #414`](http://issues.autojs6.com/414)_ _[`issue #340`](http://issues.autojs6.com/340#issuecomment-2973485826)_", + "ErrorDialogActivity 可能无法正常启动或短时间自动消失的问题 _[`issue #479`](http://issues.autojs6.com/479)_ _[`issue #471`](http://issues.autojs6.com/471)_ _[`issue #414`](http://issues.autojs6.com/414)_ _[`issue #340`](http://issues.autojs6.com/340#issuecomment-2973485826)_", "Canvas 构造函数可接受的参数类型错误 _[`issue #402`](http://issues.autojs6.com/402)_", "崩溃报告页面复制详细信息功能失效的问题", "文件管理器删除项目文件夹后 UI 未能自动刷新的问题", @@ -129,6 +129,8 @@ "客户端模式连接时支持特殊用途 IPv4 地址 (回环/广播/多播/保留/...) 检测提示", "客户端模式连接时支持连接状态显示及管理 (修正地址/中止连接)", "服务端模式连接时支持显示已建立连接的客户端数量", + "浮动按钮增强后台启动 Activity 的安全性以避免应用崩溃", + "浮动按钮 \"运行脚本\" 对话框支持最小化及状态恢复并尽最大努力保持窗口常驻或自动恢复", "使用 LiveData 及 SharedFlow 替代已弃用的 LocalBroadcastManager", "Gradle 构建脚本提升 7z 格式文件的解压效率", "Gradle 构建脚本支持获取详细的 Android Studio IDE 版本 (如 \"2025.1.4.7\")", diff --git a/app/src/main/java/ezy/assist/compat/SettingsCompat.java b/app/src/main/java/ezy/assist/compat/SettingsCompat.java index 8fe2d3be..1c6f1e12 100644 --- a/app/src/main/java/ezy/assist/compat/SettingsCompat.java +++ b/app/src/main/java/ezy/assist/compat/SettingsCompat.java @@ -24,6 +24,7 @@ import android.net.Uri; import android.os.Binder; import android.provider.Settings; import android.util.Log; +import org.autojs.autojs.util.IntentUtils; import org.autojs.autojs.util.RomUtils; import java.lang.reflect.Method; @@ -72,7 +73,7 @@ public class SettingsCompat { public static void manageWriteSettings(Context context) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); - context.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + IntentUtils.startSafely(intent, context); } private static boolean checkOp(Context context, int op) { @@ -88,8 +89,7 @@ public class SettingsCompat { private static boolean startSafely(Context context, Intent intent) { if (context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size() > 0) { - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); + IntentUtils.startSafely(intent, context); return true; } else { Log.e(TAG, "Intent is not available! " + intent); 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 7e93d1e7..af92f81a 100644 --- a/app/src/main/java/org/autojs/autojs/app/DialogUtils.kt +++ b/app/src/main/java/org/autojs/autojs/app/DialogUtils.kt @@ -1,3 +1,5 @@ +@file:Suppress("unused") + package org.autojs.autojs.app import android.app.Activity @@ -6,7 +8,9 @@ import android.content.ContextWrapper import android.content.DialogInterface import android.os.Build import android.os.Looper +import android.provider.Settings import android.text.util.Linkify +import android.util.Log import android.view.Gravity import android.view.KeyEvent import android.view.View @@ -15,6 +19,7 @@ import android.widget.CheckBox import androidx.preference.PreferenceViewHolder import com.afollestad.materialdialogs.DialogAction import com.afollestad.materialdialogs.MaterialDialog +import org.autojs.autojs.annotation.ReservedForCompatibility import org.autojs.autojs.theme.preference.LongClickablePreferenceLike import org.autojs.autojs.ui.explorer.ExplorerView import org.autojs.autojs.util.ViewUtils.showSnack @@ -22,42 +27,173 @@ import org.autojs.autojs6.R /** * Created by Stardust on Aug 4, 2017. - * Modified by SuperMonster003 as of Sep 10, 2022. * 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. */ object DialogUtils { + private const val TAG = "DialogUtils" + @JvmStatic - fun showDialog(dialog: T): T { - val context = dialog.context - if (!isActivityContext(context)) { - val window = dialog.window - val type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY + fun MaterialDialog.Builder.showAdaptive() = build().showAdaptive() + + @JvmStatic + fun MaterialDialog.showAdaptive() = showDialog(this) + + /** + * Show this [MaterialDialog] in a context-safe way. + * + * Behavior: + * 1) Always performs window operations and `show()` on the main thread. + * 2) If the dialog uses an [Activity] context, it is shown normally. + * 3) Otherwise, it tries to show as an overlay window: + * - `TYPE_APPLICATION_OVERLAY` on Android O+. + * - `TYPE_PHONE` on pre-O devices. + * Overlay requires "Draw over other apps" permission (SYSTEM_ALERT_WINDOW). + * If permission is missing, the dialog will NOT be shown and no exception will be thrown. + * 4) Avoids overriding `OnShowListener` to prevent breaking caller/library logic. + * + * zh-CN: 以 "上下文安全" 的方式显示 [MaterialDialog]. + * + * 行为说明: + * 1) 所有 Window 参数操作和 `show()` 都保证在主线程执行. + * 2) 若对话框基于 [Activity] Context, 则按常规方式显示. + * 3) 否则尝试以 overlay 窗口显示: + * - Android O+ 使用 `TYPE_APPLICATION_OVERLAY`. + * - Android O 以下使用 `TYPE_PHONE`. + * overlay 依赖 "在其他应用上层显示" (SYSTEM_ALERT_WINDOW) 权限. + * 若检测到权限缺失, 将直接放弃显示且不会抛异常. + * 4) 不覆盖 `OnShowListener`, 避免破坏调用方或库内部逻辑. + * + * @param dialog The dialog instance to show. + * zh-CN: 需要显示的对话框实例. + * @param focusable Only affects overlay dialogs. If false, `FLAG_NOT_FOCUSABLE` is added, + * which makes the dialog less likely to be blocked when app is in background, + * but also prevents it from receiving some key/IME inputs. + * zh-CN: 仅影响 overlay 对话框. 为 false 时会添加 `FLAG_NOT_FOCUSABLE`, + * 更可能在后台可见, 但会影响按键/输入法等焦点相关能力. + * + * @return The same dialog instance. + * zh-CN: 返回同一个对话框实例. + */ + @JvmStatic + @JvmOverloads + @ReservedForCompatibility + fun showDialog(dialog: T, focusable: Boolean = true): T { + runOnMain { + // Prevent duplicated show. + // zh-CN: 防止重复 show(). + if (dialog.isShowing) return@runOnMain + + val context = dialog.context + + // Activity lifecycle guard. + // zh-CN: Activity 生命周期保护. + unwrapActivity(context)?.let { act -> + if (act.isFinishing || act.isDestroyed) { + Log.w(TAG, "Skip showing dialog: Activity is finishing/destroyed.") + return@runOnMain + } + } + + val needsOverlay = !isActivityContext(context) + + if (needsOverlay) { + // Permission check. + // zh-CN: 检查 overlay 权限. + if (!Settings.canDrawOverlays(context)) { + Log.w(TAG, "Skip showing overlay dialog: missing SYSTEM_ALERT_WINDOW permission.") + return@runOnMain + } + + val type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY + } else { + @Suppress("DEPRECATION") + WindowManager.LayoutParams.TYPE_PHONE + } + + fun applyOverlayWindowParams() { + // Ensure window exists; `create()` usually creates the underlying window for Dialog. + // zh-CN: 确保 window 存在; `create()` 通常会创建底层 window. + if (dialog.window == null) { + try { + dialog.create() + } catch (t: Throwable) { + Log.w(TAG, "dialog.create() failed (ignored).", t) + } + } + + dialog.window?.let { w -> + try { + @Suppress("DEPRECATION") + w.setType(type) + } catch (t: Throwable) { + // Some ROMs may throw here; ignore and continue. + // zh-CN: 某些 ROM 可能在此抛异常; 忽略并继续. + Log.w(TAG, "Failed to set window type (ignored).", t) + } + + if (focusable) { + // Keep default behavior for key/input handling. + // zh-CN: 保持默认行为以处理按键/输入. + w.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) + } else { + // Non-focusable overlay dialogs are more likely to show while app is in background. + // zh-CN: 不可聚焦的 overlay 对话框更可能在应用后台时正常显示. + w.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) + } + } + } + + // Apply before show. + // zh-CN: show() 前先尝试设置. + applyOverlayWindowParams() + + try { + dialog.show() + } catch (t: Throwable) { + // BadTokenException / SecurityException etc. + // zh-CN: 可能出现 BadTokenException / SecurityException 等. + Log.w(TAG, "Failed to show overlay dialog.", t) + return@runOnMain + } + + // Re-apply after show (some dialog libs may reset attributes during show). + // zh-CN: show() 后再补一次 (库内部可能在 show 过程中重置参数). + applyOverlayWindowParams() } else { - @Suppress("DEPRECATION") - WindowManager.LayoutParams.TYPE_PHONE - } - - // Try setting window type before show(). - // zh-CN: 尝试在 show() 之前设置窗口类型. - window?.setType(type) - - // Ensure window type is applied when window becomes available. - // zh-CN: 当 window 可用时确保窗口类型已正确应用. - dialog.setOnShowListener { - window?.setType(type) + // Normal Activity dialog. + // zh-CN: Activity Context 正常对话框. + try { + dialog.show() + } catch (t: Throwable) { + Log.w(TAG, "Failed to show dialog.", t) + } } } - if (Looper.getMainLooper() == Looper.myLooper()) { - dialog.show() - } else { - GlobalAppContext.post { dialog.show() } - } return dialog } + private fun unwrapActivity(context: Context?): Activity? { + return when (context) { + is Activity -> context + is ContextWrapper -> unwrapActivity(context.baseContext) + else -> null + } + } + + 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 @@ -65,7 +201,7 @@ object DialogUtils { @JvmStatic fun isActivityContext(context: Context?): Boolean { - return context is Activity || context is ContextWrapper && isActivityContext(context.baseContext) + return context is Activity || (context is ContextWrapper && isActivityContext(context.baseContext)) } fun toggleContentViewByItems(dialog: MaterialDialog) { @@ -127,7 +263,7 @@ object DialogUtils { text = text } } - .let { showDialog(it) } + .showAdaptive() } } } @@ -143,7 +279,7 @@ object DialogUtils { text = text } } - .let { showDialog(it) } + .showAdaptive() true } ?: false } diff --git a/app/src/main/java/org/autojs/autojs/core/accessibility/AccessibilityTool.kt b/app/src/main/java/org/autojs/autojs/core/accessibility/AccessibilityTool.kt index f96078a9..122b23e6 100644 --- a/app/src/main/java/org/autojs/autojs/core/accessibility/AccessibilityTool.kt +++ b/app/src/main/java/org/autojs/autojs/core/accessibility/AccessibilityTool.kt @@ -15,6 +15,7 @@ import org.autojs.autojs.runtime.api.ProcessShell import org.autojs.autojs.runtime.exception.ScriptException import org.autojs.autojs.runtime.exception.ScriptInterruptedException import org.autojs.autojs.service.AccessibilityInteractionClient +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.RootUtils import org.autojs.autojs.util.SettingsUtils import org.autojs.autojs.util.ViewUtils @@ -47,7 +48,7 @@ class AccessibilityTool(private val context: Context? = null) { ViewUtils.showToast(mContext, it, true) } try { - mApplicationContext.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) + Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).startSafely(mApplicationContext) } catch (_: ActivityNotFoundException) { ViewUtils.showToast(mContext, R.string.go_to_accessibility_settings, true) } diff --git a/app/src/main/java/org/autojs/autojs/core/activity/StartForResultActivity.kt b/app/src/main/java/org/autojs/autojs/core/activity/StartForResultActivity.kt index c4ad26c8..4cd0ae34 100644 --- a/app/src/main/java/org/autojs/autojs/core/activity/StartForResultActivity.kt +++ b/app/src/main/java/org/autojs/autojs/core/activity/StartForResultActivity.kt @@ -6,6 +6,7 @@ import android.content.Intent import android.os.Bundle import android.view.View import org.autojs.autojs.tool.IntentExtras +import org.autojs.autojs.util.IntentUtils.startSafely /** * Created by SuperMonster003 on Dec 14, 2023. @@ -62,10 +63,8 @@ class StartForResultActivity : Activity() { @JvmStatic fun start(context: Context, callback: Callback?) { Intent(context, StartForResultActivity::class.java).also { intent -> - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.putExtra(IntentExtras.EXTRA_ID, IntentExtras().apply { map["callback"] = callback }.id) - context.startActivity(intent) - } + }.startSafely(context) } } diff --git a/app/src/main/java/org/autojs/autojs/core/console/ConsoleImpl.kt b/app/src/main/java/org/autojs/autojs/core/console/ConsoleImpl.kt index 9914c8b3..b0cc7b41 100644 --- a/app/src/main/java/org/autojs/autojs/core/console/ConsoleImpl.kt +++ b/app/src/main/java/org/autojs/autojs/core/console/ConsoleImpl.kt @@ -39,6 +39,7 @@ import org.autojs.autojs.ui.enhancedfloaty.ResizableExpandableFloatyWindow import org.autojs.autojs.ui.enhancedfloaty.gesture.DragGesture import org.autojs.autojs.util.ClipboardUtils import org.autojs.autojs.util.ColorUtils +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.StringUtils.key import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.R @@ -286,9 +287,7 @@ open class ConsoleImpl(val uiHandler: UiHandler) : AbstractConsole() { putExtra(Intent.EXTRA_TEXT, message) type = Mime.TEXT_PLAIN } - applicationContext.startActivity(Intent.createChooser(sendIntent, null).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }) + Intent.createChooser(sendIntent, null).startSafely(applicationContext) } private fun cutOutEntries(maxLength: Int): MutableList { diff --git a/app/src/main/java/org/autojs/autojs/core/permission/Permissions.java b/app/src/main/java/org/autojs/autojs/core/permission/Permissions.java index 6a605b5a..42282f95 100644 --- a/app/src/main/java/org/autojs/autojs/core/permission/Permissions.java +++ b/app/src/main/java/org/autojs/autojs/core/permission/Permissions.java @@ -2,6 +2,7 @@ package org.autojs.autojs.core.permission; import android.content.Context; import android.content.Intent; +import org.autojs.autojs.util.IntentUtils; import java.util.ArrayList; @@ -37,8 +38,8 @@ public class Permissions { } public static void requestPermissions(Context context, String[] permissions) { - context.startActivity(new Intent(context, PermissionRequestActivity.class) - .putExtra(PermissionRequestActivity.EXTRA_PERMISSIONS, permissions) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + Intent intent = new Intent(context, PermissionRequestActivity.class) + .putExtra(PermissionRequestActivity.EXTRA_PERMISSIONS, permissions); + IntentUtils.startSafely(intent, context); } } diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterActivity.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterActivity.kt index d3a18120..1256eece 100644 --- a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterActivity.kt +++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterActivity.kt @@ -13,6 +13,7 @@ import com.afollestad.materialdialogs.MaterialDialog import kotlinx.coroutines.launch import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.widget.SearchViewItem +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs.util.ViewUtils.onceGlobalLayout import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByThemeColorLuminance @@ -187,8 +188,7 @@ class PluginCenterActivity : BaseActivity() { fun startActivity(context: Context) { Intent(context, PluginCenterActivity::class.java) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { context.startActivity(it) } + .startSafely(context) } } diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItem.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItem.kt index 5c2cda4d..a59b9e3f 100644 --- a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItem.kt +++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItem.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.graphics.drawable.Drawable import androidx.core.net.toUri import com.afollestad.materialdialogs.MaterialDialog +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs6.R import org.joda.time.DateTime import org.joda.time.format.DateTimeFormat @@ -84,7 +85,8 @@ data class PluginCenterItem( } fun uninstall(context: Context) { - context.startActivity(Intent(Intent.ACTION_DELETE, "package:$packageName".toUri())) + Intent(Intent.ACTION_DELETE, "package:$packageName".toUri()) + .startSafely(context) } fun uninstallWithPrompt(context: Context, dialog: MaterialDialog? = null) { diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInfoDialogManager.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInfoDialogManager.kt index 132d1372..07a9a6ac 100644 --- a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInfoDialogManager.kt +++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginInfoDialogManager.kt @@ -17,6 +17,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.autojs.autojs.app.DialogUtils.showAdaptive import org.autojs.autojs.extension.MaterialDialogExtensions.makeSettingsLaunchable import org.autojs.autojs.extension.MaterialDialogExtensions.makeTextCopyable import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableTextIfAbsent @@ -119,7 +120,7 @@ object PluginInfoDialogManager { .onNegative { d, _ -> d.dismiss() } .autoDismiss(false) .apply(builderApplier) - .show() + .showAdaptive() .apply { makeTextCopyable { titleView } } // Hold the current dialog and package name for refreshing on onResume. @@ -215,7 +216,7 @@ object PluginInfoDialogManager { ViewUtils.showToast(context, R.string.text_done) parentDialog.dismiss() } - .show() + .showAdaptive() } MaterialDialog.Builder(context) @@ -244,7 +245,7 @@ object PluginInfoDialogManager { .title(R.string.text_prompt) .content(R.string.error_no_available_url_provided_for_current_plugin) .positiveText(R.string.dialog_button_dismiss) - .show() + .showAdaptive() parentDialog ?.getActionButton(DialogAction.POSITIVE) ?.setTextColor(context.getColor(R.color.dialog_button_unavailable)) 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 70239c77..ca165edc 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 @@ -19,6 +19,7 @@ import org.autojs.autojs.util.FileUtils import org.autojs.autojs.util.FileUtils.toCacheFile import org.autojs.autojs.util.IntentUtils import org.autojs.autojs.util.IntentUtils.SnackExceptionHolder +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.R import java.io.EOFException @@ -78,12 +79,10 @@ object PluginInstaller { } fun installFromFileUri(context: Context, uri: Uri) { - val intent = Intent(Intent.ACTION_VIEW).apply { + Intent(Intent.ACTION_VIEW).apply { setDataAndType(uri, Mime.APPLICATION_VND_ANDROID_PACKAGE_ARCHIVE) addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - } - context.startActivity(intent) + }.startSafely(context) } suspend fun installFromUrlWithPrompt(context: Context, url: String, expectedSha256: String? = null) { diff --git a/app/src/main/java/org/autojs/autojs/core/record/GlobalActionRecorder.java b/app/src/main/java/org/autojs/autojs/core/record/GlobalActionRecorder.java index 83ec8863..f95d47bf 100644 --- a/app/src/main/java/org/autojs/autojs/core/record/GlobalActionRecorder.java +++ b/app/src/main/java/org/autojs/autojs/core/record/GlobalActionRecorder.java @@ -18,7 +18,6 @@ import org.autojs.autojs6.R; import java.util.concurrent.CopyOnWriteArrayList; -import static org.autojs.autojs.util.RhinoUtils.isBackgroundThread; import static org.autojs.autojs.util.RhinoUtils.isMainThread; /** @@ -185,7 +184,7 @@ public class GlobalActionRecorder implements Recorder.OnStateChangedListener { .positiveColorRes(R.color.dialog_button_attraction) .canceledOnTouchOutside(false); MaterialDialogExtensions.choiceWidgetThemeColor(builder); - DialogUtils.showDialog(builder.build()); + DialogUtils.showAdaptive(builder.build()); } private String getString(int res) { diff --git a/app/src/main/java/org/autojs/autojs/external/tasker/FireSettingReceiver.java b/app/src/main/java/org/autojs/autojs/external/tasker/FireSettingReceiver.java index 57b6e821..cd9d71a4 100644 --- a/app/src/main/java/org/autojs/autojs/external/tasker/FireSettingReceiver.java +++ b/app/src/main/java/org/autojs/autojs/external/tasker/FireSettingReceiver.java @@ -2,13 +2,11 @@ package org.autojs.autojs.external.tasker; import android.content.Context; import android.content.Intent; - import androidx.annotation.NonNull; - import com.twofortyfouram.locale.sdk.client.receiver.AbstractPluginSettingReceiver; - import org.autojs.autojs.external.ScriptIntents; import org.autojs.autojs.external.open.RunIntentActivity; +import org.autojs.autojs.util.IntentUtils; import org.json.JSONObject; /** @@ -28,9 +26,9 @@ public class FireSettingReceiver extends AbstractPluginSettingReceiver { @Override protected void firePluginSetting(@NonNull Context context, @NonNull JSONObject jsonObject) { - context.startActivity(new Intent(context, RunIntentActivity.class) - .putExtra(ScriptIntents.EXTRA_KEY_JSON, jsonObject.toString()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + Intent intent = new Intent(context, RunIntentActivity.class) + .putExtra(ScriptIntents.EXTRA_KEY_JSON, jsonObject.toString()); + IntentUtils.startSafely(intent, context); } } diff --git a/app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt b/app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt index 674ead30..82715920 100644 --- a/app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt +++ b/app/src/main/java/org/autojs/autojs/inrt/launch/AssetsProjectLauncher.kt @@ -17,6 +17,7 @@ import org.autojs.autojs.pio.UncheckedIOException import org.autojs.autojs.project.ProjectConfig import org.autojs.autojs.script.JavaScriptFileSource import org.autojs.autojs.script.JavaScriptSource +import org.autojs.autojs.util.IntentUtils.startSafely import java.io.File import java.io.IOException @@ -46,10 +47,9 @@ open class AssetsProjectLauncher(private val mAssetsProjectDir: String, private } else { // 否则显示日志界面并在日志界面中运行脚本 mHandler.post { - activity.startActivity( - Intent(mActivity, LogActivity::class.java) - .putExtra(LogActivity.EXTRA_LAUNCH_SCRIPT, true) - ) + Intent(mActivity, LogActivity::class.java) + .putExtra(LogActivity.EXTRA_LAUNCH_SCRIPT, true) + .startSafely(activity) activity.finish() } } diff --git a/app/src/main/java/org/autojs/autojs/permission/AllFilesAccessPermission.kt b/app/src/main/java/org/autojs/autojs/permission/AllFilesAccessPermission.kt index 3c34b822..77a107b4 100644 --- a/app/src/main/java/org/autojs/autojs/permission/AllFilesAccessPermission.kt +++ b/app/src/main/java/org/autojs/autojs/permission/AllFilesAccessPermission.kt @@ -16,6 +16,7 @@ import org.autojs.autojs.ui.common.NotAskAgainDialog import org.autojs.autojs.ui.main.MainActivity import org.autojs.autojs.ui.main.drawer.PermissionItemHelper import org.autojs.autojs.util.IntentUtils +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.StringUtils.key import org.autojs.autojs6.R @@ -56,17 +57,16 @@ class AllFilesAccessPermission(override val context: Context) : PermissionItemHe } @RequiresApi(Build.VERSION_CODES.R) - private fun manageAllFilesAccess(): Boolean = runCatching { + private fun manageAllFilesAccess(): Boolean = when { Intent() .setAction(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION) .setData(Uri.fromParts("package", context.packageName, null)) - .let { context.startActivity(it) } - true - }.isSuccess || runCatching { + .startSafely(context) -> true Intent() .setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION) - .let { context.startActivity(it) } - }.isSuccess + .startSafely(context) -> true + else -> false + } private fun launchAppDetailsSettings() = IntentUtils.launchAppDetailsSettings(context) diff --git a/app/src/main/java/org/autojs/autojs/permission/IgnoreBatteryOptimizationsPermission.kt b/app/src/main/java/org/autojs/autojs/permission/IgnoreBatteryOptimizationsPermission.kt index e95e678d..c5f8b531 100644 --- a/app/src/main/java/org/autojs/autojs/permission/IgnoreBatteryOptimizationsPermission.kt +++ b/app/src/main/java/org/autojs/autojs/permission/IgnoreBatteryOptimizationsPermission.kt @@ -7,6 +7,7 @@ import android.os.PowerManager import android.provider.Settings import androidx.core.net.toUri import org.autojs.autojs.ui.main.drawer.PermissionItemHelper +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.R @@ -24,19 +25,14 @@ class IgnoreBatteryOptimizationsPermission(override val context: Context) : Perm override fun request() = Intent() .setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) .setData("package:${context.packageName}".toUri()) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { tryStartActivity(it) } + .startSafely(context, true) { + ViewUtils.showToast(context, R.string.text_failed) + } override fun revoke() = Intent() .setAction(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { tryStartActivity(it) } - - private fun tryStartActivity(i: Intent) = runCatching { - context.startActivity(i) - }.onFailure { - it.printStackTrace() - ViewUtils.showToast(context, R.string.text_failed) - }.isSuccess + .startSafely(context, true) { + ViewUtils.showToast(context, R.string.text_failed) + } } \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/permission/WriteSystemSettingsPermission.kt b/app/src/main/java/org/autojs/autojs/permission/WriteSystemSettingsPermission.kt index cf672a1c..0f03a813 100644 --- a/app/src/main/java/org/autojs/autojs/permission/WriteSystemSettingsPermission.kt +++ b/app/src/main/java/org/autojs/autojs/permission/WriteSystemSettingsPermission.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.net.Uri import android.provider.Settings import org.autojs.autojs.ui.main.drawer.PermissionItemHelper +import org.autojs.autojs.util.IntentUtils.startSafely class WriteSystemSettingsPermission(override val context: Context) : PermissionItemHelper { @@ -14,10 +15,8 @@ class WriteSystemSettingsPermission(override val context: Context) : PermissionI override fun revoke() = false.also { config() } - fun config() = context.startActivity( - Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS) - .setData(Uri.parse("package:${context.packageName}")) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - ) + fun config() = Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS) + .setData(Uri.parse("package:${context.packageName}")) + .startSafely(context) } \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/AppUtils.kt b/app/src/main/java/org/autojs/autojs/runtime/api/AppUtils.kt index 04b4e5b8..ad02e078 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/AppUtils.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/AppUtils.kt @@ -27,6 +27,8 @@ import org.autojs.autojs.ui.settings.AboutActivity import org.autojs.autojs.ui.settings.PreferencesActivity import org.autojs.autojs.util.App import org.autojs.autojs.util.IntentUtils +import org.autojs.autojs.util.IntentUtils.start +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs6.R import java.lang.ref.WeakReference import java.net.URI @@ -63,7 +65,7 @@ class AppUtils(context: Context, @get:ScriptInterface val fileProviderAuthority: o ?: return false val nicePackageName = getAppByAlias(alias = o)?.packageName ?: (/* packageName = */ o) val intent = mPackageManager.getLaunchIntentForPackage(nicePackageName) ?: return false - mContext.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) + intent.start(mContext) }.isSuccess @ScriptInterface @@ -155,8 +157,7 @@ class AppUtils(context: Context, @get:ScriptInterface val fileProviderAuthority: @ScriptInterface fun uninstall(packageName: String) { Intent(Intent.ACTION_DELETE, "package:$packageName".toUri()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { mContext.startActivity(it) } + .startSafely(mContext) } @ScriptInterface diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/Events.java b/app/src/main/java/org/autojs/autojs/runtime/api/Events.java index b8adc096..ebbcb053 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/Events.java +++ b/app/src/main/java/org/autojs/autojs/runtime/api/Events.java @@ -30,6 +30,7 @@ import org.autojs.autojs.core.pref.Language; import org.autojs.autojs.runtime.ScriptRuntime; import org.autojs.autojs.runtime.exception.ScriptException; import org.autojs.autojs.tool.MapBuilder; +import org.autojs.autojs.util.IntentUtils; import org.autojs.autojs6.R; import org.mozilla.javascript.BaseFunction; @@ -240,9 +241,8 @@ public class Events extends EventEmitter implements OnKeyListener, TouchObserver NotificationListenerService.getInstance().addListener(this); return; } - Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - mContext.startActivity(intent); + Intent intent = new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS); + IntentUtils.startSafely(intent, mContext); throw new ScriptException(mContext.getString(R.string.text_notification_service_disabled)); } diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/Permissions.kt b/app/src/main/java/org/autojs/autojs/runtime/api/Permissions.kt index 6e0784d6..7b7717d9 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/Permissions.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/Permissions.kt @@ -8,6 +8,7 @@ import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions import androidx.fragment.app.FragmentActivity import org.autojs.autojs.core.pref.Pref +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.RomUtils import org.autojs.autojs6.R @@ -20,18 +21,19 @@ class Permissions(private val context: Context) { var backgroundStart = object : IPermissionToggleable { override val description = "后台弹出界面 / Start in background" override fun has() = RomUtils.isBackgroundStartGranted(context) - override fun config() = when { - RomUtils.isMiui() -> { - Intent("miui.intent.action.APP_PERM_EDITOR").apply { - setClassName( - "com.miui.securitycenter", - "com.miui.permcenter.permissions.PermissionsEditorActivity", - ) - putExtra("extra_pkgname", context.packageName) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { context.startActivity(it) } + override fun config() { + when { + RomUtils.isMiui() -> { + Intent("miui.intent.action.APP_PERM_EDITOR").apply { + setClassName( + "com.miui.securitycenter", + "com.miui.permcenter.permissions.PermissionsEditorActivity", + ) + putExtra("extra_pkgname", context.packageName) + }.startSafely(context) + } + else -> super.config() } - else -> super.config() } } var displayOverOtherApps: IPermissionToggleable? = null diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/WrappedShizuku.kt b/app/src/main/java/org/autojs/autojs/runtime/api/WrappedShizuku.kt index 86fa3095..cc795f5b 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/WrappedShizuku.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/WrappedShizuku.kt @@ -15,6 +15,7 @@ import org.autojs.autojs.app.GlobalAppContext import org.autojs.autojs.core.shizuku.IUserService import org.autojs.autojs.core.shizuku.UserService import org.autojs.autojs.util.App.SHIZUKU +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.R import rikka.shizuku.Shizuku @@ -151,7 +152,7 @@ object WrappedShizuku { fun config(isRequest: Boolean? = null) = configWithContext(GlobalAppContext.get(), isRequest) fun configWithContext(context: Context, isRequest: Boolean? = null): Intent? = getLaunchIntent(context)?.also { - context.startActivity(it) + it.startSafely(context) val message = when (isRequest) { true -> "${context.getString(R.string.text_grant_autojs6_access_in_shizuku_app)} (${context.getString(R.string.text_shizuku_service_may_need_to_be_run_first)})" false -> context.getString(R.string.text_revoke_autojs6_access_in_shizuku_app) diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/app/App.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/app/App.kt index 3f56a399..ba870039 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/app/App.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/app/App.kt @@ -36,6 +36,7 @@ import org.autojs.autojs.runtime.api.augment.shell.Shell import org.autojs.autojs.runtime.exception.ShouldNeverHappenException import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException import org.autojs.autojs.timing.TimedTaskManager +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.RhinoUtils import org.autojs.autojs.util.RhinoUtils.UNDEFINED import org.autojs.autojs.util.RhinoUtils.coerceBoolean @@ -551,8 +552,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { val prefix = "http://".takeUnless { url.contains("://") } ?: "" Intent(Intent.ACTION_VIEW) .setData((prefix + url).toUri()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { globalContext.startActivity(it) } + .startSafely(globalContext) } @Suppress("HttpUrlsUsage") @@ -906,7 +906,7 @@ class App(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { } private fun startActivityWithGlobalContext(o: Intent) { - globalContext.startActivity(o.apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }) + o.startSafely(globalContext) } private fun startActivityForDualUser(scriptRuntime: ScriptRuntime, o: Any?) { diff --git a/app/src/main/java/org/autojs/autojs/service/NotificationService.kt b/app/src/main/java/org/autojs/autojs/service/NotificationService.kt index b5927c21..b960e82e 100644 --- a/app/src/main/java/org/autojs/autojs/service/NotificationService.kt +++ b/app/src/main/java/org/autojs/autojs/service/NotificationService.kt @@ -5,6 +5,7 @@ import android.content.Intent import android.provider.Settings import org.autojs.autojs.core.notification.NotificationListenerService import org.autojs.autojs.ui.main.drawer.ServiceItemHelper +import org.autojs.autojs.util.IntentUtils.startSafely class NotificationService(override val context: Context) : ServiceItemHelper { @@ -16,7 +17,7 @@ class NotificationService(override val context: Context) : ServiceItemHelper { override fun stop(): Boolean = false.also { config() } fun config() { - context.startActivity(Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS)) + Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS).startSafely(context) } } \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/theme/app/ColorInfoDialogManager.kt b/app/src/main/java/org/autojs/autojs/theme/app/ColorInfoDialogManager.kt index be09c58e..a753a251 100644 --- a/app/src/main/java/org/autojs/autojs/theme/app/ColorInfoDialogManager.kt +++ b/app/src/main/java/org/autojs/autojs/theme/app/ColorInfoDialogManager.kt @@ -13,6 +13,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.autojs.autojs.app.DialogUtils.showAdaptive import org.autojs.autojs.extension.MaterialDialogExtensions.makeTextCopyable import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableText import org.autojs.autojs.runtime.api.augment.colors.Colors @@ -35,7 +36,7 @@ object ColorInfoDialogManager { .content(R.string.error_invalid_color) .positiveText(R.string.dialog_button_dismiss) .positiveColorRes(R.color.dialog_button_default) - .show() + .showAdaptive() return } val binding = ColorInfoDialogItemsBinding.inflate(LayoutInflater.from(context)) diff --git a/app/src/main/java/org/autojs/autojs/theme/app/ColorSelectBaseActivity.kt b/app/src/main/java/org/autojs/autojs/theme/app/ColorSelectBaseActivity.kt index eba0bfdf..affb6177 100644 --- a/app/src/main/java/org/autojs/autojs/theme/app/ColorSelectBaseActivity.kt +++ b/app/src/main/java/org/autojs/autojs/theme/app/ColorSelectBaseActivity.kt @@ -46,6 +46,7 @@ import org.autojs.autojs.theme.app.ColorLibrariesActivity.Companion.presetColorL import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.main.drawer.DrawerFragment.Companion.Event.ThemeColorLayoutSwitchedEvent import org.autojs.autojs.util.ColorUtils +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs.util.ViewUtils.onceGlobalLayout import org.autojs.autojs.util.ViewUtils.setColorsByColorLuminance @@ -523,8 +524,7 @@ abstract class ColorSelectBaseActivity : BaseActivity() { protected fun showColorSearchHelp() { Intent(this, ColorSearchHelpActivity::class.java) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { startActivity(it) } + .startSafely(this) } protected fun filterColorsFromColorItems(query: String?, colorItems: List, colorItemAdapter: ColorItemAdapter) { @@ -659,7 +659,7 @@ abstract class ColorSelectBaseActivity : BaseActivity() { intent.putExtra("currentColor", context.currentColor) context.finish() } - context.startActivity(intent) + intent.startSafely(context) } @JvmStatic diff --git a/app/src/main/java/org/autojs/autojs/timing/ExactAlarmPermissionHelper.kt b/app/src/main/java/org/autojs/autojs/timing/ExactAlarmPermissionHelper.kt index 7e2e108a..ddffeb98 100644 --- a/app/src/main/java/org/autojs/autojs/timing/ExactAlarmPermissionHelper.kt +++ b/app/src/main/java/org/autojs/autojs/timing/ExactAlarmPermissionHelper.kt @@ -7,8 +7,10 @@ import android.os.Build import android.provider.Settings import androidx.annotation.RequiresApi import androidx.core.net.toUri +import org.autojs.autojs.app.DialogUtils.showAdaptive import org.autojs.autojs.extension.MaterialDialogExtensions.widgetThemeColor import org.autojs.autojs.ui.common.NotAskAgainDialog +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.StringUtils.key import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.R @@ -26,7 +28,7 @@ object ExactAlarmPermissionHelper { val intent = Intent() .setAction(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM) .setData("package:${context.packageName}".toUri()) - return runCatching { context.startActivity(intent) }.isSuccess + return runCatching { intent.startSafely(context) }.isSuccess } // Check canScheduleExactAlarms permission and prompt user if needed. @@ -57,7 +59,7 @@ object ExactAlarmPermissionHelper { } .cancelable(false) .autoDismiss(false) - .show() + .showAdaptive() } } \ No newline at end of file diff --git a/app/src/main/java/org/autojs/autojs/tool/CrashHandler.kt b/app/src/main/java/org/autojs/autojs/tool/CrashHandler.kt index fdeebfd3..2d028967 100644 --- a/app/src/main/java/org/autojs/autojs/tool/CrashHandler.kt +++ b/app/src/main/java/org/autojs/autojs/tool/CrashHandler.kt @@ -6,6 +6,7 @@ import android.util.Log import org.autojs.autojs.app.GlobalAppContext import org.autojs.autojs.core.accessibility.AccessibilityService import org.autojs.autojs.runtime.ScriptRuntime +import org.autojs.autojs.util.IntentUtils.startSafely import java.lang.Thread.UncaughtExceptionHandler import java.lang.ref.WeakReference import kotlin.system.exitProcess @@ -48,11 +49,12 @@ class CrashHandler(private val errorReportClass: Class<*>) : UncaughtExceptionHa } private fun startCrashReportActivity(msg: String, detail: String) { - Intent(GlobalAppContext.get(), errorReportClass).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP) + val context = GlobalAppContext.get() + Intent(context, errorReportClass).apply { + addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) putExtra("message", msg) putExtra("error", detail) - }.let { GlobalAppContext.get().startActivity(it) } + }.startSafely(context) } companion object { diff --git a/app/src/main/java/org/autojs/autojs/ui/common/ScriptLoopDialog.java b/app/src/main/java/org/autojs/autojs/ui/common/ScriptLoopDialog.java index d42f432b..68766a2a 100644 --- a/app/src/main/java/org/autojs/autojs/ui/common/ScriptLoopDialog.java +++ b/app/src/main/java/org/autojs/autojs/ui/common/ScriptLoopDialog.java @@ -66,7 +66,7 @@ public class ScriptLoopDialog { } public void show() { - DialogUtils.showDialog(mDialog); + DialogUtils.showAdaptive(mDialog); } } 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 b08fb6fb..4a80a0d1 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 @@ -43,6 +43,7 @@ import org.autojs.autojs.ui.filechooser.FileChooserDialogBuilder; 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.ShortcutUtils; import org.autojs.autojs.util.ViewUtils; import org.autojs.autojs.util.WorkingDirectoryUtils; @@ -61,7 +62,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import static org.autojs.autojs.app.DialogUtils.fixCheckBoxGravity; -import static org.autojs.autojs.app.DialogUtils.showDialog; import static org.autojs.autojs.util.FileUtils.TYPE.JAVASCRIPT; import static org.autojs.autojs.util.RhinoUtils.isMainThread; @@ -198,14 +198,14 @@ public class ScriptOperations { .negativeText(R.string.dialog_button_back); MaterialDialogExtensions.choiceWidgetThemeColor(builderDefaultPrefix); MaterialDialog dialogDefaultPrefix = builderDefaultPrefix.build(); - showDialog(dialogDefaultPrefix); + DialogUtils.showAdaptive(dialogDefaultPrefix); }) .autoDismiss(false); MaterialDialogExtensions.widgetThemeColor(builder); MaterialDialog dialog = builder.build(); dialogRef.set(dialog); - showDialog(fixCheckBoxGravity(dialog)); + DialogUtils.showAdaptive(fixCheckBoxGravity(dialog)); } private String getNewFileNamePresetPrefill(CharSequence prefix) { @@ -339,7 +339,7 @@ public class ScriptOperations { }) .canceledOnTouchOutside(false); MaterialDialogExtensions.widgetThemeColor(builder); - showDialog(builder.build()); + DialogUtils.showAdaptive(builder.build()); return input; } @@ -384,13 +384,12 @@ public class ScriptOperations { return; } Intent intent = new Intent(mContext, ShortcutCreateActivity.class) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .putExtra(ShortcutCreateActivity.EXTRA_FILE, file); - mContext.startActivity(intent); + IntentUtils.startSafely(intent, mContext); } public void delete(final ScriptFile scriptFile) { - DialogUtils.showDialog(new MaterialDialog.Builder(mContext) + DialogUtils.showAdaptive(new MaterialDialog.Builder(mContext) .title(mContext.getString(R.string.text_confirm_to_delete)) .content(scriptFile.getName()) .negativeText(R.string.text_cancel) @@ -409,7 +408,7 @@ public class ScriptOperations { } String content = mContext.getString(R.string.text_old_path) + ": " + oldPath + "\n" + mContext.getString(R.string.text_new_path) + ": " + newPath; - DialogUtils.showDialog(new MaterialDialog.Builder(mContext) + DialogUtils.showAdaptive(new MaterialDialog.Builder(mContext) .title(mContext.getString(R.string.text_prompt)) .content(content) .negativeText(R.string.text_cancel) @@ -489,7 +488,7 @@ public class ScriptOperations { } public void importFile() { - DialogUtils.showDialog(new FileChooserDialogBuilder(mContext) + DialogUtils.showAdaptive(new FileChooserDialogBuilder(mContext) .dir(EnvironmentUtils.getExternalStoragePath()) .justScriptFile() .singleChoice(file -> importFile(file.getPath()).subscribe()) @@ -502,7 +501,7 @@ public class ScriptOperations { public void timedTask(ScriptFile scriptFile) { Intent intent = new Intent(mContext, TimedTaskSettingActivity.class) .putExtra(ScriptIntents.EXTRA_KEY_PATH, scriptFile.getPath()); - mContext.startActivity(intent); + IntentUtils.startSafely(intent, mContext); } private class InputCallback implements MaterialDialog.InputCallback { diff --git a/app/src/main/java/org/autojs/autojs/ui/doc/ManualDialog.kt b/app/src/main/java/org/autojs/autojs/ui/doc/ManualDialog.kt index 305aa1cb..f0ce7582 100644 --- a/app/src/main/java/org/autojs/autojs/ui/doc/ManualDialog.kt +++ b/app/src/main/java/org/autojs/autojs/ui/doc/ManualDialog.kt @@ -10,6 +10,7 @@ import android.view.View import android.widget.TextView import com.afollestad.materialdialogs.MaterialDialog import org.autojs.autojs.ui.widget.EWebView +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs6.databinding.FloatingManualDialogBinding /** @@ -62,7 +63,7 @@ class ManualDialog(private val mContext: Context) { mDialog.dismiss() Intent(mContext, DocumentationActivity::class.java) .putExtra(DocumentationActivity.EXTRA_URL, mEWebView.webView.url) - .let { mContext.startActivity(it) } + .startSafely(mContext) } } diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.kt b/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.kt index 32b9fc43..2eeea4af 100644 --- a/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.kt @@ -16,6 +16,8 @@ import android.view.ActionMode import android.view.Menu import android.view.MenuItem import android.widget.TextView +import androidx.core.view.get +import androidx.core.view.size import com.afollestad.materialdialogs.MaterialDialog import io.reactivex.Observable import io.reactivex.android.schedulers.AndroidSchedulers @@ -33,6 +35,7 @@ import org.autojs.autojs.theme.widget.ThemeColorToolbar import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.main.MainActivity import org.autojs.autojs.ui.main.scripts.EditableFileInfoDialogManager +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.Observers import org.autojs.autojs.util.ViewUtils.onceGlobalLayout import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByThemeColorLuminance @@ -40,8 +43,6 @@ import org.autojs.autojs6.R import org.autojs.autojs6.databinding.ActivityEditBinding import java.io.File import java.io.IOException -import androidx.core.view.get -import androidx.core.view.size /** * Created by Stardust on Jan 29, 2017. @@ -364,50 +365,46 @@ open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyAc private const val LOG_TAG = "EditActivity" @JvmStatic - fun editFile(context: Context, path: String?, newTask: Boolean) { + fun editFile(context: Context, path: String?, newTask: Boolean) = editFile(context, null, path, newTask) - } @JvmStatic - fun editFile(context: Context, uri: Uri?, newTask: Boolean) { - runCatching { - context.startActivity(newIntent(context).setData(uri)) - }.getOrElse { - context.startActivity(newIntentFallback(context, newTask).setData(uri)) + fun editFile(context: Context, uri: Uri?, newTask: Boolean) = + when { + newIntent(context).setData(uri).startSafely(context) -> true + newIntentFallback(context, newTask).setData(uri).startSafely(context) -> true + else -> false } - } @JvmStatic - fun editFile(context: Context, name: String?, path: String?, newTask: Boolean) { - runCatching { - context.startActivity(newIntent(context).apply { + fun editFile(context: Context, name: String?, path: String?, newTask: Boolean) = + when { + newIntent(context).apply { putExtra(EditorView.EXTRA_PATH, path) putExtra(EditorView.EXTRA_NAME, name) - }) - }.getOrElse { - context.startActivity(newIntentFallback(context, newTask).apply { + }.startSafely(context) -> true + newIntentFallback(context, newTask).apply { putExtra(EditorView.EXTRA_PATH, path) putExtra(EditorView.EXTRA_NAME, name) - }) + }.startSafely(context) -> true + else -> false } - } @JvmStatic - fun viewContent(context: Context, name: String?, content: String?, newTask: Boolean) { - runCatching { - context.startActivity(newIntent(context).apply { + fun viewContent(context: Context, name: String?, content: String?, newTask: Boolean) = + when { + newIntent(context).apply { putExtra(EditorView.EXTRA_CONTENT, content) putExtra(EditorView.EXTRA_NAME, name) putExtra(EditorView.EXTRA_READ_ONLY, true) - }) - }.getOrElse { - context.startActivity(newIntentFallback(context, newTask).apply { + }.startSafely(context) -> true + newIntentFallback(context, newTask).apply { putExtra(EditorView.EXTRA_CONTENT, content) putExtra(EditorView.EXTRA_NAME, name) putExtra(EditorView.EXTRA_READ_ONLY, true) - }) + }.startSafely(context) -> true + else -> false } - } private fun newIntent(context: Context): Intent { // @Caution by SuperMonster003 on Sep 11, 2022. diff --git a/app/src/main/java/org/autojs/autojs/ui/enhancedfloaty/util/FloatingWindowPermissionUtil.java b/app/src/main/java/org/autojs/autojs/ui/enhancedfloaty/util/FloatingWindowPermissionUtil.java index d76d1fdd..fcf502ed 100644 --- a/app/src/main/java/org/autojs/autojs/ui/enhancedfloaty/util/FloatingWindowPermissionUtil.java +++ b/app/src/main/java/org/autojs/autojs/ui/enhancedfloaty/util/FloatingWindowPermissionUtil.java @@ -22,9 +22,9 @@ public class FloatingWindowPermissionUtil { public static void goToFloatingWindowPermissionSetting(Context context) { String packageName = context.getPackageName(); try { - context.startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, - Uri.parse("package:" + packageName)) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, + Uri.parse("package:" + packageName)); + IntentUtils.start(intent, context); } catch (Exception e) { IntentUtils.launchAppDetailsSettings(context, packageName); } diff --git a/app/src/main/java/org/autojs/autojs/ui/error/CrashReportActivity.kt b/app/src/main/java/org/autojs/autojs/ui/error/CrashReportActivity.kt index 16c44b99..4cbd1a2f 100644 --- a/app/src/main/java/org/autojs/autojs/ui/error/CrashReportActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/error/CrashReportActivity.kt @@ -7,6 +7,7 @@ import org.autojs.autojs.runtime.api.augment.util.VersionCodesInfo.briefOfCurren import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.main.MainActivity import org.autojs.autojs.util.ClipboardUtils +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.BuildConfig import org.autojs.autojs6.R @@ -70,9 +71,9 @@ class CrashReportActivity : BaseActivity() { val intent = packageManager.getLaunchIntentForPackage(packageName)?.apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) } ?: Intent(this, MainActivity::class.java).apply { - addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK) + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) } - startActivity(intent) + intent.startSafely(this) exit() } diff --git a/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java b/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java index 0743fe7e..550e87ac 100644 --- a/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java +++ b/app/src/main/java/org/autojs/autojs/ui/error/ErrorDialogActivity.java @@ -7,6 +7,7 @@ import com.afollestad.materialdialogs.MaterialDialog; import org.autojs.autojs.extension.MaterialDialogExtensions; import org.autojs.autojs.ui.BaseActivity; import org.autojs.autojs.util.ClipboardUtils; +import org.autojs.autojs.util.IntentUtils; import org.autojs.autojs.util.ViewUtils; import org.autojs.autojs6.R; @@ -75,8 +76,7 @@ public class ErrorDialogActivity extends BaseActivity { Intent intent = new Intent(context, ErrorDialogActivity.class); intent.putExtra(EXTRA_TITLE, context.getString(titleRes)); intent.putExtra(EXTRA_MESSAGE, message); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); + IntentUtils.startSafely(intent, context); } /** @@ -88,8 +88,7 @@ public class ErrorDialogActivity extends BaseActivity { intent.putExtra(EXTRA_TITLE, context.getString(titleRes)); intent.putExtra(EXTRA_MESSAGE, message); intent.putExtra(EXTRA_POSITIVE_BUTTON_TEXT, context.getString(positiveButtonTextRes)); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - context.startActivity(intent); + IntentUtils.startSafely(intent, context); } } diff --git a/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerProjectToolbar.java b/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerProjectToolbar.java index 94619c18..4684d006 100644 --- a/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerProjectToolbar.java +++ b/app/src/main/java/org/autojs/autojs/ui/explorer/ExplorerProjectToolbar.java @@ -21,6 +21,7 @@ import org.autojs.autojs.project.ProjectConfig; import org.autojs.autojs.project.ProjectLauncher; import org.autojs.autojs.ui.project.BuildActivity; import org.autojs.autojs.ui.project.ProjectConfigActivity; +import org.autojs.autojs.util.IntentUtils; import org.autojs.autojs6.R; import org.autojs.autojs6.databinding.ExplorerProjectToolbarBinding; import org.greenrobot.eventbus.Subscribe; @@ -148,9 +149,8 @@ public class ExplorerProjectToolbar extends CardView { void edit() { Intent intent = new Intent(getContext(), ProjectConfigActivity.class) - .putExtra(ProjectConfigActivity.EXTRA_DIRECTORY, mDirectory.getPath()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - getContext().startActivity(intent); + .putExtra(ProjectConfigActivity.EXTRA_DIRECTORY, mDirectory.getPath()); + IntentUtils.startSafely(intent, getContext()); } public void setRunnableOnly(boolean b) { 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 f6f1ac58..1a1beb52 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 @@ -81,8 +81,9 @@ import java.util.concurrent.Callable /** * Created by Stardust on Aug 21, 2017. - * Modified by SuperMonster003 as of Apr 1, 2023. * 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. */ @SuppressLint("CheckResult", "NonConstantResourceId", "NotifyDataSetChanged") open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRefreshListener, PopupMenu.OnMenuItemClickListener { @@ -134,6 +135,11 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef ColorStateList.valueOf(context.getColor(R.color.explorer_file_operation_button)) } + // Request host dialog to hide/show without losing state. + // zh-CN: 请求宿主对话框隐藏/显示且不丢失状态. + private var mRequestHostDialogHide: Runnable? = null + private var mRequestHostDialogShow: Runnable? = null + constructor(context: Context) : super(context) { init(context) } @@ -142,6 +148,18 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef init(context) } + // Set hide callback from Java callers (e.g. CircularMenu). + // zh-CN: 提供给 Java 调用方 (例如 CircularMenu) 设置 hide 回调. + fun setRequestHostDialogHide(runnable: Runnable?) { + mRequestHostDialogHide = runnable + } + + // Set show callback from Java callers (e.g. CircularMenu). + // zh-CN: 提供给 Java 调用方 (例如 CircularMenu) 设置 show 回调. + fun setRequestHostDialogShow(runnable: Runnable?) { + mRequestHostDialogShow = runnable + } + private fun init(context: Context) { ExplorerViewBinding.inflate(LayoutInflater.from(context), this, true).also { binding -> this.binding = binding @@ -248,6 +266,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef R.id.create_shortcut -> { ScriptOperations(context, this@ExplorerView, currentPage) .createShortcut(selectedItem!!.toScriptFile()) + mRequestHostDialogHide?.run() } R.id.open_by_other_apps -> { Scripts.openByOtherApps(selectedItem!!.toScriptFile()) @@ -256,15 +275,18 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef R.id.send -> { Scripts.send(context, selectedItem!!.toScriptFile()) notifyItemOperated() + mRequestHostDialogHide?.run() } R.id.timed_task -> { ScriptOperations(context, this@ExplorerView, currentPage) .timedTask(selectedItem!!.toScriptFile()) notifyItemOperated() + mRequestHostDialogHide?.run() } R.id.action_build_apk -> { BuildActivity.launch(context, selectedItem!!.path) notifyItemOperated() + mRequestHostDialogHide?.run() } R.id.reset -> { val o = Explorers.Providers.workspace() @@ -844,6 +866,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef } private fun run() { + mRequestHostDialogHide?.run() when { mExplorerItem.isExecutable -> { Scripts.run(context, ScriptFile(mExplorerItem.path)) @@ -857,6 +880,8 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef } private fun edit() { + mRequestHostDialogHide?.run() + when { mExplorerItem.isTextEditable -> { Scripts.edit(context, ScriptFile(mExplorerItem.path)) @@ -870,19 +895,32 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef } private fun showInfo() { + // Hide host overlay dialog so the info dialog can be shown on top. + // zh-CN: 隐藏宿主 overlay 对话框, 让信息对话框显示在最上层. + mRequestHostDialogHide?.run() + when { mExplorerItem.isInstallable -> { - ApkInfoDialogManager.showApkInfoDialog(context, mExplorerItem.toScriptFile()) + ApkInfoDialogManager.showApkInfoDialog(context, mExplorerItem.toScriptFile(), null) { + // Restore host dialog after the info dialog is dismissed. + // zh-CN: 信息对话框关闭后恢复宿主对话框. + mRequestHostDialogShow?.run() + } notifyItemOperated() } mExplorerItem.isMediaMenu || mExplorerItem.isMediaPlayable -> { - MediaInfoDialogManager.showMediaInfoDialog(context, mExplorerItem) + MediaInfoDialogManager.showMediaInfoDialog(context, mExplorerItem, null) { + // Restore host dialog after the info dialog is dismissed. + // zh-CN: 信息对话框关闭后恢复宿主对话框. + mRequestHostDialogShow?.run() + } notifyItemOperated() } } } private fun install() { + mRequestHostDialogHide?.run() when { mExplorerItem.isInstallable -> { mExplorerItem.install(this@ExplorerView) @@ -1001,6 +1039,7 @@ open class ExplorerView : ThemeColorSwipeRefreshLayout, SwipeRefreshLayout.OnRef .setAsWorkingDir(selectedItem!!.toScriptFile()) } R.id.action_build_apk -> { + mRequestHostDialogHide?.run() BuildActivity.launch(context, selectedItem!!.path) } R.id.reset -> { 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 9c8eb7ee..db53c4d6 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 @@ -50,6 +50,8 @@ import java.text.MessageFormat; /** * Created by Stardust on Oct 18, 2017. + * Modified by JetBrains AI Assistant (GPT-5.2) as of Jan 20, 2026. + * Modified by SuperMonster003 as of Jan 20, 2026. */ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { @@ -70,6 +72,8 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { private final Recorder.OnStateChangedListener mRecorderStateListener; private CircularActionMenuBinding binding; private MaterialDialog mSettingsDialog; + private MaterialDialog mScriptListDialog; + private ExplorerView mScriptListDialogExplorerView; private MaterialDialog mLayoutInspectDialog; private String mRunningPackage; private String mRunningActivity; @@ -135,53 +139,82 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { private void setupBindingListeners() { binding.scriptList.setOnClickListener(v -> { mWindow.collapse(); - ExplorerView explorerView = new ExplorerView(mContext); - explorerView.setExplorer(Explorers.workspace(), ExplorerDirPage.createRoot(WorkingDirectoryUtils.getPath())); - explorerView.setDirectorySpanSize(2); - final MaterialDialog dialog = new MaterialDialog.Builder(mContext) - .title(R.string.text_run_script) - .titleColorRes(R.color.day_night) - .customView(explorerView, false) - .backgroundColorRes(R.color.window_background) - .positiveText(R.string.dialog_button_dismiss) - .positiveColorRes(R.color.dialog_button_default) - .cancelable(false) - .build(); - // Only dismiss on clicking the item itself. - // zh-CN: 仅在点击条目本体时关闭对话框. - explorerView.setOnItemClickListener((view, item) -> { - if (item.isExecutable()) { - dialog.dismiss(); - Scripts.run(view != null ? view.getContext() : explorerView.getContext(), item.toScriptFile()); - } else { - DialogUtils.showDialog(new MaterialDialog.Builder(mContext) - .title(mContext.getString(R.string.error_failed_to_run_script)) - .content(mContext.getString( - R.string.text_file_with_abs_path_is_not_an_executable_script, - item.toScriptFile().getAbsolutePath() - )) - .positiveText(R.string.dialog_button_dismiss) - .positiveColorRes(R.color.dialog_button_failure) - .build()); - } - }); + if (mScriptListDialog == null) { - // Do not dismiss on action buttons (run/edit/delete/rename/etc.). - // zh-CN: 点击右侧操作按钮 (运行/编辑/删除/重命名等) 时不关闭对话框. - explorerView.setOnItemOperateListener(null); + mScriptListDialogExplorerView = new ExplorerView(mContext); + mScriptListDialogExplorerView.setExplorer(Explorers.workspace(), ExplorerDirPage.createRoot(WorkingDirectoryUtils.getPath())); + mScriptListDialogExplorerView.setDirectorySpanSize(2); - explorerView.setOnProjectToolbarOperateListener(toolbar -> dialog.dismiss()); - explorerView.setOnProjectToolbarClickListener(toolbar -> toolbar.findViewById(R.id.project_run).performClick()); - explorerView.setProjectToolbarRunnableOnly(true); + mScriptListDialog = new MaterialDialog.Builder(mContext) + .title(R.string.text_run_script) + .titleColorRes(R.color.day_night) + .customView(mScriptListDialogExplorerView, false) + .backgroundColorRes(R.color.window_background) + .neutralText(R.string.dialog_button_minimize) + .neutralColorRes(R.color.dialog_button_reset) + .onNeutral((dialog, which) -> { + mScriptListDialog.hide(); + }) + .positiveText(R.string.dialog_button_dismiss) + .positiveColorRes(R.color.dialog_button_default) + .onPositive((dialog, which) -> { + dialog.dismiss(); + mScriptListDialog = null; + mScriptListDialogExplorerView = null; + }) + .cancelable(false) + .autoDismiss(false) + .build(); - DialogUtils.adaptToExplorer(dialog, explorerView); - DialogUtils.showDialog(dialog); + var scriptListDialog = mScriptListDialog; + + // Hide host dialog before launching Activity or showing secondary dialogs. + // zh-CN: 在启动 Activity 或显示二级对话框之前隐藏宿主对话框. + mScriptListDialogExplorerView.setRequestHostDialogHide(scriptListDialog::hide); + + // Restore host dialog (overlay) when needed, keeping state. + // zh-CN: 需要时恢复宿主对话框 (overlay), 并保留状态. + mScriptListDialogExplorerView.setRequestHostDialogShow(() -> { + if (!scriptListDialog.isShowing()) { + DialogUtils.showDialog(scriptListDialog); + } + }); + + // Only dismiss on clicking the item itself. + // zh-CN: 仅在点击条目本体时关闭对话框. + mScriptListDialogExplorerView.setOnItemClickListener((view, item) -> { + if (item.isExecutable()) { + scriptListDialog.hide(); + Scripts.run(view != null ? view.getContext() : mScriptListDialogExplorerView.getContext(), item.toScriptFile()); + } else { + DialogUtils.showAdaptive(new MaterialDialog.Builder(mContext) + .title(mContext.getString(R.string.error_failed_to_run_script)) + .content(mContext.getString( + R.string.text_file_with_abs_path_is_not_an_executable_script, + item.toScriptFile().getAbsolutePath() + )) + .positiveText(R.string.dialog_button_dismiss) + .positiveColorRes(R.color.dialog_button_failure) + .build()); + } + }); + + mScriptListDialogExplorerView.setOnItemOperateListener(null); + + mScriptListDialogExplorerView.setOnProjectToolbarOperateListener(toolbar -> scriptListDialog.hide()); + mScriptListDialogExplorerView.setOnProjectToolbarClickListener(toolbar -> toolbar.findViewById(R.id.project_run).performClick()); + mScriptListDialogExplorerView.setProjectToolbarRunnableOnly(true); + + DialogUtils.adaptToExplorer(scriptListDialog, mScriptListDialogExplorerView); + } + + DialogUtils.showAdaptive(mScriptListDialog); }); binding.record.setOnClickListener(v -> { mWindow.collapse(); if (!RootUtils.isRootAvailable()) { - DialogUtils.showDialog(new AppLevelThemeDialogBuilder(mContext) + DialogUtils.showAdaptive(new AppLevelThemeDialogBuilder(mContext) .title(mContext.getString(R.string.text_no_root_access)) .content(mContext.getString(R.string.no_root_access_for_record)) .positiveText(R.string.dialog_button_abandon) @@ -199,7 +232,7 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { .item(R.drawable.ic_circular_menu_hierarchy, mContext.getString(R.string.text_inspect_layout_hierarchy), mCollapseWindowAndInspectLayoutHierarchyListener) .title(mContext.getString(R.string.text_inspect_layout)) .build(); - DialogUtils.showDialog(mLayoutInspectDialog); + DialogUtils.showAdaptive(mLayoutInspectDialog); return true; }); binding.stopAllScripts.setOnClickListener(v -> { @@ -248,7 +281,7 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { .title(mContext.getString(R.string.text_more)) .build(); - DialogUtils.showDialog(mSettingsDialog); + DialogUtils.showAdaptive(mSettingsDialog); }); } @@ -276,6 +309,7 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { private View.OnClickListener onCircularMenuItemClick(View.OnClickListener listener) { return v -> { dismissSettingsDialog(); + dismissScriptListDialog(); listener.onClick(v); }; } @@ -392,6 +426,16 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { } } + private void dismissScriptListDialog() { + if (mScriptListDialog != null) { + mScriptListDialog.dismiss(); + mScriptListDialog = null; + } + if (mScriptListDialogExplorerView != null) { + mScriptListDialogExplorerView = null; + } + } + @NonNull private String getTextAlreadyCopied(int actionResId) { return MessageFormat.format("{0} ({1})", @@ -401,6 +445,7 @@ public class CircularMenu implements LayoutInspector.CaptureAvailableListener { public void close() { dismissSettingsDialog(); + dismissScriptListDialog(); try { mWindow.close(); } catch (IllegalArgumentException e) { diff --git a/app/src/main/java/org/autojs/autojs/ui/floating/CodeGenerateDialog.java b/app/src/main/java/org/autojs/autojs/ui/floating/CodeGenerateDialog.java index 510e406f..2be0b7a6 100644 --- a/app/src/main/java/org/autojs/autojs/ui/floating/CodeGenerateDialog.java +++ b/app/src/main/java/org/autojs/autojs/ui/floating/CodeGenerateDialog.java @@ -86,7 +86,7 @@ public class CodeGenerateDialog extends AppLevelThemeDialogBuilder { String code = generateCode(); AppLevelThemeDialogBuilder builder = new AppLevelThemeDialogBuilder(context); if (code != null) { - DialogUtils.showDialog(builder + DialogUtils.showAdaptive(builder .title(R.string.text_generated_code) .content(code) .negativeText(R.string.dialog_button_cancel) @@ -99,7 +99,7 @@ public class CodeGenerateDialog extends AppLevelThemeDialogBuilder { })) .build()); } else { - DialogUtils.showDialog(builder + DialogUtils.showAdaptive(builder .title(R.string.text_prompt) .content(R.string.text_failed_to_generate) .positiveText(R.string.dialog_button_dismiss) diff --git a/app/src/main/java/org/autojs/autojs/ui/floating/LayoutFloatyWindow.kt b/app/src/main/java/org/autojs/autojs/ui/floating/LayoutFloatyWindow.kt index 50c4e336..b36cab0d 100644 --- a/app/src/main/java/org/autojs/autojs/ui/floating/LayoutFloatyWindow.kt +++ b/app/src/main/java/org/autojs/autojs/ui/floating/LayoutFloatyWindow.kt @@ -5,7 +5,7 @@ import android.view.ContextThemeWrapper import android.view.View import android.view.ViewGroup import org.autojs.autojs.app.AppLevelThemeDialogBuilder -import org.autojs.autojs.app.DialogUtils +import org.autojs.autojs.app.DialogUtils.showAdaptive import org.autojs.autojs.core.accessibility.Capture import org.autojs.autojs.core.accessibility.NodeInfo import org.autojs.autojs.core.accessibility.WindowInfo @@ -111,7 +111,7 @@ abstract class LayoutFloatyWindow( protected fun generateCode() { CodeGenerateDialog(context, capture.root, mLayoutSelectedNode) .build() - .let { DialogUtils.showDialog(it) } + .showAdaptive() } protected fun switchWindow() { @@ -129,7 +129,7 @@ abstract class LayoutFloatyWindow( val builder = WindowSwitchingDialog(context, windowInfoList).apply { sortItems(compareBy { it.order.rawValue }) } - val dialog = DialogUtils.showDialog(builder.build()) + val dialog = builder.build().showAdaptive() builder.itemsClickCallback = { _, position -> builder.itemList[position].window.root?.let { dialog.dismiss() diff --git a/app/src/main/java/org/autojs/autojs/ui/keystore/ManageKeyStoreActivity.kt b/app/src/main/java/org/autojs/autojs/ui/keystore/ManageKeyStoreActivity.kt index 4a2f5df9..87a41cd6 100644 --- a/app/src/main/java/org/autojs/autojs/ui/keystore/ManageKeyStoreActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/keystore/ManageKeyStoreActivity.kt @@ -21,6 +21,7 @@ import org.autojs.autojs.core.pref.Pref import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.keystore.NewKeyStoreDialog.NewKeyStoreConfigs import org.autojs.autojs.ui.viewmodel.KeyStoreViewModel +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils.excludeFloatingActionButtonFromBottomNavigationBar import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByThemeColorLuminance @@ -38,7 +39,7 @@ class ManageKeyStoreActivity : BaseActivity() { companion object { fun startActivity(context: Context) { - context.startActivity(Intent(context, ManageKeyStoreActivity::class.java)) + Intent(context, ManageKeyStoreActivity::class.java).startSafely(context) } } diff --git a/app/src/main/java/org/autojs/autojs/ui/log/LogActivity.kt b/app/src/main/java/org/autojs/autojs/ui/log/LogActivity.kt index 106a6423..c43dad9f 100644 --- a/app/src/main/java/org/autojs/autojs/ui/log/LogActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/log/LogActivity.kt @@ -10,6 +10,7 @@ import org.autojs.autojs.AutoJs.Companion.instance import org.autojs.autojs.core.console.GlobalConsole import org.autojs.autojs.runtime.api.Mime import org.autojs.autojs.ui.BaseActivity +import org.autojs.autojs.util.IntentUtils.startSafelyWithOptions import org.autojs.autojs.util.ViewUtils.excludeFloatingActionButtonFromBottomNavigationBar import org.autojs.autojs.util.ViewUtils.showToast import org.autojs.autojs6.R @@ -97,9 +98,9 @@ class LogActivity : BaseActivity() { @JvmStatic fun launch(context: Context) { - val intent = Intent(context, LogActivity::class.java).apply { addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } + val intent = Intent(context, LogActivity::class.java) val options = ActivityOptions.makeCustomAnimation(context, R.anim.no_anim_fade_in, R.anim.no_anim_fade_out) - context.startActivity(intent, options.toBundle()) + intent.startSafelyWithOptions(context, options.toBundle()) } } diff --git a/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.kt b/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.kt index c9326444..544f1dc4 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.kt @@ -54,6 +54,7 @@ import org.autojs.autojs.ui.settings.PreferencesActivity import org.autojs.autojs.ui.widget.DrawerAutoClose import org.autojs.autojs.ui.widget.SearchViewItem import org.autojs.autojs.util.IntentUtils +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.StringUtils.key import org.autojs.autojs.util.UpdateUtils import org.autojs.autojs.util.ViewUtils @@ -451,7 +452,7 @@ class MainActivity : BaseActivity(), DelegateHost, HostActivity { var shouldRecreateMainActivity = false @JvmStatic - fun launch(context: Context) = context.startActivity(getIntent(context).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) + fun launch(context: Context) = getIntent(context).startSafely(context) @JvmStatic fun getIntent(context: Context?) = Intent(context, MainActivity::class.java) diff --git a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt index 1d57d517..52798f61 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt @@ -50,6 +50,7 @@ import org.autojs.autojs.ui.settings.PreferencesActivity import org.autojs.autojs.util.DisplayUtils import org.autojs.autojs.util.IntentUtils.App.exit import org.autojs.autojs.util.IntentUtils.App.restart +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.NetworkUtils import org.autojs.autojs.util.NotificationUtils import org.autojs.autojs.util.RomUtils @@ -172,10 +173,8 @@ open class DrawerFragment : Fragment() { } } item.setOnLaunchSettingsListener { - Intent().apply { - action = Settings.ACTION_ACCESSIBILITY_SETTINGS - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { i -> mContext.startActivity(i) } + Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS) + .startSafely(mContext) } } @@ -375,10 +374,8 @@ open class DrawerFragment : Fragment() { descriptionRes = R.string.description_ignore_battery_optimizations, ).also { item -> item.setOnLaunchSettingsListener { - Intent().apply { - action = Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { i -> mContext.startActivity(i) } + Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS) + .startSafely(mContext) } } @@ -463,9 +460,9 @@ open class DrawerFragment : Fragment() { Shizuku.isPreV11() -> { ViewUtils.showSnack(d.view, R.string.error_shizuku_version_is_not_supported) } - else -> WrappedShizuku.getLaunchIntent(mContext)?.let { - runCatching { mContext.startActivity(it) }.getOrNull() - } ?: ViewUtils.showSnack(d.view, R.string.error_failed_to_revoke_shizuku_access) + else -> WrappedShizuku.getLaunchIntent(mContext) + ?.startSafely(mContext) + ?: ViewUtils.showSnack(d.view, R.string.error_failed_to_revoke_shizuku_access) } } } @@ -503,10 +500,8 @@ open class DrawerFragment : Fragment() { prefKey = R.string.key_auto_night_mode_enabled, ).also { item -> item.setOnLaunchSettingsListener { - Intent().apply { - action = Settings.ACTION_DISPLAY_SETTINGS - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { i -> mContext.startActivity(i) } + Intent(Settings.ACTION_DISPLAY_SETTINGS) + .startSafely(mContext) } item.isHidden = !ViewUtils.AutoNightMode.isFunctional() } @@ -539,10 +534,8 @@ open class DrawerFragment : Fragment() { descriptionRes = R.string.description_night_mode, prefKey = R.string.key_night_mode_enabled, ).setOnLaunchSettingsListener { - Intent().apply { - action = Settings.ACTION_DISPLAY_SETTINGS - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { i -> mContext.startActivity(i) } + Intent(Settings.ACTION_DISPLAY_SETTINGS) + .startSafely(mContext) } mKeepScreenOnWhenInForegroundItem = DrawerMenuToggleableItem( 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 8da44cae..a8c43f53 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 @@ -2,6 +2,7 @@ package org.autojs.autojs.ui.main.scripts import android.annotation.SuppressLint import android.content.Context +import android.content.DialogInterface import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.content.pm.PackageManager.GET_META_DATA @@ -24,6 +25,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.selects.select import kotlinx.coroutines.withContext import net.dongliu.apk.parser.ApkFile +import org.autojs.autojs.app.DialogUtils.showAdaptive import org.autojs.autojs.extension.MaterialDialogExtensions.makeSettingsLaunchable import org.autojs.autojs.extension.MaterialDialogExtensions.makeTextCopyable import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableTextIfAbsent @@ -43,7 +45,20 @@ object ApkInfoDialogManager { @JvmStatic @JvmOverloads @SuppressLint("SetTextI18n") - fun showApkInfoDialog(context: Context, apkFile: File, builderApplier: (MaterialDialog.Builder.() -> Unit)? = null) { + fun showApkInfoDialog( + context: Context, + apkFile: File, + builderApplier: (MaterialDialog.Builder.() -> Unit)? = null, + ) = showApkInfoDialog(context, apkFile, builderApplier, null) + + @JvmStatic + @SuppressLint("SetTextI18n") + fun showApkInfoDialog( + context: Context, + apkFile: File, + builderApplier: (MaterialDialog.Builder.() -> Unit)?, + onDismissListener: DialogInterface.OnDismissListener?, + ) { val binding = ApkFileInfoDialogItemsBinding.inflate(LayoutInflater.from(context)) // Create an independent Scope for the Dialog, bind its lifecycle with the Dialog. @@ -75,11 +90,16 @@ object ApkInfoDialogManager { .neutralColorRes(R.color.dialog_button_hint) .onNegative { materialDialog, _ -> materialDialog.dismiss() } .also { builder -> builderApplier?.invoke(builder) } - .show() + .build() .apply { makeTextCopyable { titleView } - setOnDismissListener { scope.cancel() } + setOnDismissListener { + scope.cancel() + onDismissListener?.onDismiss(this) + } } + .showAdaptive() + scope.launch { val apkInfoDeferred = async(Dispatchers.IO) { getApkInfo(apkFile) } diff --git a/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayManifestActivity.kt b/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayManifestActivity.kt index becf85d4..d776ea81 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayManifestActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayManifestActivity.kt @@ -5,6 +5,7 @@ import android.content.Intent import io.noties.prism4j.GrammarLocator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs6.R import java.io.File import java.util.regex.Pattern @@ -84,7 +85,7 @@ class DisplayManifestActivity : BaseDisplayContentActivity() { putExtra(PATH_IDENTIFIER_MANIFEST, manifestFile.path) putExtra(INTENT_IDENTIFIER_PERMISSIONS, usesPermissions.toTypedArray()) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { context.startActivity(it) } + }.startSafely(context) } private fun parsePermissionsFromManifest(manifestContent: CharSequence): Array { diff --git a/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayMediaInfoActivity.kt b/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayMediaInfoActivity.kt index 85012a5e..e7597ee9 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayMediaInfoActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/scripts/DisplayMediaInfoActivity.kt @@ -5,6 +5,7 @@ import android.content.Intent import io.noties.prism4j.GrammarLocator import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs6.R class DisplayMediaInfoActivity : BaseDisplayContentActivity() { @@ -27,10 +28,9 @@ class DisplayMediaInfoActivity : BaseDisplayContentActivity() { @JvmStatic fun launch(context: Context, mediaInfo: String) { - val intent = Intent(context, DisplayMediaInfoActivity::class.java) - intent.putExtra(INTENT_IDENTIFIER_MEDIA_INFO, mediaInfo) - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - context.startActivity(intent) + Intent(context, DisplayMediaInfoActivity::class.java).apply { + putExtra(INTENT_IDENTIFIER_MEDIA_INFO, mediaInfo) + }.startSafely(context) } } 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 d220d0ce..bf12fb66 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 @@ -13,6 +13,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.autojs.autojs.app.DialogUtils.showAdaptive import org.autojs.autojs.extension.MaterialDialogExtensions.makeTextCopyable import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableTextIfAbsent import org.autojs.autojs.external.fileprovider.AppFileProvider @@ -37,7 +38,7 @@ object EditableFileInfoDialogManager { MaterialDialog.Builder(context) .title(R.string.text_failed) .content(R.string.file_not_exist_or_readable) - .show() + .showAdaptive() return } val binding = EditableFileInfoDialogItemsBinding.inflate(LayoutInflater.from(context)) @@ -55,7 +56,7 @@ object EditableFileInfoDialogManager { .limitIconToDefaultSize() .positiveText(R.string.dialog_button_dismiss) .positiveColorRes(R.color.dialog_button_default) - .show() + .showAdaptive() .apply { makeTextCopyable { titleView } setOnDismissListener { scope.cancel() } diff --git a/app/src/main/java/org/autojs/autojs/ui/main/scripts/ExplorerFragment.kt b/app/src/main/java/org/autojs/autojs/ui/main/scripts/ExplorerFragment.kt index 8c54b86c..ef3e65b9 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/scripts/ExplorerFragment.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/scripts/ExplorerFragment.kt @@ -32,6 +32,7 @@ import org.autojs.autojs.ui.widget.ScrollAwareFABBehavior import org.autojs.autojs.util.IntentUtils import org.autojs.autojs.util.IntentUtils.SnackExceptionHolder import org.autojs.autojs.util.IntentUtils.ToastExceptionHolder +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar import org.autojs.autojs6.R import org.autojs.autojs6.databinding.FragmentExplorerBinding @@ -215,18 +216,17 @@ class ExplorerFragment : ViewPagerFragment(0), OnFloatingActionButtonClickListen override fun onClick(button: FloatingActionButton, pos: Int) { mExplorerView?.let { view -> + val ctx = context ?: return@let when (pos) { - 3 -> context?.startActivity( - Intent(context, ProjectConfigActivity::class.java) - .putExtra(ProjectConfigActivity.EXTRA_PARENT_DIRECTORY, view.currentPage.path) - .putExtra(ProjectConfigActivity.EXTRA_NEW_PROJECT, true) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - ) - 2 -> ScriptOperations(context, view, view.currentPage) + 3 -> Intent(ctx, ProjectConfigActivity::class.java) + .putExtra(ProjectConfigActivity.EXTRA_PARENT_DIRECTORY, view.currentPage.path) + .putExtra(ProjectConfigActivity.EXTRA_NEW_PROJECT, true) + .startSafely(ctx) + 2 -> ScriptOperations(ctx, view, view.currentPage) .importFile() - 1 -> ScriptOperations(context, view, view.currentPage) + 1 -> ScriptOperations(ctx, view, view.currentPage) .newFile() - 0 -> ScriptOperations(context, view, view.currentPage) + 0 -> ScriptOperations(ctx, view, view.currentPage) .newDirectory() else -> Unit } diff --git a/app/src/main/java/org/autojs/autojs/ui/main/scripts/MediaInfoDialogManager.kt b/app/src/main/java/org/autojs/autojs/ui/main/scripts/MediaInfoDialogManager.kt index 8c22bd00..29f9cbaa 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/scripts/MediaInfoDialogManager.kt +++ b/app/src/main/java/org/autojs/autojs/ui/main/scripts/MediaInfoDialogManager.kt @@ -2,6 +2,7 @@ package org.autojs.autojs.ui.main.scripts import android.annotation.SuppressLint import android.content.Context +import android.content.DialogInterface import android.view.LayoutInflater import android.view.View.MeasureSpec.UNSPECIFIED import android.widget.TextView @@ -16,6 +17,7 @@ import kotlinx.coroutines.async import kotlinx.coroutines.cancel import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.autojs.autojs.app.DialogUtils.showAdaptive import org.autojs.autojs.extension.MaterialDialogExtensions.makeTextCopyable import org.autojs.autojs.extension.MaterialDialogExtensions.setCopyableText import org.autojs.autojs.model.explorer.ExplorerItem @@ -32,8 +34,22 @@ object MediaInfoDialogManager { private const val MEDIA_INFO_ERROR_OPENING_FILE = "Error opening file..." @JvmStatic + @JvmOverloads @SuppressLint("SetTextI18n") - fun showMediaInfoDialog(context: Context, explorerItem: ExplorerItem) { + fun showMediaInfoDialog( + context: Context, + explorerItem: ExplorerItem, + builderApplier: (MaterialDialog.Builder.() -> Unit)? = null, + ) = showMediaInfoDialog(context, explorerItem, builderApplier, null) + + @JvmStatic + @SuppressLint("SetTextI18n") + fun showMediaInfoDialog( + context: Context, + explorerItem: ExplorerItem, + builderApplier: (MaterialDialog.Builder.() -> Unit)?, + onDismissListener: DialogInterface.OnDismissListener?, + ) { val binding = MediaFileInfoDialogItemsBinding.inflate(LayoutInflater.from(context)) // Create an independent Scope for the Dialog, bind its lifecycle with the Dialog. @@ -52,11 +68,16 @@ object MediaInfoDialogManager { .onNegative { materialDialog, _ -> materialDialog.dismiss() } .neutralText(R.string.ellipsis_six) .neutralColorRes(R.color.dialog_button_unavailable) - .show() + .also { builder -> builderApplier?.invoke(builder) } + .build() .apply { makeTextCopyable { titleView } - setOnDismissListener { scope.cancel() } + setOnDismissListener { + scope.cancel() + onDismissListener?.onDismiss(this) + } } + .showAdaptive() scope.launch { val mediaInfo = MediaInfo() diff --git a/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java b/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java index 5fdc0991..fa178977 100644 --- a/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java +++ b/app/src/main/java/org/autojs/autojs/ui/main/task/TaskListRecyclerView.java @@ -32,6 +32,7 @@ import org.autojs.autojs.timing.TimedTaskManager; import org.autojs.autojs.ui.timing.TimedTaskSettingActivity; import org.autojs.autojs.util.ColorUtils; import org.autojs.autojs.util.FileUtils; +import org.autojs.autojs.util.IntentUtils; import org.autojs.autojs6.R; import org.autojs.autojs6.databinding.ExplorerFirstCharIconBinding; import org.autojs.autojs6.databinding.TaskListRecyclerViewItemBinding; @@ -307,7 +308,7 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView { : TimedTaskSettingActivity.EXTRA_TASK_ID; Intent intent = new Intent(getContext(), TimedTaskSettingActivity.class) .putExtra(extra, task.getId()); - getContext().startActivity(intent); + IntentUtils.startSafely(intent, getContext()); } } } diff --git a/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java b/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java index f935b172..51934758 100644 --- a/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java +++ b/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java @@ -1070,7 +1070,7 @@ public class BuildActivity extends BaseActivity implements ApkBuilder.ProgressCa public static void launch(Context context, String extraSource) { Intent intent = new Intent(context, BuildActivity.class) .putExtra(BuildActivity.EXTRA_SOURCE, extraSource); - context.startActivity(intent); + IntentUtils.startSafely(intent, context); } } diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/AboutActivity.kt b/app/src/main/java/org/autojs/autojs/ui/settings/AboutActivity.kt index 98e166ff..a134e3df 100644 --- a/app/src/main/java/org/autojs/autojs/ui/settings/AboutActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/settings/AboutActivity.kt @@ -18,6 +18,7 @@ import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.common.NotAskAgainDialog import org.autojs.autojs.util.ClipboardUtils import org.autojs.autojs.util.DeviceUtils +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.BuildConfig import org.autojs.autojs6.R @@ -135,7 +136,7 @@ open class AboutActivity : BaseActivity() { } private fun launchDeveloperOptions() { - startActivity(Intent(this, DeveloperOptionsActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) + Intent(this, DeveloperOptionsActivity::class.java).startSafely(this) } private fun toastForFirstDeveloperIdentifier() { @@ -189,16 +190,14 @@ open class AboutActivity : BaseActivity() { private fun launchGithubIssuesPage() { Intent(Intent.ACTION_VIEW) .setData(getString(R.string.url_github_autojs6_issues).toUri()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { startActivity(it) } + .startSafely(this) } companion object { fun startActivity(context: Context) { Intent(context, AboutActivity::class.java) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { context.startActivity(it) } + .startSafely(context) } } diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/AboutAppAndDeveloperPreference.kt b/app/src/main/java/org/autojs/autojs/ui/settings/AboutAppAndDeveloperPreference.kt index 9c9b3032..1d76b13b 100644 --- a/app/src/main/java/org/autojs/autojs/ui/settings/AboutAppAndDeveloperPreference.kt +++ b/app/src/main/java/org/autojs/autojs/ui/settings/AboutAppAndDeveloperPreference.kt @@ -5,10 +5,10 @@ import android.content.Intent import android.net.Uri import android.text.util.Linkify import android.util.AttributeSet -import androidx.preference.Preference.SummaryProvider import com.afollestad.materialdialogs.DialogAction import com.afollestad.materialdialogs.MaterialDialog import org.autojs.autojs.theme.preference.MaterialPreference +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ViewUtils import org.autojs.autojs6.BuildConfig import org.autojs.autojs6.R @@ -42,22 +42,20 @@ class AboutAppAndDeveloperPreference : MaterialPreference { d?.getActionButton(DialogAction.NEUTRAL)!!.apply { setTextColor(context.getColor(R.color.dialog_button_hint)) setOnClickListener { - try { + when { Intent().apply { @Suppress("SpellCheckingInspection") data = Uri.parse( "mqqopensdkapi://bizAgent/qm/qr" + - "?" + "url" + "=" + "http%3A%2F%2Fqm.qq.com" + - "%2F" + "cgi-bin" + "%2F" + "qm" + "%2F" + "qr" + - "%3F" + "from" + "%3D" + "app" + - "%26" + "p" + "%3D" + "android" + - "%26" + "jump_from" + "%3D" + "webapi" + - "%26" + "k" + "%3D" + "6BH7HuJj29dwE0AIcUuxtAlK6NWlefmH" + "?" + "url" + "=" + "http%3A%2F%2Fqm.qq.com" + + "%2F" + "cgi-bin" + "%2F" + "qm" + "%2F" + "qr" + + "%3F" + "from" + "%3D" + "app" + + "%26" + "p" + "%3D" + "android" + + "%26" + "jump_from" + "%3D" + "webapi" + + "%26" + "k" + "%3D" + "6BH7HuJj29dwE0AIcUuxtAlK6NWlefmH" ) - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { context.startActivity(it) } - } catch (e: Exception) { - context.getString( + }.startSafely(context) -> Unit + else -> context.getString( R.string.error_app_not_installed_with_name, context.getString(R.string.app_name_qq), ).let { msg -> ViewUtils.showToast(context, msg, true) } diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/AppLanguagePreference.kt b/app/src/main/java/org/autojs/autojs/ui/settings/AppLanguagePreference.kt index c42aba6b..9bafdd5e 100644 --- a/app/src/main/java/org/autojs/autojs/ui/settings/AppLanguagePreference.kt +++ b/app/src/main/java/org/autojs/autojs/ui/settings/AppLanguagePreference.kt @@ -8,6 +8,7 @@ import org.autojs.autojs.app.GlobalAppContext import org.autojs.autojs.core.pref.Language import org.autojs.autojs.theme.preference.MaterialListPreference import org.autojs.autojs.ui.BaseActivity +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.LocaleUtils class AppLanguagePreference : MaterialListPreference { @@ -27,9 +28,7 @@ class AppLanguagePreference : MaterialListPreference { override fun onNeutral() { Intent(Intent.ACTION_MAIN).apply { setClassName("com.android.settings", "com.android.settings.LanguageSettings") - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - prefContext.startActivity(this) - } + }.startSafely(prefContext) } override fun onChangeConfirmed(dialog: MaterialDialog) { diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/DisplayVersionHistoriesActivity.kt b/app/src/main/java/org/autojs/autojs/ui/settings/DisplayVersionHistoriesActivity.kt index 5bbb1350..460dc7f8 100644 --- a/app/src/main/java/org/autojs/autojs/ui/settings/DisplayVersionHistoriesActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/settings/DisplayVersionHistoriesActivity.kt @@ -34,6 +34,7 @@ import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.settings.VersionHistoryRepository.Companion.Category import org.autojs.autojs.ui.settings.VersionHistoryRepository.Companion.DEFAULT_FILTER import org.autojs.autojs.ui.settings.VersionHistoryRepository.Companion.DEFAULT_VERSION_NAME +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.ProcessLogger import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar import org.autojs.autojs.util.ViewUtils.setMenuIconsColorByThemeColorLuminance @@ -250,9 +251,8 @@ class DisplayVersionHistoriesActivity : BaseActivity() { @JvmStatic fun launch(context: Context) { - Intent(context, DisplayVersionHistoriesActivity::class.java).apply { - addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - }.let { context.startActivity(it) } + Intent(context, DisplayVersionHistoriesActivity::class.java) + .startSafely(context) } class NoFadeItemAnimator : DefaultItemAnimator() { diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesActivity.kt b/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesActivity.kt index de7dc92e..82457e31 100644 --- a/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesActivity.kt +++ b/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesActivity.kt @@ -6,6 +6,7 @@ import android.os.Bundle import org.autojs.autojs.app.GlobalAppContext import org.autojs.autojs.theme.ThemeColorManager import org.autojs.autojs.ui.BaseActivity +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs6.R import org.autojs.autojs6.databinding.ActivityPreferencesBinding @@ -46,8 +47,7 @@ open class PreferencesActivity : BaseActivity() { @JvmOverloads fun launch(context: Context = GlobalAppContext.get()) { Intent(context, PreferencesActivity::class.java) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .let { context.startActivity(it) } + .startSafely(context) } } diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/ScheduledRestartSettingsDialogBuilder.kt b/app/src/main/java/org/autojs/autojs/ui/settings/ScheduledRestartSettingsDialogBuilder.kt index ac60beab..49a35b49 100644 --- a/app/src/main/java/org/autojs/autojs/ui/settings/ScheduledRestartSettingsDialogBuilder.kt +++ b/app/src/main/java/org/autojs/autojs/ui/settings/ScheduledRestartSettingsDialogBuilder.kt @@ -76,7 +76,6 @@ class ScheduledRestartSettingsDialogBuilder(context: Context) : MaterialDialog.B } mSeekBar.progress = (context.resources.getInteger(R.integer.scheduled_restart_start_delay_default_value) - mStartDelayMinValue) / 100 })) - autoDismiss(false) negativeText(R.string.dialog_button_cancel) negativeColorRes(R.color.dialog_button_default) onNegative { d, _ -> d.dismiss() } @@ -90,10 +89,11 @@ class ScheduledRestartSettingsDialogBuilder(context: Context) : MaterialDialog.B Pref.putInt(R.string.key_scheduled_restart_delay, mStartDelayMinValue + mSeekBar.progress * 100) d.dismiss() } + autoDismiss(false) } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { - binding.scheduledRestartStartDelayTitle.text = "$mScheduledRestartStartDelayTitlePrefix: ${mStartDelayMinValue + progress * 100}ms" + binding.scheduledRestartStartDelayTitle.text = context.getString(R.string.text_property_colon_value_unit, mScheduledRestartStartDelayTitlePrefix, mStartDelayMinValue + progress * 100, "ms") } override fun onStartTrackingTouch(seekBar: SeekBar) { diff --git a/app/src/main/java/org/autojs/autojs/ui/widget/CommonMarkdownView.kt b/app/src/main/java/org/autojs/autojs/ui/widget/CommonMarkdownView.kt index ecbb5e1c..b7e93307 100644 --- a/app/src/main/java/org/autojs/autojs/ui/widget/CommonMarkdownView.kt +++ b/app/src/main/java/org/autojs/autojs/ui/widget/CommonMarkdownView.kt @@ -10,6 +10,7 @@ import android.widget.FrameLayout import androidx.core.net.toUri import com.afollestad.materialdialogs.MaterialDialog import org.autojs.autojs.runtime.api.Mime +import org.autojs.autojs.util.IntentUtils.startSafely import org.autojs.autojs.util.TextUtils.markdownToHtml /** @@ -47,13 +48,13 @@ class CommonMarkdownView : WebView { } override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean { - context.startActivity(Intent(Intent.ACTION_VIEW).setData(request.url).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) + Intent(Intent.ACTION_VIEW).setData(request.url).startSafely(context) return true } @Deprecated("Deprecated in Java") override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean { - context.startActivity(Intent(Intent.ACTION_VIEW).setData(url.toUri()).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)) + Intent(Intent.ACTION_VIEW).setData(url.toUri()).startSafely(context) return true } } diff --git a/app/src/main/java/org/autojs/autojs/ui/widget/EWebView.java b/app/src/main/java/org/autojs/autojs/ui/widget/EWebView.java index a498a697..6ad721b0 100644 --- a/app/src/main/java/org/autojs/autojs/ui/widget/EWebView.java +++ b/app/src/main/java/org/autojs/autojs/ui/widget/EWebView.java @@ -2,7 +2,6 @@ package org.autojs.autojs.ui.widget; import android.annotation.SuppressLint; import android.app.Activity; -import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; @@ -17,20 +16,18 @@ import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.FrameLayout; import android.widget.ProgressBar; - import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; import org.autojs.autojs.app.OnActivityResultDelegate; import org.autojs.autojs.tool.ImageSelector; +import org.autojs.autojs.util.IntentUtils; import org.autojs.autojs6.R; import java.util.Arrays; import java.util.List; import java.util.concurrent.TimeUnit; -import io.reactivex.Observable; -import io.reactivex.android.schedulers.AndroidSchedulers; - /** * Created by Stardust on Aug 22, 2017. */ @@ -124,7 +121,7 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres public boolean openFileChooser(ValueCallback valueCallback, String[] acceptType) { if (getContext() instanceof OnActivityResultDelegate.DelegateHost && - getContext() instanceof Activity && isImageType(acceptType)) { + getContext() instanceof Activity && isImageType(acceptType)) { chooseImage(valueCallback); return true; } @@ -201,12 +198,7 @@ public class EWebView extends FrameLayout implements SwipeRefreshLayout.OnRefres if (intentActivities.isEmpty()) { return false; } - try { - getContext().startActivity(Intent.createChooser(intent, getResources().getString(R.string.text_open_with))); - } catch (ActivityNotFoundException e) { - e.printStackTrace(); - return false; - } + return IntentUtils.startSafely(Intent.createChooser(intent, getResources().getString(R.string.text_open_with)), getContext()); } return true; } diff --git a/app/src/main/java/org/autojs/autojs/util/IntentUtils.kt b/app/src/main/java/org/autojs/autojs/util/IntentUtils.kt index 1e04b4b6..345eb3d7 100644 --- a/app/src/main/java/org/autojs/autojs/util/IntentUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/IntentUtils.kt @@ -7,6 +7,7 @@ import android.content.Context import android.content.Context.ALARM_SERVICE import android.content.Intent import android.net.Uri +import android.os.Bundle import android.os.SystemClock import android.provider.OpenableColumns import android.provider.Settings @@ -59,6 +60,16 @@ object IntentUtils { onFailure?.invoke(t) }.isSuccess + @JvmStatic + @JvmOverloads + fun Intent.startSafelyWithOptions(context: Context, options: Bundle? = null, printStackTrace: Boolean = false, onFailure: ((Throwable) -> Unit)? = null): Boolean = + runCatching { + startWithOptions(context, options) + }.onFailure { t -> + if (printStackTrace) t.printStackTrace() + onFailure?.invoke(t) + }.isSuccess + @JvmStatic fun Intent.start(context: Context) { val activity = context.findActivity() @@ -70,6 +81,17 @@ object IntentUtils { } } + @JvmStatic + fun Intent.startWithOptions(context: Context, options: Bundle? = null) { + val activity = context.findActivity() + if (activity != null) { + activity.startActivity(this, options) + } else { + addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(this, options) + } + } + @Suppress("SpellCheckingInspection") fun chatWithQQ(context: Context, qq: String): Boolean { val uri = "mqqwpa://im/chat?chat_type=wpa&uin=$qq".toUri() diff --git a/app/src/main/java/org/autojs/autojs/util/NotificationUtils.kt b/app/src/main/java/org/autojs/autojs/util/NotificationUtils.kt index c1dc3b97..3a3ea06d 100644 --- a/app/src/main/java/org/autojs/autojs/util/NotificationUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/NotificationUtils.kt @@ -155,8 +155,7 @@ object NotificationUtils { @JvmStatic fun launchSettings() { - val localIntent = createAppNotificationIntent(globalAppContext) - globalAppContext.startActivity(localIntent) + createAppNotificationIntent(globalAppContext).startSafely(globalAppContext) } @JvmStatic diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2de04ce4..3bbc4c17 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -1191,5 +1191,6 @@ أعاد المكوّن الإضافي %1$s معلومات فارغة. أعاد المكوّن الإضافي %1$s variant غير صالح: %2$s. لم يتم العثور على موارد Paddle OCR المضمّنة. يُرجى إعادة الحزم مع تفعيل Paddle OCR. + تصغير diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 3573e2e1..f8e68bbf 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -1186,5 +1186,6 @@ %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 diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index a12608ad..b49812a1 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -1189,5 +1189,6 @@ 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 diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 0306cf66..ba4ebe22 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1189,5 +1189,6 @@ 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 diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c5853096..9222af04 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1190,5 +1190,6 @@ %1$s プラグインが空の info を返しました. %1$s プラグインが無効な variant を返しました: %2$s. 埋め込みの Paddle OCR assets が見つかりません. Paddle OCR を有効にして再パッケージしてください. + 最小化 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 4d5669d7..9e4731c7 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -1191,5 +1191,6 @@ %1$s 플러그인이 빈 info를 반환했습니다. %1$s 플러그인이 잘못된 variant를 반환했습니다: %2$s. 내장된 Paddle OCR assets를 찾을 수 없습니다. Paddle OCR을 활성화하여 다시 패키징해 주세요. + 최소화 diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5f24335e..e54cf590 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -1189,5 +1189,6 @@ Плагин %1$s вернул пустую информацию. Плагин %1$s вернул недопустимый variant: %2$s. Не найдены встроенные ресурсы Paddle OCR. Перепакуйте приложение с включённым Paddle OCR. + Свернуть diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 44238d76..66862b5d 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1187,5 +1187,6 @@ %1$s 插件返回的 info 為空. %1$s 插件返回的 variant 無效: %2$s. 未找到內置 Paddle OCR 資源, 請在打包時勾選並注入 Paddle OCR 後重試. + 最小化 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index bb113760..d11f06cb 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1187,5 +1187,6 @@ %1$s 外掛返回的 info 為空. %1$s 外掛返回的 variant 無效: %2$s. 未找到內建 Paddle OCR 資源, 請在打包時勾選並注入 Paddle OCR 後重試. + 最小化 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 803e4fc7..c8c07a6f 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1187,5 +1187,6 @@ %1$s 插件返回的 info 为空. %1$s 插件返回的 variant 无效: %2$s. 未找到内置 Paddle OCR 资源, 请在打包时勾选并注入 Paddle OCR 后重试. + Minimize diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1c76f74c..0adc30c8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1444,5 +1444,6 @@ %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 diff --git a/version.properties b/version.properties index 941f7e6d..24981f4b 100644 --- a/version.properties +++ b/version.properties @@ -1,5 +1,5 @@ -#Sun Jan 18 22:49:01 CST 2026 -BUILD_TIME=1768747741064 +#Tue Jan 20 15:19:53 CST 2026 +BUILD_TIME=1768893593849 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=3630 -VERSION_NAME=6.7.0 Alpha16 +VERSION_BUILD=3636 +VERSION_NAME=6.7.0 Alpha17 VSCODE_EXT_REQUIRED_VERSION=1.0.13