6.7.0 - Alpha14 - 新增 device.setPointerLocation 等 Toggleablle 系列方法, 用于设置或获取指针位置系统设置项 (issue #381)

This commit is contained in:
SuperMonster003
2026-01-10 19:08:19 +08:00
parent e01f010e46
commit 59fe480254
4 changed files with 87 additions and 6 deletions

View File

@@ -13,6 +13,7 @@
"s13n.bytes 方法, 用于标准化字节数据 (参阅 项目文档 > [标准化](https://docs.autojs6.com/#/s13n))", "s13n.bytes 方法, 用于标准化字节数据 (参阅 项目文档 > [标准化](https://docs.autojs6.com/#/s13n))",
"app.isDualInstalled 方法, 用于检测双开应用是否已安装 (需要 Shizuku 或 Root 权限) _[`issue #450`](http://issues.autojs6.com/450)_", "app.isDualInstalled 方法, 用于检测双开应用是否已安装 (需要 Shizuku 或 Root 权限) _[`issue #450`](http://issues.autojs6.com/450)_",
"device.getSharedDeviceId 方法, 用于跨应用获取统一共享设备 ID _[`issue #455`](http://issues.autojs6.com/455)_", "device.getSharedDeviceId 方法, 用于跨应用获取统一共享设备 ID _[`issue #455`](http://issues.autojs6.com/455)_",
"device.setPointerLocation 等 Toggleablle 系列方法, 用于设置或获取指针位置系统设置项 _[`issue #381`](http://issues.autojs6.com/381)_",
"ui.getNavigationBarHeight 方法/navigationBarHeight 属性 (getter), 用于获取导航栏高度 _[`issue #456`](http://issues.autojs6.com/456)_", "ui.getNavigationBarHeight 方法/navigationBarHeight 属性 (getter), 用于获取导航栏高度 _[`issue #456`](http://issues.autojs6.com/456)_",
"ui.getVisible(Status/Navigation)BarHeight 方法/visible(Status/Navigation)BarHeight 属性 (getter), 用于快捷获取状态栏或导航栏可见高度 _[`issue #456`](http://issues.autojs6.com/456)_", "ui.getVisible(Status/Navigation)BarHeight 方法/visible(Status/Navigation)BarHeight 属性 (getter), 用于快捷获取状态栏或导航栏可见高度 _[`issue #456`](http://issues.autojs6.com/456)_",
"http 模块请求相关方法获取的 body 对象增加 stream/saveToFile/close 等方法 _[`issue #452`](http://issues.autojs6.com/452)_", "http 模块请求相关方法获取的 body 对象增加 stream/saveToFile/close 等方法 _[`issue #452`](http://issues.autojs6.com/452)_",

View File

@@ -1,10 +1,14 @@
package org.autojs.autojs.runtime.api.augment.device package org.autojs.autojs.runtime.api.augment.device
import android.provider.Settings
import androidx.core.net.toUri
import org.autojs.autojs.annotation.RhinoFunctionBody import org.autojs.autojs.annotation.RhinoFunctionBody
import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface import org.autojs.autojs.annotation.RhinoRuntimeFunctionInterface
import org.autojs.autojs.extension.AnyExtensions.isJsNullish import org.autojs.autojs.extension.AnyExtensions.isJsNullish
import org.autojs.autojs.extension.AnyExtensions.jsBrief import org.autojs.autojs.extension.AnyExtensions.jsBrief
import org.autojs.autojs.extension.FlexibleArray import org.autojs.autojs.extension.FlexibleArray
import org.autojs.autojs.extension.FlexibleArray.Companion.component1
import org.autojs.autojs.extension.FlexibleArray.Companion.component2
import org.autojs.autojs.runtime.ScriptRuntime import org.autojs.autojs.runtime.ScriptRuntime
import org.autojs.autojs.runtime.api.ScreenMetrics import org.autojs.autojs.runtime.api.ScreenMetrics
import org.autojs.autojs.runtime.api.augment.Augmentable import org.autojs.autojs.runtime.api.augment.Augmentable
@@ -14,12 +18,14 @@ import org.autojs.autojs.runtime.exception.WrappedIllegalArgumentException
import org.autojs.autojs.util.DeviceUtils import org.autojs.autojs.util.DeviceUtils
import org.autojs.autojs.util.NetworkUtils import org.autojs.autojs.util.NetworkUtils
import org.autojs.autojs.util.RhinoUtils.UNDEFINED import org.autojs.autojs.util.RhinoUtils.UNDEFINED
import org.autojs.autojs.util.RhinoUtils.coerceBoolean
import org.autojs.autojs.util.ShellUtils
import org.autojs.autojs.util.ShellUtils.PointerLocation
import org.mozilla.javascript.Context import org.mozilla.javascript.Context
import org.mozilla.javascript.NativeArray import org.mozilla.javascript.NativeArray
import org.mozilla.javascript.Undefined import org.mozilla.javascript.Undefined
import java.util.function.Supplier import java.util.function.Supplier
import org.autojs.autojs.runtime.api.Device as ApiDevice import org.autojs.autojs.runtime.api.Device as ApiDevice
import androidx.core.net.toUri
@Suppress("unused", "UNUSED_PARAMETER") @Suppress("unused", "UNUSED_PARAMETER")
class Device(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) { class Device(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
@@ -38,6 +44,13 @@ class Device(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
::isConnectedOrConnecting.name, ::isConnectedOrConnecting.name,
::isWifiAvailable.name, ::isWifiAvailable.name,
::getSharedDeviceId.name, ::getSharedDeviceId.name,
::setPointerLocation.name,
::setPointerLocationEnabled.name,
::setPointerLocationDisabled.name,
::isPointerLocationEnabled.name,
::isPointerLocationDisabled.name,
::togglePointerLocation.name,
) )
override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>( override val selfAssignmentGetters = listOf<Pair<String, Supplier<Any?>>>(
@@ -50,6 +63,8 @@ class Device(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
companion object : FlexibleArray() { companion object : FlexibleArray() {
const val KEY_POINTER_LOCATION = "pointer_location"
@JvmStatic @JvmStatic
@RhinoRuntimeFunctionInterface @RhinoRuntimeFunctionInterface
fun summary(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) { fun summary(scriptRuntime: ScriptRuntime, args: Array<out Any?>): String = ensureArgumentsIsEmpty(args) {
@@ -211,6 +226,70 @@ class Device(scriptRuntime: ScriptRuntime) : Augmentable(scriptRuntime) {
?: throw WrappedIllegalArgumentException("Argument $it cannot be converted as a timing element for device.${::vibrate.name}") ?: throw WrappedIllegalArgumentException("Argument $it cannot be converted as a timing element for device.${::vibrate.name}")
} }
@JvmStatic
@RhinoRuntimeFunctionInterface
fun setPointerLocation(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsOnlyOne(args) {
val enabled = coerceBoolean(it, false)
// @Hint by SuperMonster003 on Jan 10, 2025.
// ! Starting from Android API 23 (6.0) [M], in the android.provider.Settings.System source code,
// ! `PRIVATE_SETTINGS.add(POINTER_LOCATION);` means that `POINTER_LOCATION` is not settable,
// ! otherwise it will trigger an exception:
// ! "java.lang.IllegalArgumentException: You cannot change private secure settings.".
// ! zh-CN:
// ! Android API 23 (6.0) [M] 起, android.provider.Settings.System 源码中,
// ! `PRIVATE_SETTINGS.add(POINTER_LOCATION);` 意味着 `POINTER_LOCATION` 是不可设置的,
// ! 否则会触发异常: "java.lang.IllegalArgumentException: You cannot change private secure settings.".
// !
// # if (SettingsCompat.canWriteSettings(globalContext)) {
// # try {
// # if (Settings.System.putInt(globalContext.contentResolver, KEY_POINTER_LOCATION, if (enabled) PointerLocation.ENABLED.value else PointerLocation.DISABLED.value)) {
// # return@ensureArgumentsOnlyOne true
// # }
// # } catch (e: Exception) {
// # if (e.message == null || !e.message!!.lowercase().contains("private secure settings")) {
// # e.printStackTrace()
// # }
// # }
// # }
ShellUtils.checkPointerLocationState(globalContext, enabled) || ShellUtils.togglePointerLocation(globalContext)
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun setPointerLocationEnabled(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsIsEmpty(args) {
setPointerLocation(scriptRuntime, arrayOf(true))
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun setPointerLocationDisabled(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsIsEmpty(args) {
setPointerLocation(scriptRuntime, arrayOf(false))
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun isPointerLocationEnabled(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsIsEmpty(args) {
try {
Settings.System.getInt(globalContext.contentResolver, KEY_POINTER_LOCATION, PointerLocation.DISABLED.value) == PointerLocation.ENABLED.value
} catch (e: Exception) {
ShellUtils.checkPointerLocationState(globalContext, true)
}
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun isPointerLocationDisabled(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsIsEmpty(args) {
!isPointerLocationEnabled(scriptRuntime, args)
}
@JvmStatic
@RhinoRuntimeFunctionInterface
fun togglePointerLocation(scriptRuntime: ScriptRuntime, args: Array<out Any?>): Boolean = ensureArgumentsIsEmpty(args) {
setPointerLocation(scriptRuntime, arrayOf(!isPointerLocationEnabled(scriptRuntime, args)))
}
} }
} }

View File

@@ -20,7 +20,8 @@ object ShellUtils {
} }
} }
private fun checkPointerLocationState(context: Context, aimState: Boolean) = when (aimState) { @JvmStatic
fun checkPointerLocationState(context: Context, aimState: Boolean) = when (aimState) {
true -> isPointerLocationEnabled(context) true -> isPointerLocationEnabled(context)
else -> isPointerLocationDisabled(context) else -> isPointerLocationDisabled(context)
} }
@@ -54,7 +55,7 @@ object ShellUtils {
WrappedShizuku.execCommand(context, command) WrappedShizuku.execCommand(context, command)
}.isSuccess }.isSuccess
private enum class PointerLocation(val value: Int) { enum class PointerLocation(val value: Int) {
ENABLED(1), ENABLED(1),
DISABLED(0) DISABLED(0)
} }

View File

@@ -1,5 +1,5 @@
#Fri Jan 09 23:39:38 CST 2026 #Sat Jan 10 19:06:16 CST 2026
BUILD_TIME=1767973178586 BUILD_TIME=1768043176049
COMPILE_SDK_VERSION=36 COMPILE_SDK_VERSION=36
IMAGE_QUANT_CMAKE_VERSION=3.22.1 IMAGE_QUANT_CMAKE_VERSION=3.22.1
IMAGE_QUANT_NDK_VERSION=26.1.10909125 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 RAPID_OCR_OPENCV_MOBILE_VERSION=4.5.3
TARGET_SDK_VERSION=36 TARGET_SDK_VERSION=36
TARGET_SDK_VERSION_INRT=29 TARGET_SDK_VERSION_INRT=29
VERSION_BUILD=3591 VERSION_BUILD=3593
VERSION_NAME=6.7.0 Alpha14 VERSION_NAME=6.7.0 Alpha14
VSCODE_EXT_REQUIRED_VERSION=1.0.13 VSCODE_EXT_REQUIRED_VERSION=1.0.13