4

I'm trying call a method present in a class that extends AccessibilityService from another class that extends Service this way:

MyAccessibility access = new MyAccessibility();
access.doAction(); // doAction(); is the method called

but nothing happens, already if this is called inside MyAccessibility (AccessibilityService class) all works fine.

public class MyAccessibility extends AccessibilityService {

@Override
    protected void onServiceConnected() {
        super.onServiceConnected();

        System.out.println("Accessibility was connected!");

        doAction();
    }

    public void doAction(){

    performGlobalAction(GLOBAL_ACTION_RECENTS);

    }

}

Then how i can call any method of MyAccessibility from a another service?


EDIT:

I also tried change doAction() to be static, but performGlobalAction cannot be.

3 Answers3

5

The solution is access MyAccessibility by a singleton:

public class MyAccessibility extends AccessibilityService {

public static MyAccessibility instance;

@Override
    protected void onServiceConnected() {
        super.onServiceConnected();

        System.out.println("Accessibility was connected!");

        instance = this;

    }

    public void doAction(){

    performGlobalAction(GLOBAL_ACTION_RECENTS);

    }

}

And call doAction(); from your service like this:

MyAccessibility.instance.doAction();
  • 1
    While this solution will result in the code for "doAction" running, it won't run in the way that you're expecting. Namely, within the context of an AccessibilityService, with the full privileges that this entails. – MobA11y Aug 22 '18 at 14:29
  • @ChrisCM, i'm need call `doAction();` outside of `AccessibilityService` class. My project require this, and this was the solution to my trouble. –  Aug 22 '18 at 14:43
  • This is a very fragile thing that you're doing, if it happens to work in this case, cool, but it has already failed for one user: https://stackoverflow.com/questions/46194538/accessibilityservice-performglobalaction-not-working-in-own-app – MobA11y Aug 22 '18 at 15:02
0

You can't. While the answers provided will cause the code to be run, it most certainly won't run in the way you're expecting it to. AccessibilityServices are not like normal Services. They get elevated priveleges. In order to get those elevated priveleges they must be run within their own special Context, and the only way to get that state is to launch the service from the AccessibilityServices settings menu... Where TalkBack is.

YOU COULD... you shouldn't... but YOU COULD, start your service and use intra process communication mechanisms to get the function to run when you want it to from another process. This would be the only way to achieve what you want from a functional perspective.

MobA11y
  • 18,425
  • 3
  • 49
  • 76
-1

I think we need to make an intent to call the service, then it'll be performing like a service.

Intent intent = new Intent(this, HelloService.class); startService(intent);

https://developer.android.com/guide/components/services

If we want to call this method specifically, then copy this method to a regular class and call it.

Meep
  • 501
  • 6
  • 24
  • the service already was started exactly by `startService();`. –  Aug 19 '18 at 22:46
  • `If we want to call this method specifically, then copy this method to a regular class and call it.`. This not can be, because lost access to especific methods like `performGlobalAction();` –  Aug 19 '18 at 22:48
  • are you calling the method from UI thread? Service performs in the background thread. – Meep Aug 19 '18 at 22:49
  • from a background service in: `class CMDThread implements Runnable {` –  Aug 19 '18 at 22:51
  • CMDThread calls MyAccessibility Service - do you see System.out.println("Accessibility was connected!"); coming out? – Meep Aug 19 '18 at 22:57
  • MyAccessibility Service is started in `onCreate().` of MainActivity. MainActivity also start my background service `SocketBackgroundService` where contains CMDThread that is executed when Socket was connected with success. Then CMD Thread will wait for some command from server application. Then if i send a command for example "show recent apps" then: `MyAccessibility access = new MyAccessibility(); access.doAction();` like i showed above on question. But nothing happens. –  Aug 19 '18 at 23:05
  • Is MyAccessibility a one time operation? If it is, then we can recreate the MyAccessibility in CMD Thread and run it. Then, the MyAccessibility will run the doAction(). If you want to get the doAction() specifically only without calling the service. I think MyAccessibility need to be running in order to have performGlobalAction() to work. Try adding the system.out.print("something") in doAction() to see if it comes up or not. – Meep Aug 19 '18 at 23:15
  • `performGlobalAction();` is false, `system.out.print("something")` comes. Then the trouble is with `performGlobalAction();`. –  Aug 19 '18 at 23:28
  • I think performGlobalAction(); will run if the service is on. Check if the service is on or not. check https://stackoverflow.com/questions/29200046/accessibility-service-performglobalaction-returns-false – Meep Aug 19 '18 at 23:43
  • thank you by help, i discovered a possible solution. See my answer. –  Aug 20 '18 at 00:35