diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json index 4885cf2b..228158fa 100644 --- a/.changelog/lang_zh-Hans.json +++ b/.changelog/lang_zh-Hans.json @@ -1,7 +1,7 @@ { "$data": { "v6.7.0": { - "released_date": "2026/02/23", + "released_date": "2026/03/07", "feature": [ "插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮/主页标签页)", "版本历史功能, 支持查看/恢复可编辑文件的历史版本 (入口: 主页抽屉按钮/文件管理器菜单/代码编辑器菜单)", @@ -150,6 +150,8 @@ "代码编辑器 \"查找/替换\" 支持状态持久化及实时显示搜索计数信息", "代码编辑器提示保存时确保保存成功后再退出编辑器以降低保存失败率", "代码编辑器保存按钮的状态更符合用户主观逻辑", + "打包应用打包过程对话框增加 \"中止\" 按钮", + "打包应用打包过程对话框的显示方式并增加耗时统计", "打包应用页面默认勾选必要权限 (WAKE_LOCK/INTERNET/WRITE_EXTERNAL_STORAGE) _[`issue #397`](http://issues.autojs6.com/397)_", "打包应用设置页面增加前台服务开关 _[`issue #406`](http://issues.autojs6.com/406)_", "脚本项目配置文件保存时增加键名冲突检测机制防止键名歧义", diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 895c02a8..411bda6d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -167,13 +167,14 @@ + + - diff --git a/app/src/main/java/androidx/recyclerview/widget/ThemeColorRecyclerView.java b/app/src/main/java/androidx/recyclerview/widget/ThemeColorRecyclerView.java index 7b4e745a..895f87fa 100644 --- a/app/src/main/java/androidx/recyclerview/widget/ThemeColorRecyclerView.java +++ b/app/src/main/java/androidx/recyclerview/widget/ThemeColorRecyclerView.java @@ -3,34 +3,21 @@ package androidx.recyclerview.widget; import android.content.Context; import android.util.AttributeSet; import android.widget.EdgeEffect; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.widget.EdgeEffectCompat; import org.autojs.autojs.theme.ThemeColor; import org.autojs.autojs.theme.ThemeColorManager; import org.autojs.autojs.theme.ThemeColorMutable; -import java.lang.reflect.Field; - /** * Created by Stardust on Aug 14, 2016. - * Modified by SuperMonster003 as of Dec 1, 2021. + * Modified by JetBrains AI Assistant (GPT-5.3-Codex (xhigh)) as of Mar 6, 2026. + * Modified by SuperMonster003 as of Mar 6, 2026. */ public class ThemeColorRecyclerView extends RecyclerView implements ThemeColorMutable { private int mColorPrimary; - private Field mLeftGlowField; - private Field mTopGlowField; - private Field mRightGlowField; - private Field mBottomGlowField; - - private Field mEdgeEffectField; - - private boolean hasAppliedThemeColorLeft; - private boolean hasAppliedThemeColorTop; - private boolean hasAppliedThemeColorRight; - private boolean hasAppliedThemeColorBottom; - public ThemeColorRecyclerView(Context context) { super(context); init(); @@ -46,65 +33,17 @@ public class ThemeColorRecyclerView extends RecyclerView implements ThemeColorMu init(); } - private boolean applyThemeColor(Field edgeEffectCompatField) { - try { - EdgeEffectCompat edgeEffectCompat = (EdgeEffectCompat) edgeEffectCompatField.get(this); - if (edgeEffectCompat != null) { - return setEdgeEffectColor(edgeEffectCompat, mColorPrimary); - } - } catch (Exception ignored) { - /* Ignored. */ - } - return false; - } - private void init() { - try { - mEdgeEffectField = EdgeEffectCompat.class.getDeclaredField("mEdgeEffect"); - mEdgeEffectField.setAccessible(true); - mLeftGlowField = RecyclerView.class.getDeclaredField("mLeftGlow"); - mLeftGlowField.setAccessible(true); - mRightGlowField = RecyclerView.class.getDeclaredField("mRightGlow"); - mRightGlowField.setAccessible(true); - mTopGlowField = RecyclerView.class.getDeclaredField("mTopGlow"); - mTopGlowField.setAccessible(true); - mBottomGlowField = RecyclerView.class.getDeclaredField("mBottomGlow"); - mBottomGlowField.setAccessible(true); - } catch (Exception e) { - e.printStackTrace(); - } - - // android:fadeScrollbars="true" - // setScrollbarFadingEnabled(true); - - // android:scrollbarDefaultDelayBeforeFade="600" - // setScrollBarDefaultDelayBeforeFade(600); - - // android:scrollbarFadeDuration="500" - // setScrollBarFadeDuration(500); - - // android:scrollbars="vertical" - // setVerticalScrollBarEnabled(true); - - // To ensure scrollbar fading works properly. - // setFadingEdgeLength(0); - - ThemeColorManager.add(this); - } - - private boolean setEdgeEffectColor(EdgeEffectCompat compat, int color) { - if (compat == null) { - return false; - } - try { - EdgeEffect edgeEffect = (EdgeEffect) mEdgeEffectField.get(compat); - if (edgeEffect != null) { - edgeEffect.setColor(color); + setEdgeEffectFactory(new EdgeEffectFactory() { + @NonNull + @Override + protected EdgeEffect createEdgeEffect(@NonNull RecyclerView view, int direction) { + EdgeEffect edgeEffect = new EdgeEffect(view.getContext()); + edgeEffect.setColor(mColorPrimary); + return edgeEffect; } - } catch (Exception ignored) { - /* Ignored. */ - } - return true; + }); + ThemeColorManager.add(this); } @Override @@ -113,36 +52,7 @@ public class ThemeColorRecyclerView extends RecyclerView implements ThemeColorMu return; } mColorPrimary = color.colorPrimary; - invalidateGlows(); - } - - void invalidateGlows() { super.invalidateGlows(); - hasAppliedThemeColorLeft = false; - hasAppliedThemeColorTop = false; - hasAppliedThemeColorRight = false; - hasAppliedThemeColorBottom = false; - } - - void ensureLeftGlow() { - super.ensureLeftGlow(); - hasAppliedThemeColorLeft = hasAppliedThemeColorLeft || applyThemeColor(mLeftGlowField); - } - - void ensureTopGlow() { - super.ensureTopGlow(); - hasAppliedThemeColorTop = hasAppliedThemeColorTop || applyThemeColor(mTopGlowField); - - } - - void ensureRightGlow() { - super.ensureLeftGlow(); - hasAppliedThemeColorRight = hasAppliedThemeColorRight || applyThemeColor(mRightGlowField); - } - - void ensureBottomGlow() { - super.ensureBottomGlow(); - hasAppliedThemeColorBottom = hasAppliedThemeColorBottom || applyThemeColor(mBottomGlowField); } } diff --git a/app/src/main/java/com/stardust/autojs/core/util/ScriptPromiseAdapter.kt b/app/src/main/java/com/stardust/autojs/core/util/ScriptPromiseAdapter.kt index 3e116da5..e8dbaf91 100644 --- a/app/src/main/java/com/stardust/autojs/core/util/ScriptPromiseAdapter.kt +++ b/app/src/main/java/com/stardust/autojs/core/util/ScriptPromiseAdapter.kt @@ -44,6 +44,6 @@ class ScriptPromiseAdapter { } companion object { - private val UNSET = Object() + private val UNSET = Any() } } \ No newline at end of file diff --git a/app/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt b/app/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt index 458f706c..69f41203 100644 --- a/app/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt +++ b/app/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.kt @@ -156,7 +156,7 @@ open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Co override fun wrap(cx: Context, scope: Scriptable, obj: Any?, staticType: Class<*>?): Any? { return when { - obj is String -> runtime.bridges.toString(obj.toString()) + obj is String -> runtime.bridges.toString(obj) staticType == UiObjectCollection::class.java -> runtime.bridges.asArray(obj) else -> super.wrap(cx, scope, obj, staticType) } diff --git a/app/src/main/java/com/stardust/automator/simple_action/SearchUpTargetAction.kt b/app/src/main/java/com/stardust/automator/simple_action/SearchUpTargetAction.kt index 9212d909..fc5c8fc0 100644 --- a/app/src/main/java/com/stardust/automator/simple_action/SearchUpTargetAction.kt +++ b/app/src/main/java/com/stardust/automator/simple_action/SearchUpTargetAction.kt @@ -32,7 +32,7 @@ class SearchUpTargetAction(action: Int, filter: FilterAction.Filter) : SearchTar companion object { - private val TAG = SearchUpTargetAction::class.java!!.getSimpleName() + private val TAG = SearchUpTargetAction::class.java.getSimpleName() private val LOOP_MAX = 20 } } diff --git a/app/src/main/java/org/autojs/autojs/core/accessibility/UiSelector.kt b/app/src/main/java/org/autojs/autojs/core/accessibility/UiSelector.kt index de6b64dd..4a45ecc4 100644 --- a/app/src/main/java/org/autojs/autojs/core/accessibility/UiSelector.kt +++ b/app/src/main/java/org/autojs/autojs/core/accessibility/UiSelector.kt @@ -863,13 +863,17 @@ open class UiSelector : UiObjectActions, StringReadable { internal fun pick(scriptRuntime: ScriptRuntime) = Detector(compass, object : Result(resultType) { - override fun byOne() = selector?.let { sel -> - root?.let { return sel.findOneOf(it) } ?: sel.findOnce() + override fun byOne(): UiObject? { + return selector?.let { sel -> + root?.let { return sel.findOneOf(it) } ?: sel.findOnce() + } } - override fun byAll() = selector?.let { sel -> - root?.let { return sel.findOf(it) } ?: sel.find() - } ?: EMPTY + override fun byAll(): UiObjectCollection { + return selector?.let { sel -> + root?.let { return sel.findOf(it) } ?: sel.find() + } ?: EMPTY + } }, callback, selector).detect(scriptRuntime) 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 4cd0ae34..e79f3d3d 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 @@ -41,15 +41,17 @@ class StartForResultActivity : Activity() { } } if (extras == null) { - finish().also { return } + finish() + return } - val callback = extras!!.map["callback"] + val callback = extras.map["callback"] if (callback is Callback) { mCallback = callback } if (callback == null) { mCallback = null - finish().also { return } + finish() + return } mCallback!!.onActivityCreate(this) } diff --git a/app/src/main/java/org/autojs/autojs/core/pref/Language.kt b/app/src/main/java/org/autojs/autojs/core/pref/Language.kt index bde237ae..11897be2 100644 --- a/app/src/main/java/org/autojs/autojs/core/pref/Language.kt +++ b/app/src/main/java/org/autojs/autojs/core/pref/Language.kt @@ -23,7 +23,7 @@ enum class Language(@JvmField val languageTag: String, @KeyRes private val keyRe ; val locale: Locale = when (languageTag.isBlank()) { - true -> LocaleUtils.getSystemLocale() + true -> LocaleUtils.getPrimarySystemLocale() else -> Locale.forLanguageTag(languageTag) } @@ -39,7 +39,7 @@ enum class Language(@JvmField val languageTag: String, @KeyRes private val keyRe return languageTag } - val systemTag = LocaleUtils.getSystemLocale().toLanguageTag() + val systemTag = LocaleUtils.getPrimarySystemLocale().toLanguageTag() val availableTags = values().map { it.languageTag } if (systemTag in availableTags) { diff --git a/app/src/main/java/org/autojs/autojs/engine/RhinoJavaScriptEngine.kt b/app/src/main/java/org/autojs/autojs/engine/RhinoJavaScriptEngine.kt index f81f705d..f0d953c1 100644 --- a/app/src/main/java/org/autojs/autojs/engine/RhinoJavaScriptEngine.kt +++ b/app/src/main/java/org/autojs/autojs/engine/RhinoJavaScriptEngine.kt @@ -7,10 +7,6 @@ import android.util.Log import android.view.View import org.autojs.autojs.core.ui.ViewExtras import org.autojs.autojs.engine.module.AssetAndUrlModuleSourceProvider -import org.autojs.autojs.rhino.extension.AnyExtensions.isJsNullish -import org.autojs.autojs.rhino.extension.AnyExtensions.jsBrief -import org.autojs.autojs.rhino.extension.ScriptableExtensions.defineProp -import org.autojs.autojs.rhino.extension.ScriptableExtensions.prop import org.autojs.autojs.pio.PFiles import org.autojs.autojs.pio.UncheckedIOException import org.autojs.autojs.project.ScriptConfig @@ -18,6 +14,10 @@ import org.autojs.autojs.rhino.AndroidContextFactory import org.autojs.autojs.rhino.AutoJsContext import org.autojs.autojs.rhino.RhinoAndroidHelper import org.autojs.autojs.rhino.TopLevelScope +import org.autojs.autojs.rhino.extension.AnyExtensions.isJsNullish +import org.autojs.autojs.rhino.extension.AnyExtensions.jsBrief +import org.autojs.autojs.rhino.extension.ScriptableExtensions.defineProp +import org.autojs.autojs.rhino.extension.ScriptableExtensions.prop import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.api.augment.proxy.PaintProxyObject import org.autojs.autojs.script.JavaScriptSource @@ -42,7 +42,7 @@ import java.io.IOException import java.io.InputStreamReader import java.io.Reader import java.net.URI -import java.util.* +import java.util.Locale /** * Created by Stardust on Apr 2, 2017. @@ -215,9 +215,9 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con private inner class WrapFactory : AndroidContextFactory.WrapFactory() { override fun wrapAsJavaObject(cx: Context?, scope: Scriptable, javaObject: Any?, staticType: TypeInfo): Scriptable? { - return when (javaObject) { - is View -> ViewExtras.getNativeView(scope, /* view = */ javaObject, staticType.asClass(), runtime) - is Paint if Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> { + return when { + javaObject is View -> ViewExtras.getNativeView(scope, /* view = */ javaObject, staticType.asClass(), runtime) + javaObject is Paint && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> { // Use composition-based proxy to preserve Paint identity and intercept setColor only. // zh-CN: 使用组合式代理以保持 Paint 身份一致性, 且仅拦截 setColor. val base = super.wrapAsJavaObject(cx, scope, javaObject, staticType) ?: return null @@ -226,11 +226,12 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con else -> super.wrapAsJavaObject(cx, scope, javaObject, staticType) } } - } companion object { + private const val TAG = "RhinoJavaScriptEngine" + const val SOURCE_FILE_INIT = "init.js" const val SOURCE_NAME_INIT = "" const val MODULES_ROOT_PATH = "modules" @@ -238,9 +239,5 @@ open class RhinoJavaScriptEngine(private val androidContext: android.content.Con @JvmField val JS_BEAUTIFY_FILE = PFiles.join(JS_BEAUTIFY_PATH, "beautify.js") - - private val TAG = RhinoJavaScriptEngine::class.java.simpleName - } - } diff --git a/app/src/main/java/org/autojs/autojs/external/ScriptIntents.kt b/app/src/main/java/org/autojs/autojs/external/ScriptIntents.kt index a2e76a80..370ca71e 100644 --- a/app/src/main/java/org/autojs/autojs/external/ScriptIntents.kt +++ b/app/src/main/java/org/autojs/autojs/external/ScriptIntents.kt @@ -65,7 +65,7 @@ object ScriptIntents { JavaScriptFileSource(path).let { fss: JavaScriptFileSource -> source = script?.let { SequenceScriptSource(fss.name, StringScriptSource(it), fss) } ?: fss } - File(path!!).parent?.let { config.workingDirectory = it } + File(path).parent?.let { config.workingDirectory = it } } } source?.let { AutoJs.instance.scriptEngineService.execute(it, config) } diff --git a/app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt b/app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt index c41a2702..9fbb540e 100644 --- a/app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt +++ b/app/src/main/java/org/autojs/autojs/inrt/SettingsActivity.kt @@ -2,8 +2,10 @@ package org.autojs.autojs.inrt import android.os.Bundle import android.view.View +import android.widget.EdgeEffect import androidx.appcompat.app.AppCompatActivity import androidx.preference.PreferenceFragmentCompat +import androidx.recyclerview.widget.RecyclerView import org.autojs.autojs.runtime.api.Permissions import org.autojs.autojs.theme.preference.Syncable import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar @@ -67,11 +69,17 @@ class SettingsActivity : AppCompatActivity() { setDivider(null) setDividerHeight(0) + listView.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() { + override fun createEdgeEffect(recyclerView: RecyclerView, direction: Int): EdgeEffect { + return EdgeEffect(recyclerView.context).apply { + color = recyclerView.context.getColor(R.color.md_blue_gray_500) + } + } + } + listView.isHorizontalScrollBarEnabled = false listView.isVerticalScrollBarEnabled = false listView.excludePaddingClippableViewFromBottomNavigationBar() } - } - } 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 ad02e078..400cdb41 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 @@ -61,12 +61,13 @@ class AppUtils(context: Context, @get:ScriptInterface val fileProviderAuthority: * @param o < alias | packageName > */ @ScriptInterface - fun launchPackage(o: String?) = runCatching { - o ?: return false - val nicePackageName = getAppByAlias(alias = o)?.packageName ?: (/* packageName = */ o) - val intent = mPackageManager.getLaunchIntentForPackage(nicePackageName) ?: return false - intent.start(mContext) - }.isSuccess + fun launchPackage(o: String?): Boolean = + runCatching { + o ?: return false + val nicePackageName = getAppByAlias(alias = o)?.packageName ?: (/* packageName = */ o) + val intent = mPackageManager.getLaunchIntentForPackage(nicePackageName) ?: return false + intent.start(mContext) + }.isSuccess @ScriptInterface @Suppress("unused") diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/device/Device.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/device/Device.kt index 8b57c6b5..3166c911 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/device/Device.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/device/Device.kt @@ -122,14 +122,14 @@ class Device(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { @JvmStatic @RhinoFunctionBody fun vibrateRhinoWithRuntime(scriptRuntime: ScriptRuntime, o: Any?, p: Any?) { - when (o) { - is String -> { + when { + o is String -> { MorseCode.vibrateRhino(o, p) } - is Number if p is Number -> { + o is Number && p is Number -> { scriptRuntime.device.vibrate(/* off = */ o.toLong(), /* millis = */ p.toLong()) } - is NativeArray if p is Number -> { + o is NativeArray && p is Number -> { val listOff = listOf(p.toLong()) val listOthers = o.map { toVibrateTimingElement(it) } val timings = (listOff + listOthers).toLongArray() diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/dialogs/Dialogs.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/dialogs/Dialogs.kt index 262585e0..15cc3556 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/dialogs/Dialogs.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/dialogs/Dialogs.kt @@ -494,15 +494,16 @@ class Dialogs(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { } private fun applyDialogProperty(builder: JsDialogBuilder, name: String, value: Any?) { - when (val propertySetter = propertySetterMap[name]) { - PropertyConverter.COLOR_INT -> { + val propertySetter = propertySetterMap[name] + when { + propertySetter == PropertyConverter.COLOR_INT -> { val colorInt = Colors.toIntRhino(value) invokeJavaMethod(builder, name, arrayOf(colorInt)) } - PropertyConverter.BOOLEAN if coerceBoolean(value, false) -> { + propertySetter == PropertyConverter.BOOLEAN && coerceBoolean(value, false) -> { invokeJavaMethod(builder, name, emptyArray()) } - is String -> when (propertySetter) { + propertySetter is String -> when (propertySetter) { in propertySetterMap -> { applyDialogProperty(builder, propertySetter, value) } diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/images/Images.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/images/Images.kt index 9e5d0737..eb373580 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/images/Images.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/images/Images.kt @@ -1494,7 +1494,7 @@ class Images(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime), AsEmitt val similarityMethod = runCatching { ImageSimilarity::class.java.getDeclaredMethod(metric, OpencvMat::class.java, OpencvMat::class.java) }.getOrElse { throw WrappedIllegalArgumentException("Unknown similarity metric: $metric") } - if (similarityMethod.returnType != Double::class.java && similarityMethod.returnType != java.lang.Double::class.java) { + if (similarityMethod.returnType != Double::class.java) { throw WrappedIllegalArgumentException("Similarity metric ($metric) method must return Double type. Found: ${similarityMethod.returnType}") } similarityMethod.invoke(ImageSimilarity, matA, matB) as Double diff --git a/app/src/main/java/org/autojs/autojs/runtime/api/augment/util/Inspect.kt b/app/src/main/java/org/autojs/autojs/runtime/api/augment/util/Inspect.kt index f84a538b..d1bf789b 100644 --- a/app/src/main/java/org/autojs/autojs/runtime/api/augment/util/Inspect.kt +++ b/app/src/main/java/org/autojs/autojs/runtime/api/augment/util/Inspect.kt @@ -587,9 +587,7 @@ object Inspect : Augmentable(), Invokable { private fun formatProperty(ctx: Ctx, value: ScriptableObject, recurseTimes: Int?, visibleKeys: NativeObject, key: String, array: Boolean): String { var name: String? = null - val desc = js_object_getOwnPropertyDescriptor(value, key) ?: newNativeObject().apply { - put("value", this, value.prop(key)) - } + val desc = js_object_getOwnPropertyDescriptor(value, key) val getter = desc.prop(PROXY_GETTER_KEY) val setter = desc.prop(PROXY_SETTER_KEY) diff --git a/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorHorizontalScrollView.java b/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorHorizontalScrollView.java index fd561ac2..f61537f0 100644 --- a/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorHorizontalScrollView.java +++ b/app/src/main/java/org/autojs/autojs/theme/widget/ThemeColorHorizontalScrollView.java @@ -1,10 +1,11 @@ package org.autojs.autojs.theme.widget; +import android.annotation.SuppressLint; import android.content.Context; +import android.os.Build; import android.util.AttributeSet; import android.widget.EdgeEffect; import android.widget.HorizontalScrollView; - import org.autojs.autojs.theme.ThemeColor; import org.autojs.autojs.theme.ThemeColorManager; import org.autojs.autojs.theme.ThemeColorMutable; @@ -60,17 +61,23 @@ public class ThemeColorHorizontalScrollView extends HorizontalScrollView impleme invalidate(); } + @SuppressLint("DiscouragedPrivateApi") private void syncEdgeEffect() { - try { - Field f1 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowLeft"); - f1.setAccessible(true); - f1.set(this, mEdgeGlowLeft); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + setLeftEdgeEffectColor(mFadingEdgeColor); + setRightEdgeEffectColor(mFadingEdgeColor); + } else { + try { + Field f1 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowLeft"); + f1.setAccessible(true); + f1.set(this, mEdgeGlowLeft); - Field f2 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowRight"); - f2.setAccessible(true); - f2.set(this, mEdgeGlowRight); - } catch (Exception e) { - e.printStackTrace(); + Field f2 = HorizontalScrollView.class.getDeclaredField("mEdgeGlowRight"); + f2.setAccessible(true); + f2.set(this, mEdgeGlowRight); + } catch (Exception e) { + e.printStackTrace(); + } } } } 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 50da5b4c..dd0401e3 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 @@ -1080,7 +1080,7 @@ public class ScriptOperations { // zh-CN: 删除操作使用不确定进度条即可, 行为更稳定. MaterialDialog.Builder builder = new MaterialDialog.Builder(mContext) .title(titleRes) - .content(R.string.text_deleting) + .content(mContext.getString(R.string.text_deleting) + mContext.getString(R.string.text_half_ellipsis)) .negativeText(R.string.dialog_button_abort) .negativeColorRes(R.color.dialog_button_caution) .onNegative((dialog, which) -> { diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.kt b/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.kt index 7b27ec37..326eccc7 100644 --- a/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.kt +++ b/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.kt @@ -8,6 +8,7 @@ import android.content.ContextWrapper import android.content.Intent import android.content.IntentFilter import android.database.Cursor +import android.graphics.Color import android.graphics.Rect import android.net.Uri import android.os.Build @@ -1328,8 +1329,8 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag mNormalToolbar.apply { setOnMenuItemClickListener(this@EditorView) setOnMenuItemLongClickListener { id -> - when (id) { - R.id.run if !mReadOnly -> true.also { debug() } + when { + id == R.id.run && !mReadOnly -> true.also { debug() } else -> false } } @@ -1338,8 +1339,8 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag (existing as? ToolbarFragment<*>)?.apply { setOnMenuItemClickListener(this@EditorView) setOnMenuItemLongClickListener { id -> - when (id) { - R.id.run if !mReadOnly -> true.also { debug() } + when { + id == R.id.run && !mReadOnly -> true.also { debug() } else -> false } } @@ -1513,7 +1514,12 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag mCodeCompletionBar.setTextColor(textColor) mSymbolBar.setTextColor(textColor) mShowFunctionsButton.setColorFilter(textColor) - ViewUtils.setNavigationBarBackgroundColor(activity, imeBarBackgroundColor) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + ViewUtils.setNavigationBarBackgroundColor(activity, imeBarBackgroundColor) + } else { + val adjustedImageContrastColor = ColorUtils.adjustColorForContrast(Color.WHITE, ColorUtils.applyAlpha(imeBarBackgroundColor, 1.0), 2.3) + ViewUtils.setNavigationBarBackgroundColor(activity, adjustedImageContrastColor) + } invalidate() } } @@ -2683,7 +2689,7 @@ class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFrag private const val MIN_CONFIDENCE_TO_WRITE_FILE = 90 private val DEFAULT_CHARSET_TO_WRITE_FILE = StandardCharsets.UTF_8 - private const val LARGE_FILE_MODE_THRESHOLD = JavaScriptHighlighter.MAX_HIGHLIGHT_CHARS + private const val LARGE_FILE_MODE_THRESHOLD = JavaScriptHighlighter.MAX_HIGHLIGHT_CHARS // Internal storage root (no external SD). // zh-CN: 内部存储根目录 (不访问外置 SD). diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditText.kt b/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditText.kt index 2e80e020..77b0cd4c 100644 --- a/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditText.kt +++ b/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditText.kt @@ -597,11 +597,14 @@ class CodeEditText : AppCompatEditText { runCatching { event.text.clear() } runCatching { event.contentDescription = null } - // Also drop selection-changed events entirely in large-text mode. - // zh-CN: 大文本模式下直接丢弃 selection-changed 事件. - if (event.eventType == AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED) return - if (event.eventType == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) return - if (event.eventType == AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY) return + // Also drop selection-changed events entirely in large-text mode to avoid TransactionTooLargeException. + // zh-CN: 大文本模式下直接丢弃 selection-changed 事件以避免 TransactionTooLargeException. + when (event.eventType) { + AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED -> return + AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED -> return + AccessibilityEvent.TYPE_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY -> return + else -> Unit + } } super.sendAccessibilityEventUnchecked(event) } diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.kt b/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.kt index c1c9eb98..92648edd 100644 --- a/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.kt +++ b/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.kt @@ -178,7 +178,7 @@ class CodeEditor : HVScrollView { if (mProcessDialog?.isShowing == true) return@Runnable mProcessDialog = MaterialDialog.Builder(context) - .content(R.string.text_processing) + .content(R.string.text_in_progress) // Text only, no progress spinner. // zh-CN: 仅显示文字, 不使用进度圆圈动画. .cancelable(false) diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/keyboard/SymbolsConfigStore.kt b/app/src/main/java/org/autojs/autojs/ui/edit/keyboard/SymbolsConfigStore.kt index ae18d8e2..bccedf0d 100644 --- a/app/src/main/java/org/autojs/autojs/ui/edit/keyboard/SymbolsConfigStore.kt +++ b/app/src/main/java/org/autojs/autojs/ui/edit/keyboard/SymbolsConfigStore.kt @@ -225,7 +225,7 @@ object SymbolsConfigStore { fun getAllDefaultNameAliases(context: Context): Set { val appLang = Language.getPrefLanguageOrNull() val appKey = appLang?.languageTag ?: "null" - val sysKey = LocaleUtils.getSystemLocale().toLanguageTag() + val sysKey = LocaleUtils.getPrimarySystemLocale().toLanguageTag() val cacheKey = "app=$appKey|sys=$sysKey" sDefaultAliasesCache[cacheKey]?.let { return it } diff --git a/app/src/main/java/org/autojs/autojs/ui/floating/layoutinspector/NodeInfoView.kt b/app/src/main/java/org/autojs/autojs/ui/floating/layoutinspector/NodeInfoView.kt index e1154b0f..af4b828a 100644 --- a/app/src/main/java/org/autojs/autojs/ui/floating/layoutinspector/NodeInfoView.kt +++ b/app/src/main/java/org/autojs/autojs/ui/floating/layoutinspector/NodeInfoView.kt @@ -184,7 +184,7 @@ class NodeInfoView : RecyclerView { } } return when (NodeInfo::class.java.getDeclaredField(attr).type) { - java.lang.String::class.java -> "$attr('$value')" + String::class.java -> "$attr('$value')" else -> "$attr($value)" } } diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesFragment.kt b/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesFragment.kt index 4f8fcfef..e641351f 100644 --- a/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesFragment.kt +++ b/app/src/main/java/org/autojs/autojs/ui/settings/PreferencesFragment.kt @@ -2,7 +2,10 @@ package org.autojs.autojs.ui.settings import android.os.Bundle import android.view.View +import android.widget.EdgeEffect import androidx.preference.PreferenceFragmentCompat +import androidx.recyclerview.widget.RecyclerView +import org.autojs.autojs.theme.ThemeColorManager import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar import org.autojs.autojs6.R @@ -14,9 +17,15 @@ class PreferencesFragment : PreferenceFragmentCompat() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + listView.edgeEffectFactory = object : RecyclerView.EdgeEffectFactory() { + override fun createEdgeEffect(recyclerView: RecyclerView, direction: Int): EdgeEffect { + return EdgeEffect(recyclerView.context).apply { + color = ThemeColorManager.colorPrimary + } + } + } listView.isHorizontalScrollBarEnabled = false listView.isVerticalScrollBarEnabled = false listView.excludePaddingClippableViewFromBottomNavigationBar() } - -} \ No newline at end of file +} diff --git a/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt b/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt index 8c54020f..ba3b3287 100644 --- a/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/ColorUtils.kt @@ -384,10 +384,8 @@ object ColorUtils { ) @JvmStatic - fun applyAlpha(@ColorInt color: Int, alpha: Double): Int = when (alpha) { - 1.0 -> color - else -> ColorUtils.setAlphaComponent(color, (alpha * 255).roundToInt()) - } + fun applyAlpha(@ColorInt color: Int, alpha: Double): Int = + ColorUtils.setAlphaComponent(color, (alpha * 255).roundToInt()) /** * Calculate the contrast ratio between two colors using the W3C WCAG formula. diff --git a/app/src/main/java/org/autojs/autojs/util/FileUtils.kt b/app/src/main/java/org/autojs/autojs/util/FileUtils.kt index ec19d7d3..1f2afe58 100644 --- a/app/src/main/java/org/autojs/autojs/util/FileUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/FileUtils.kt @@ -3091,16 +3091,17 @@ object FileUtils { }.getOrElse { false } @JvmStatic - fun File.isBinDiscImageLike() = runCatching { - this@isBinDiscImageLike.inputStream().use { inputStream -> - val header = ByteArray(2048) // Read first sector - if (inputStream.read(header) != header.size) return false + fun File.isBinDiscImageLike(): Boolean = + runCatching { + this@isBinDiscImageLike.inputStream().use { inputStream -> + val header = ByteArray(2048) // Read first sector + if (inputStream.read(header) != header.size) return false - // Check for very basic ISO 9660 primary volume descriptor - val pvdDescriptor = "CD001".toByteArray() - header.sliceArray(0x800 until 0x800 + pvdDescriptor.size).contentEquals(pvdDescriptor) - } - }.getOrElse { false } + // Check for very basic ISO 9660 primary volume descriptor + val pvdDescriptor = "CD001".toByteArray() + header.sliceArray(0x800 until 0x800 + pvdDescriptor.size).contentEquals(pvdDescriptor) + } + }.getOrElse { false } // Determines if a CUE file describes audio tracks @JvmStatic @@ -3168,17 +3169,26 @@ object FileUtils { }.getOrElse { false } @JvmStatic - fun File.isSegaMDLike() = runCatching { - this@isSegaMDLike.inputStream().use { inputStream -> - val header = ByteArray(512) // 假设 SEGA 游戏文件有特定的头部 - if (inputStream.read(header) != header.size) return false + fun File.isSegaMDLike(): Boolean = + runCatching { + this@isSegaMDLike.inputStream().use { inputStream -> + // Assume SEGA game files have a specific header. + // zh-CN: 假设 SEGA 游戏文件有特定的头部. + val header = ByteArray(512) + if (inputStream.read(header) != header.size) return false - // 这里你需要根据 SEGA 文件的具体特征来调整条件 - // 例如: 找到特定的标识符或者模式 - val segaIdentifier = byteArrayOf(0x53, 0x45, 0x47, 0x41) // 可能的 "SEGA" 标记 - header.sliceArray(segaIdentifier.indices).contentEquals(segaIdentifier) - } - }.getOrElse { false } + // Here is the modification needed to adjust the conditions based on specific SEGA file characteristics. + // This requires identifying specific identifiers or patterns within the header. + // zh-CN: + // 这里需要根据 SEGA 文件的具体特征来调整条件. + // 例如: 找到特定的标识符或者模式. + + // Possible "SEGA" marker. + // zh-CN: 可能的 "SEGA" 标记. + val segaIdentifier = byteArrayOf(0x53, 0x45, 0x47, 0x41) + header.sliceArray(segaIdentifier.indices).contentEquals(segaIdentifier) + } + }.getOrElse { false } // Function to check if a file is likely a macro based on scripting patterns found in samples @JvmStatic diff --git a/app/src/main/java/org/autojs/autojs/util/LocaleUtils.kt b/app/src/main/java/org/autojs/autojs/util/LocaleUtils.kt index b9059933..e90d7739 100644 --- a/app/src/main/java/org/autojs/autojs/util/LocaleUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/LocaleUtils.kt @@ -38,18 +38,41 @@ object LocaleUtils { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { context.getSystemService(LocaleManager::class.java).applicationLocales = LocaleList.getEmptyLocaleList() } else { - setLocale(context, getSystemLocale()) + setLocale(context, getPrimarySystemLocale()) } } @JvmStatic + @Deprecated("Use getSystemLocaleList instead", ReplaceWith("getPrimarySystemLocale()")) fun getSystemLocale(): Locale = Resources.getSystem().configuration.locales[0] ?: Locale.getDefault() + @JvmStatic + @JvmOverloads + fun getSystemLocaleList(context: Context? = null): List { + return when { + Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { + val localeManager = (context ?: GlobalAppContext.get()).getSystemService(LocaleManager::class.java) + val localeList: LocaleList = localeManager.systemLocales + List(localeList.size()) { index -> localeList[index] } + } + else -> { + val localeList = Resources.getSystem().configuration.locales + List(localeList.size()) { index -> localeList[index] } + } + } + } + + @JvmStatic + @JvmOverloads + fun getPrimarySystemLocale(context: Context? = null): Locale { + return getSystemLocaleList(context).firstOrNull() ?: Locale.getDefault() + } + @JvmStatic fun getResources(desiredLocale: Locale?): Resources { return GlobalAppContext.get().let { context -> context.resources.configuration.let { Configuration(it) }.run { - setLocale(desiredLocale ?: getSystemLocale()) + setLocale(desiredLocale ?: getPrimarySystemLocale()) context.createConfigurationContext(this).resources } } diff --git a/app/src/main/java/org/autojs/autojs/util/MathUtils.kt b/app/src/main/java/org/autojs/autojs/util/MathUtils.kt index 7cc06267..9cd6ad30 100644 --- a/app/src/main/java/org/autojs/autojs/util/MathUtils.kt +++ b/app/src/main/java/org/autojs/autojs/util/MathUtils.kt @@ -1,15 +1,25 @@ -package org.autojs.autojs.util; +package org.autojs.autojs.util /** * Created by Stardust on Nov 26, 2017. + * Transformed by SuperMonster003 on Mar 5, 2026. + * Modified by SuperMonster003 as of Mar 5, 2026. */ -public class MathUtils { +object MathUtils { - public static int min(int... ints) { - int min = ints[0]; - for (int i = 1; i < ints.length; i++) { - min = Math.min(ints[i], min); - } - return min; - } + @JvmStatic + fun min(vararg ints: Int): Int = + ints.minOrNull() ?: throw NoSuchElementException("Array is empty") + + @JvmStatic + fun Int.floorMod(mod: Int): Int = + Math.floorMod(this, mod) + + @JvmStatic + fun Long.floorMod(mod: Long): Long = + Math.floorMod(this, mod) + + @JvmStatic + fun Long.floorMod(mod: Int): Int = + Math.floorMod(this, mod) } diff --git a/app/src/main/res/layout/activity_apps_icon_select.xml b/app/src/main/res/layout/activity_apps_icon_select.xml index 0c48a142..f93a7ead 100644 --- a/app/src/main/res/layout/activity_apps_icon_select.xml +++ b/app/src/main/res/layout/activity_apps_icon_select.xml @@ -22,7 +22,7 @@ - diff --git a/app/src/main/res/layout/activity_display_release_history.xml b/app/src/main/res/layout/activity_display_release_history.xml index 13702047..36b605fd 100644 --- a/app/src/main/res/layout/activity_display_release_history.xml +++ b/app/src/main/res/layout/activity_display_release_history.xml @@ -46,7 +46,7 @@ - - diff --git a/app/src/main/res/layout/activity_symbols_settings.xml b/app/src/main/res/layout/activity_symbols_settings.xml index 15cafc53..e54c4ebf 100644 --- a/app/src/main/res/layout/activity_symbols_settings.xml +++ b/app/src/main/res/layout/activity_symbols_settings.xml @@ -105,7 +105,7 @@ android:layout_height="0dp" android:layout_weight="1"> - diff --git a/app/src/main/res/layout/activity_trash.xml b/app/src/main/res/layout/activity_trash.xml index 11daf44f..a25ab66e 100644 --- a/app/src/main/res/layout/activity_trash.xml +++ b/app/src/main/res/layout/activity_trash.xml @@ -35,7 +35,7 @@ tools:visibility="gone" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - diff --git a/app/src/main/res/layout/activity_version_history.xml b/app/src/main/res/layout/activity_version_history.xml index 11daf44f..a25ab66e 100644 --- a/app/src/main/res/layout/activity_version_history.xml +++ b/app/src/main/res/layout/activity_version_history.xml @@ -35,7 +35,7 @@ tools:visibility="gone" app:layout_behavior="@string/appbar_scrolling_view_behavior"> - diff --git a/app/src/main/res/layout/bubble_popup_menu.xml b/app/src/main/res/layout/bubble_popup_menu.xml index 5ee41b10..fb2b0b0f 100644 --- a/app/src/main/res/layout/bubble_popup_menu.xml +++ b/app/src/main/res/layout/bubble_popup_menu.xml @@ -13,7 +13,7 @@ android:layout_gravity="center_horizontal" android:background="@drawable/little_triangle" /> - - - - diff --git a/app/src/main/res/layout/dialog_class_search.xml b/app/src/main/res/layout/dialog_class_search.xml index f3eb7d03..9a4885c8 100644 --- a/app/src/main/res/layout/dialog_class_search.xml +++ b/app/src/main/res/layout/dialog_class_search.xml @@ -23,7 +23,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - diff --git a/app/src/main/res/layout/dialog_list_view.xml b/app/src/main/res/layout/dialog_list_view.xml index c7ceeeee..202d29cd 100644 --- a/app/src/main/res/layout/dialog_list_view.xml +++ b/app/src/main/res/layout/dialog_list_view.xml @@ -4,7 +4,7 @@ android:layout_height="match_parent" android:orientation="vertical"> - diff --git a/app/src/main/res/layout/explorer_view.xml b/app/src/main/res/layout/explorer_view.xml index 447f7f02..aea52b6c 100644 --- a/app/src/main/res/layout/explorer_view.xml +++ b/app/src/main/res/layout/explorer_view.xml @@ -14,7 +14,7 @@ app:cardElevation="0.97dp" app:cardUseCompatPadding="true" /> - diff --git a/app/src/main/res/layout/fragment_drawer.xml b/app/src/main/res/layout/fragment_drawer.xml index e9a5e7f1..511073df 100644 --- a/app/src/main/res/layout/fragment_drawer.xml +++ b/app/src/main/res/layout/fragment_drawer.xml @@ -13,7 +13,7 @@ android:importantForAccessibility="no" android:orientation="vertical"> - - - diff --git a/modules/material-dialogs/src/main/java/com/afollestad/materialdialogs/internal/MDTintHelper.java b/modules/material-dialogs/src/main/java/com/afollestad/materialdialogs/internal/MDTintHelper.java index bef430b2..6e6bd2bd 100644 --- a/modules/material-dialogs/src/main/java/com/afollestad/materialdialogs/internal/MDTintHelper.java +++ b/modules/material-dialogs/src/main/java/com/afollestad/materialdialogs/internal/MDTintHelper.java @@ -139,7 +139,7 @@ public class MDTintHelper { fCursorDrawable.set(editor, drawables); } catch (NoSuchFieldException e1) { Log.d("MDTintHelper", "Device issue with cursor tinting: " + e1.getMessage()); - e1.printStackTrace(); + // e1.printStackTrace(); } catch (Exception e2) { e2.printStackTrace(); }