Как я могу программно запустить и остановить AccessibilityService?

Фон

У меня есть приложение с AccessibilityService. Android, похоже, постоянно держит AccessibilityService, но мне нужно только для запуска. (В частности, если пользователь открывает мое приложение и отключает его, AccessibilityService больше не требуется.)

Если мой AccessibilityService работает, когда он не нужен, он расточает RAM и процессор устройства, и я хочу избежать сделав это для моих пользователей, если это возможно.

Вопрос

Как я могу программно запустить и остановить мой AccessibilityService?

Обратите внимание, что я не запрашиваю программно включить или отключить AccessibilityService в настройках доступности Android; это только начало и остановка, когда она уже включена.

То, что я пробовал (остановка AccessibilityService)

  • Отключить компонент AccessibilityService, используя следующее:

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

    Это убило все приложение, включая AccessibilityService. Кроме того, после перезагрузки телефона AccessibilityService больше не отображается в настройках доступности Android. (Кажется, что компонент необходимо повторно включить, а затем перезапустить телефон, чтобы он снова появился.)

  • Отключить компонент AccessibilityService, используя следующее:

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

    Это не остановило AccessibilityService.

  • Остановка AccessibilityService с помощью Context.stopService() и Service.stopSelf(). Это не остановило службу, предположительно поскольку ОС привязана к ней.

  • Убив AccessibilityService с помощью Process.killProcess(). Однако служба была вскоре перезапущена и снова подключена, предположительно, потому что ОС привязана к ней.

  • Отмена регистрации событий доступности с помощью AccessibilityService.setServiceInfo(new AccessibilityServiceInfo()). Это останавливает обслуживание от получения событий доступности, но служба по-прежнему работает в фоновом режиме.

Связанные вопросы

Ответ 1

Взято из раздел Lifecycle в документации AccessibilityService:

Жизненный цикл службы доступности управляется исключительно системой и следует установленному сроку службы. Запуск службы доступности запускается исключительно пользователем, явно включающим службу в настройках устройства. После того, как система связывается с сервисом, он вызывает onServiceConnected(). Этот метод может быть переопределен клиентами, которые хотят выполнить настройку после связывания.

Служба доступности останавливается, когда пользователь отключает ее в настройках устройства или когда он вызывает disableSelf().

Ответ 2

Как указано в ответе Сэма, жизненный цикл AccessibilityService управляется исключительно системой, поэтому вы не можете его убить.

Но, кроме оптимизации ресурсов, если вам еще нужно запустить/остановить работу AccessibilityService в некоторых обстоятельствах, вы можете просто использовать старый добрый SharedPreferences.

Ваша служба onAccessibilityEvent должна быть:

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

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

Если вы хотите "выключить/включить" услугу, вы можете сделать это, просто написав это на некоторой кнопке onClickListener или в другом месте в соответствии с вашими потребностями:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

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

prefs.edit().putBoolean("isServiceEnabled", true).apply();  // enable