1

I did auto clicker using dispatchGesture and everything is working but when I touch the screen using my finger it stop and call onCancelled method

The Service

public class MyService extends AccessibilityService {

    private Path path;
    private GestureDescription.Builder builder;
    private GestureDescription.StrokeDescription strokeDescription;
    private GestureResultCallback gestureResultCallback;
    private GestureDescription gestureDescription;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent.getBooleanExtra("isClicked", false)) {
            clickOnPosition();
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {

    }

    @Override
    public void onInterrupt() {

    }

    private void clickOnPosition() {
        if (path == null) {
            path = new Path();
            path.moveTo(540, 960);
            path.lineTo(540, 960);
        }
        if (builder == null)
            builder = new GestureDescription.Builder();
        if (strokeDescription == null) {
            strokeDescription = new GestureDescription.StrokeDescription(path, 0, 500);
            builder.addStroke(strokeDescription);
        }
        if (gestureResultCallback == null)
            gestureResultCallback = new GestureResultCallback() {
                @Override
                public void onCompleted(GestureDescription gestureDescription) {
                    clickOnPosition();
                }

                @Override
                public void onCancelled(GestureDescription gestureDescription) {
                    super.onCancelled(gestureDescription);
                }
            };
        if (gestureDescription == null)
            gestureDescription = builder.build();
        dispatchGesture(gestureDescription, gestureResultCallback, null);
    }

}

Button In MainActivity

public void click(View view) {
    if (intent == null) {
        intent = new Intent(this, MyService.class);
        intent.putExtra("isClicked", true);
        startService(intent);
    }
}

And about code is it good code or there is a better way to do this one???

Taha Sami
  • 1,565
  • 1
  • 16
  • 43

1 Answers1

2

I'm very surprised that you are starting AccessibilityService by own (in click method)... this kind of Service must be enabled, allowed and started by system automatically, check out how to declare this in HERE. without that process (system auto-start, not own call) AccessibilityService will probably behave like usual Service, causing no permission for executing dispatchGesture (and all other sensitive methods call), also some custom AccessibilityService methods won't be ever called, like overriden, but empty onAccessibilityEvent(...)

snachmsm
  • 17,866
  • 3
  • 32
  • 74
  • Yes I should check if the user enabled accessibility permission but the code above for test only before starting to build the real app – Taha Sami Feb 18 '21 at 11:57
  • I spent two weeks understanding AccessibilityService class and I master it now well because you helped me before but the problem now when I touch the screen the dispatchGesture is canceling, I didn't find anything about this problem in the documentation – Taha Sami Feb 18 '21 at 12:09
  • at first: you just can't start `AccessibilityService` by own, thats for shure. when you do that it behaves like usual `Service` and don't have proper permissions for touching screen on any point at any time. system will start your `AccessibilityService` when you enable it in settings. so remove all `startService()` occurences from your code, these are just wrong – snachmsm Feb 18 '21 at 12:44
  • I have 2 buttons, First button to check if the accessibility permission is enabled or no, if was no, I move him to accessibility settings to enable permission. About the second button I made it for start auto clicker after checking. So I don't want to start auto-click directly after enabling the permission. But I want when pressing on the second button. – Taha Sami Feb 18 '21 at 13:13
  • `AccessibilityService` is started by system when it is enabled by user and is working always, even when your app is killed, you just can't start it by own, how many times I must repeat that? you may leave some flag, `static` in `Service` class or in `SharedPreferences`, which disables functionality of this service, but it is still running always as long as is enabled in proper settings - this flag check/uncheck you may implement in `click` method, but your service is alive no matter of that flag – snachmsm Feb 18 '21 at 13:36
  • and `AccessibilityService` started in "your way" behaves just like usual `Service` and doesn't have proper perms for touching screen. nuff said, I've nothing to add, if my answer isn't proper or doesn't satisfy you then just wait for another one – snachmsm Feb 18 '21 at 13:38
  • just put some `Log.i()` in methods `onCreate()` or `onServiceConnected()` and observe what will happen when you enable and disable this `Service` in proper options. they will fire when enabled, and will also fire when you run manually, but then it will behave just like "usual" `Service` as `AccessibilityService` `extends` it directly – snachmsm Feb 18 '21 at 17:36
  • `AccessibilityService` ([source](https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/accessibilityservice/AccessibilityService.java)) implements some methods which can be called only by system (when OS start this service then it bound to it). note that `onCancelled` is called in two places when gesture success and successful execution will be called only when this service is properly bounded to OS service and proper `mCaller` will be created by `IBinder` – snachmsm Feb 18 '21 at 17:43
  • I'm trying to check if the accessibility is enabled or no but using [isEnabled](https://developer.android.com/reference/android/view/accessibility/AccessibilityManager#isEnabled()) method. Can you tell me what this method does? – Taha Sami Feb 25 '21 at 15:36
  • afaik returns info about state in system settings, is enabled or not (so it is working on not). worth note that when you are ofteny reinstalling your app when service is enabled/running then sometimes system may "stuck" on "enabled state" (`isEnabled` returns `true`), but not re-running service after app reinstallation. and then even toggling in settings isn't restarting service. I've met this situation plenty of times on at least two devices, only device reboot was helping – snachmsm Feb 25 '21 at 17:21
  • Appreciate your cooperation with me to understand accessibility, Thanks Sir. – Taha Sami Feb 25 '21 at 18:05