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

AccessibilityService中dispatchGesture始终返回false,无法触发屏幕点击如何解决?

AccessibilityService调用dispatchGesture返回false无法点击的解决方案

问题描述

在SDK API 31环境下,自定义的AccessibilityService(类名FloatingButton)调用dispatchGesture方法始终返回false,无法发起屏幕点击操作。相关代码、Manifest配置及无障碍服务配置如下:

服务核心代码

public class FloatingButton extends AccessibilityService {
    private WindowManager windowManager;
    private ImageView shotButton;
    private int[] passMark = {100, 100};
    private int[] shotMark = {200, 200};

    @Override
    public void onInterrupt() {}

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {}

    @Override
    public void onCreate() {
        super.onCreate();

        shotButton = new ImageView(this);
        shotButton.setImageResource(R.drawable.activate);
        windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
        final WindowManager.LayoutParams shotButtonParams = getLayoutParams();
        shotButtonParams.x = 0;
        shotButtonParams.y = 100;

        windowManager.addView(shotButton, shotButtonParams);

        try {
            OnTouchListener shotButtonOnTouchListener = getShotButtonOnTouchListener(shotButtonParams);
            OnClickListener shotButtonOnClickListener = getShotButtonOnClickListener();

            shotButton.setOnClickListener(shotButtonOnClickListener);
            shotButton.setOnTouchListener(shotButtonOnTouchListener);
        } catch (Exception exception) {
            Log.e("SuperShot", exception.getMessage());
        }
    }

    private WindowManager.LayoutParams getLayoutParams() {
        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT
        );

        layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
        return layoutParams;
    }

    private OnClickListener getShotButtonOnClickListener() {
        return new OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("SuperShot", "Coordinate pass: " + String.valueOf(passMark[0]) + ", " + String.valueOf(passMark[1]));
                Log.d("SuperShot", "Coordinate shot: " + String.valueOf(shotMark[0]) + ", " + String.valueOf(shotMark[1]));

                click(passMark[0], passMark[1]);
            }
        };
    }

    private void click(int x, int y) {
        Path path = new Path();
        path.moveTo(x, y);

        StrokeDescription clickStroke = new StrokeDescription(path, 0, 10);
        GestureDescription.Builder clickBuilder = new GestureDescription.Builder();
        clickBuilder.addStroke(clickStroke);
        GestureDescription gesture = clickBuilder.build();
        boolean result = this.dispatchGesture(gesture, null, null);
        Log.d("SuperShot", String.valueOf(result));
    }
}

Manifest配置

<service
    android:name="com.example.shots.FloatingButton"
    android:foregroundServiceType="specialUse"
    android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
    android:exported="false">
    <intent-filter>
        <action android:name="android.accessibilityservice.AccessibilityService" />
    </intent-filter>
    <meta-data
        android:name="android.accessibilityservice"
        android:resource="@xml/config_accessibility_service" />
</service>

无障碍服务配置(config_accessibility_service.xml)

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackAllMask"
    android:accessibilityFlags="flagDefault"
    android:canPerformGestures="true" />

可能的原因及解决办法

  • 无障碍服务未手动开启
    无障碍服务必须由用户在系统设置中手动启用,仅配置权限没用。打开系统设置→无障碍→找到你的应用服务,确认已开启。

  • 手势路径未模拟完整点击动作
    当前代码只调用了path.moveTo(x,y),没有模拟按下+抬起的完整点击流程,系统识别不了是点击动作。修改click方法,补充完整的手势时序:

    private void click(int x, int y) {
        Path path = new Path();
        path.moveTo(x, y);
        // 按下动作:0ms开始,持续50ms
        StrokeDescription downStroke = new StrokeDescription(path, 0, 50);
        // 抬起动作:50ms开始,持续50ms(坐标不变,模拟松开)
        StrokeDescription upStroke = new StrokeDescription(path, 50, 50);
        
        GestureDescription.Builder builder = new GestureDescription.Builder();
        builder.addStroke(downStroke).addStroke(upStroke);
        boolean result = dispatchGesture(builder.build(), null, null);
        Log.d("SuperShot", String.valueOf(result));
    }
    
  • 服务初始化时机错误
    当前在onCreate中初始化悬浮窗和事件,但onCreate时无障碍服务可能还未完全绑定到系统,此时调用dispatchGesture会失效。把初始化逻辑移到onServiceConnected方法(无障碍服务成功绑定后才会触发):

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        // 这里初始化悬浮窗和点击事件
        shotButton = new ImageView(this);
        shotButton.setImageResource(R.drawable.activate);
        windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
        final WindowManager.LayoutParams shotButtonParams = getLayoutParams();
        shotButtonParams.x = 0;
        shotButtonParams.y = 100;
        windowManager.addView(shotButton, shotButtonParams);
        
        try {
            OnTouchListener shotButtonOnTouchListener = getShotButtonOnTouchListener(shotButtonParams);
            OnClickListener shotButtonOnClickListener = getShotButtonOnClickListener();
            shotButton.setOnClickListener(shotButtonOnClickListener);
            shotButton.setOnTouchListener(shotButtonOnTouchListener);
        } catch (Exception exception) {
            Log.e("SuperShot", exception.getMessage());
        }
    }
    

    同时删除onCreate中的对应初始化代码。

  • 悬浮窗权限未授予
    悬浮窗使用TYPE_APPLICATION_OVERLAY,需要动态申请SYSTEM_ALERT_WINDOW权限,且用户要在设置中允许应用显示悬浮窗。检查权限是否已获取,未获取的话添加权限申请逻辑。

  • 无障碍配置权限不足
    修改config_accessibility_service.xml,补充更全面的权限标志,确保服务具备手势操作的权限:

    <?xml version="1.0" encoding="utf-8"?>
    <accessibility-service
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:accessibilityEventTypes="typeAllMask"
        android:accessibilityFeedbackType="feedbackAllMask"
        android:accessibilityFlags="flagDefault|flagIncludeNotImportantViews|flagRequestTouchExplorationMode"
        android:canPerformGestures="true" />
    
  • API 31的特殊限制
    Android 12对无障碍服务的手势操作有更严格的管控,确保应用的目标SDK版本为31或更高。另外,若不需要前台服务,可移除android:foregroundServiceType="specialUse"属性,避免不必要的权限冲突。


内容的提问来源于stack exchange,提问作者КИТ KIT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 11:45:53