我使用以下代码以编程方式单击屏幕。但它就是行不通。我在 Android 13 和 Android 14 调试版和发布版上进行了测试
class ClickAccessibilityService : AccessibilityService() {
override fun onAccessibilityEvent(event: AccessibilityEvent?) {
// Log accessibility events
Log.d("ClickService", "Accessibility Event: ${event?.eventType}")
}
override fun onInterrupt() {
// Handle interruptions if needed
}
override fun onServiceConnected() {
super.onServiceConnected()
Log.d("ClickService", "Service Connected")
}
fun clickAtPosition(x: Int, y: Int){
val clickPath = Path()
clickPath.moveTo(x.toFloat(), y.toFloat())
val clickStroke = StrokeDescription(clickPath, 0, 1)
val clickBuilder = GestureDescription.Builder()
clickBuilder.addStroke(clickStroke)
dispatchGesture(clickBuilder.build(), null, null)
}
}
在执行代码之前授予可访问权限。这是清单文件中有关它的部分:
<service
android:name=".customutils.ClickAccessibilityService"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>
调用代码如下:
val accessibilityService = ClickAccessibilityService()
accessibilityService.clickAtPosition(result.x.toInt(), result.y.toInt())
println("click")
accessibility_service_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
android:canPerformGestures="true"
android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews"
android:settingsActivity="com.example.ba.SettingsActivity" />
我觉得这个方法已经不管用了还是什么。
在发送手势时,有两件事需要注意。首先是您用于调度手势的路径和为执行点击提供的时间。 基本问题在下面几行。代码应该修改如下:
fun clickAtPosition(x: Int, y: Int){
val clickPath = Path()
clickPath.moveTo(x.toFloat(), y.toFloat())
//Here we are adding one pixel to the y value so as the give a click some range on where to click.
clickPath.lineTo(x.toFloat(), y.toFloat() + 1)
//When providing Stroke Description you should add non zero start time and time for gesture.
val clickStroke = StrokeDescription(clickPath, 50, 50)
我们需要在路径中添加一条lineTo语句,因为当使用moveTo时,它将路径的原点移动到该点,但不存在任何路径。因此我们在语句中添加一条线,它是从y值到y的路径+ 1 值,本质上是在某种意义上单击一下。
时间的第二个问题是为什么使用50毫秒作为开始时间。这是手势发送到屏幕之前的持续时间。这为屏幕提供了充足的时间来完全处理先前的渲染并开始单击。 50 毫秒的手势时间是完成单击的时间。 使用低于 200 毫秒(我们通常用作长按阈值)的时间是一个不错的值。
因此,假设您已正确设置辅助功能服务,以下更改将使其正常工作。