【问题标题】:AccessibilityService dispatched gesture stops when user touch the screen当用户触摸屏幕时,AccessibilityService 调度的手势停止
【发布时间】:2021-12-22 01:00:58
【问题描述】:

我正在尝试使用 AccessibilityService 制作一个自动点击应用程序。我使用方法 dispatchGesture 和 AccessibilityService.GestureResultCallback 来执行点击屏幕并在 onCompleted() 中重复它。问题是如果我在手势完成之前触摸屏幕,手势就会取消(onCancelled 被触发)。如何防止屏幕触摸停止我的手势?

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.falcon.autoclick">

<application
    android:name=".base.App"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.AutoClick">
    <activity android:name=".ManageConfigActivity" />
    <activity android:name=".TestActivity" />
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service
        android:name=".FloatingMenu"
        android:enabled="true"
        android:exported="false" />
    <service
        android:name=".AutoService"
        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/global_action_bar_service" />
    </service>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />

</manifest>

@xml/global_action_bar_service

<?xml version="1.0" encoding="utf-8"?>
<accessibility-service 
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagDefault"
android:canPerformGestures="true"
android:description="@string/app_name"
android:notificationTimeout="100"
android:settingsActivity=".MainActivity" />

AutoService.java

public static final String EXTRA_ACTION = "auto_service_action";
public static final String ACTION_START_AUTO = "start_auto_click";
public static final String ACTION_STOP_AUTO = "stop_auto_click";
public static final String EXTRA_TARGET = "extra_target";

private Handler handler;
private IntervalRunnable runnable;
private CountDownTimer startTimer;
private CountDownTimer endTimer;

@Override
public void onCreate() {
    super.onCreate();
    HandlerThread handlerThread = new HandlerThread("auto-handler");
    handlerThread.start();
    handler = new Handler(handlerThread.getLooper());
}

 @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    String action = intent.getAction();
    if (action != null) {
        if (action.equals(ACTION_START_AUTO)) {
            Target target = (Target) intent.getSerializableExtra(EXTRA_TARGET);
            runnable = new IntervalRunnable(target);
            handler.postDelayed(runnable, 100);
        } else if (action.equals(ACTION_STOP_AUTO)) {
            stopAuto();
        }
    }
    return super.onStartCommand(intent, flags, startId);
}

private void stopAuto() {
    if (startTimer != null) {
        startTimer.cancel();
    }
    if (endTimer != null) {
        endTimer.cancel();
    }
    handler.removeCallbacks(runnable);
    runnable = null;
}

private void startSingleTarget(Target target) {
    dispatchGesture(getGestureDescription(target), new AccessibilityService.GestureResultCallback() {
        @Override
        public void onCompleted(GestureDescription gestureDescription) {
            super.onCompleted(gestureDescription);
            LogUtil.d("stopwatch", "gesture completed");

            startTimer = new CountDownTimer(target.getDelayTime(), 1000) {
                @Override
                public void onTick(long l) {

                }

                @Override
                public void onFinish() {
                    handler.post(runnable);
                }
            }.start();
        }

        @Override
        public void onCancelled(GestureDescription gestureDescription) {
            super.onCancelled(gestureDescription);
            LogUtil.d("testttttt", "gesture cancelled");
        }
    }, null);
}

private GestureDescription getGestureDescription(Target target) {
    long duration = 0;
    GestureDescription.Builder gestureBuilder = new GestureDescription.Builder();
    Path path = new Path();
    path.moveTo(target.getCenterStartX(), target.getCenterStartY());
    if (target.isSwipe()) {
        path.lineTo(target.getCenterEndX(), target.getCenterEndY());
        duration = target.getSwipeDuration();
    } else {
        duration = target.getClickDuration();
    }

    gestureBuilder.addStroke(new GestureDescription.StrokeDescription(path,
            0,
            duration));
    return gestureBuilder.build();
}

private class IntervalRunnable implements Runnable {
    private Target target;

    public IntervalRunnable(Target target) {
        this.target = target;
    }

    @Override
    public void run() {
        startSingleTarget(target);
    }
}

【问题讨论】:

  • 你解决了吗?另外,有没有办法调度关键事件?

标签: android accessibilityservice


【解决方案1】:

如何防止屏幕触摸停止我的手势?

dispatchGesture 无法做到这一点。来自官方documentation 关于dispatchGesture向触摸屏发送手势。当前正在进行的任何手势,无论是来自用户、此服务还是其他服务,都将被取消。因此,用户可以取消由您的服务调度的手势。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多