You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AccessibilityService中dispatchGesture始终返回false问题求助

排查AccessibilityService dispatchGesture返回false的问题

以下是针对你的问题的具体排查和修复步骤:

1. 修正手势StrokeDescription的参数

你当前的手势仅包含moveTo动作,系统可能无法识别为有效的触摸事件。模拟点击需要明确的按下-抬起动作,修改手势代码如下:

fun clickAt(x: Int, y: Int): Boolean {
    val gestureBuilder = GestureDescription.Builder()
    val path = Path()
    // 移动到目标坐标,然后保持在该点(模拟按下动作)
    path.moveTo(x.toFloat(), y.toFloat())
    path.lineTo(x.toFloat(), y.toFloat())
    // 构造StrokeDescription:路径、延迟执行时间、手势时长、是否为最后一笔
    val stroke = GestureDescription.StrokeDescription(path, 0, 100L, true)
    gestureBuilder.addStroke(stroke)
    val gesture = gestureBuilder.build()

    return dispatchGesture(gesture, object : GestureResultCallback() {
        override fun onCompleted(gestureDescription: GestureDescription) {
            Log.d("Gesture", "点击完成")
            super.onCompleted(gestureDescription)
        }

        override fun onCancelled(gestureDescription: GestureDescription) {
            Log.d("Gesture", "点击被取消")
            super.onCancelled(gestureDescription)
        }
    }, null)
}

关键点:

  • 增加lineTo到同一坐标,让系统识别为触摸按下动作
  • 将手势时长从1L改为100L(毫秒),避免时长过短被系统忽略

2. 确认Android版本兼容性

dispatchGesture是Android 7.0(API 24)才引入的API,若测试设备系统版本低于该版本,调用会直接返回false。请确保测试设备系统版本≥API 24。

3. 检查服务活跃状态

在你的TextReaderAccessibilityService中添加onDestroy日志,确认服务未被系统意外销毁:

override fun onDestroy() {
    Log.d("AccessibilityService", "服务已销毁")
    super.onDestroy()
}

若服务频繁被销毁,需排查是否因内存不足或厂商后台限制导致,可将应用加入系统后台白名单。

4. 关闭触摸探索模式

你的配置中开启了canRequestTouchExplorationMode,该模式下系统会接管触摸事件,可能干扰手势执行。在onServiceConnected中关闭该模式:

override fun onServiceConnected() {
    super.onServiceConnected()
    val serviceInfo = serviceInfo
    // 移除触摸探索模式标志
    serviceInfo.flags = serviceInfo.flags and AccessibilityServiceInfo.FLAG_REQUEST_TOUCH_EXPLORATION_MODE.inv()
    setServiceInfo(serviceInfo)
}

5. 避免主线程外调用dispatchGesture

AccessibilityService的方法必须在主线程执行,若通过Flutter MethodChannel调用,需确保在主线程处理:

MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "your_channel_name")
    .setMethodCallHandler { call, result ->
        if (call.method == "clickAt") {
            val x = call.argument<Int>("x") ?: 0
            val y = call.argument<Int>("y") ?: 0
            // 切换到主线程执行手势
            Handler(Looper.getMainLooper()).post {
                val success = clickAt(x, y)
                result.success(success)
            }
        } else {
            result.notImplemented()
        }
    }

6. 简化accessibilityservice.xml配置

你的配置中accessibilityEventTypes存在重复项(typeAllMask已包含其他类型),简化配置避免潜在冲突:

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:canPerformGestures="true"
    android:accessibilityEventTypes="typeAllMask"
    android:notificationTimeout="300"
    android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews|flagRequestEnhancedWebAccessibility|flagReportViewIds"
    android:canRetrieveWindowContent="true"
    android:settingsActivity="com.example.macroexternal.SettingsActivity"
    android:canRequestTouchExplorationMode="true">
</accessibility-service>

7. 排查厂商ROM限制

部分国产厂商(小米、华为等)对辅助服务有额外限制,需在系统设置中:

  • 确认应用的“辅助功能”权限已完全开启
  • 开启“允许模拟手势”或相关权限(不同厂商路径不同)
  • 将应用加入后台保护白名单,避免被系统杀死

内容的提问来源于stack exchange,提问作者Denis Trifanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 18:57:45