Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I programmatically start and stop an AccessibilityService?

Background

I have an app that has an AccessibilityService. Android seems to keep AccessibilityServices running all the time, but I only need mine to run sometimes. (Specifically, if a user opens my app and turns it off, the AccessibilityService is no longer needed.)

If my AccessibilityService is running when it isn't needed, it's wasting the device's RAM and CPU, and I want to avoid doing this to my users if possible.

Question

How can I programmatically start and stop my AccessibilityService?

Note that I am not asking to programmatically enable or disable the AccessibilityService in Android's accessibility settings; this is just about starting and stopping it when it's already enabled.

What I've tried (stopping the AccessibilityService)

  • Disabling the AccessibilityService component using the following:

    PackageManager.setComponentEnabledSetting(
        accessibilityServiceName,
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        0
    );
    

    This killed the entire application, including the AccessibilityService. Also, after rebooting the phone, the AccessibilityService was no longer visible in the Android accessibility settings. (It seems that the component needs to be re-enabled followed by restarting the phone in order to get it to show up again.)

  • Disabling the AccessibilityService component using the following:

    PackageManager.setComponentEnabledSetting(
        accessibilityServiceName,
        PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
        PackageManager.DONT_KILL_APP
    );
    

    This didn't stop the AccessibilityService.

  • Stopping the AccessibilityService using Context.stopService() and Service.stopSelf(). These didn't stop the service, presumably because the OS is bound to it.

  • Killing the AccessibilityService's process using Process.killProcess(). However, the service was soon after restarted and reconnected, presumably because the OS is bound to it.

  • Unregistering for accessibility events using AccessibilityService.setServiceInfo(new AccessibilityServiceInfo()). This stops the service from getting accessibility events, but the service still runs in the background.

Related questions

  • Can accessibility service be stopped or killed?

    This one is only about stopping the service. I want to be able to start the service again once it's stopped.

like image 887
Sam Avatar asked Nov 05 '16 00:11

Sam


People also ask

How do I give an app permanent accessibility?

Open your Settings app, search for "Accessibility", and tap on the first result. Next, tap one of these three buttons (the button that you see will depend on your device): Installed Services, Downloaded Services, or Downloaded apps. Tap A2U Android. Make sure the A2U Android shortcut is toggled OFF.

What is Android Accessibility suite used for?

Android Accessibility Suite is a collection of accessibility services that help you use your Android device eyes-free or with a switch device. Android Accessibility Suite includes: Accessibility Menu: Use this large on-screen menu to control gestures, hardware buttons, navigation, and more.


2 Answers

As stated in Sam's answer, the lifecycle of an AccessibilityService is managed exclusively by the system, so you can't kill it.

But apart resource optimization aims, if you still need to start/stop the AccessibilityService from operating in some circumstances, you can simply use the good old SharedPreferences.

Your Service's onAccessibilityEvent should be:

@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());

    if (prefs.getBoolean("isServiceEnabled", true)){
        /*
        * Your code goes here
        */
    }
}

When you want to "switch off/on" the service you can do it by simply writing this in some button's onClickListener or somewhere else according to your needs:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

prefs.edit().putBoolean("isServiceEnabled", false).apply(); // disable

prefs.edit().putBoolean("isServiceEnabled", true).apply();  // enable
like image 44
Drilon Kurti Avatar answered Sep 19 '22 15:09

Drilon Kurti


Taken from the Lifecycle section of the AccessibilityService documentation:

The lifecycle of an accessibility service is managed exclusively by the system and follows the established service life cycle. Starting an accessibility service is triggered exclusively by the user explicitly turning the service on in device settings. After the system binds to a service, it calls onServiceConnected(). This method can be overriden by clients that want to perform post binding setup.

An accessibility service stops either when the user turns it off in device settings or when it calls disableSelf() (In Android 7.0 (API 24) and later).

like image 128
Sam Avatar answered Sep 20 '22 15:09

Sam