如何以编程方式启用/禁用Android中的辅助功能服务

时间:2012-04-08 07:28:12

标签: android service accessibility

我想以编程方式启用/禁用“设置” - >“可访问性”选项下列出的辅助功能服务。

我可以像下面这样启动辅助功能:

Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivityForResult(intent, 0);

但我对如何通过我的代码启用视图中列出的服务一无所知。

请告诉我你的意见。

10 个答案:

答案 0 :(得分:16)

我通过调用

找到了解决方案
Settings.Secure.putString(getContentResolver(), 
    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "pkgname/classname");
Settings.Secure.putString(getContentResolver(), 
    Settings.Secure.ACCESSIBILITY_ENABLED, "1");

pkgname是您的包名称,而classname是您的辅助功能服务的类名。

如果您需要启用多项服务,或者您不想破坏之前的设置,则可能需要使用:来分隔其他服务。

此外,您可能需要作为系统应用程序运行,并且您可能需要以下权限

<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />

然而,根据@Rupert Rawnsley,这可能不适用于Android的某些版本,我正在使用Android 4.0.4并希望它适合您。

PS。如果它不起作用,也许你可以在/data/data/com.android.providers.settings/databases/settings.db/secure找到一些运气,那就是Android存储安全设置的地方。

答案 1 :(得分:7)

从Android 6.0开始,您可以使用:

adb shell settings put secure enabled_accessibility_services packagname/servicename

Android 6.0上不再提供旧版本中的settings.db。

答案 2 :(得分:7)

在Android 7(API 24)中,AccessibilityService可以通过调用disableSelf()方法以编程方式禁用自身。

答案 3 :(得分:5)

AccessibilityService很特殊,无法以编程方式启动。

答案 4 :(得分:4)

您可以做的最好的事情是:使用以下方法打开accessibilty设置:

  

Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)

并启动意图 - 您也可以从prefernece xml文件中执行此操作:

  

intent android:action =&#34; android.settings.ACCESSIBILITY_SETTINGS&#34;

答案 5 :(得分:3)

以防万一有人在你的锁定屏幕输入密码或密码时仍然试图关闭对话来自adb。您可以尝试的一件事是adb shell am force-stop com.google.android.marvin.talkback

答案 6 :(得分:1)

在仪器化测试中,我像这样启动我的辅助功能:

private fun enableAccessibilityService() {
    val packageName = "com.example"
    val className = "$packageName.service.MyService"
    val string = "enabled_accessibility_services"
    val cmd = "settings put secure $string $packageName/$className"
    InstrumentationRegistry.getInstrumentation()
      .getUiAutomation(UiAutomation.FLAG_DONT_SUPPRESS_ACCESSIBILITY_SERVICES)
      .executeShellCommand(cmd)
      .close()
    TimeUnit.SECONDS.sleep(3)
}

我在Android 6和8上进行了测试。这也适用于非系统应用。

答案 7 :(得分:0)

这是有效的解决方案(如果您的活动未运行,则会自行停用)

@Override
protected void onServiceConnected() {
    super.onServiceConnected();
    Toast.makeText(this, "Connected!",Toast.LENGTH_SHORT).show();
    ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
    scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
        public void run() {
            serviceChecker();
        }
    }, 0, 5, TimeUnit.SECONDS);
}

private void serviceChecker(){
    if(!isActivityRunning(MainActivity.class)) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            disableSelf();
        }
    }
}
protected Boolean isActivityRunning(Class activityClass)
{
    ActivityManager activityManager = (ActivityManager) getBaseContext().getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);

    for (ActivityManager.RunningTaskInfo task : tasks) {
        if (activityClass.getCanonicalName().equalsIgnoreCase(task.baseActivity.getClassName()))
            return true;
    }

    return false;
}

答案 8 :(得分:0)

您可以通过用冒号分隔多个应用程序来为它们启用无障碍服务,如下所示:

adb shell settings put secure enabled_accessibility_services com.app1/com.app1.MyAccessibilityService:com.app2/com.app2.MyAccessibilityService

答案 9 :(得分:-3)

我发现了这篇文章:How to programmatically check if a service is declared in AndroidManifest.xml?。最常见的答案是关于PackageManager,它告诉你正在运行的是什么。