简体   繁体   English

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

[英]How to Programmatically Enable/Disable Accessibility Service in Android

I would like to programmatically enable/disable Accessibility Services listed under Settings->Accessibility option.我想以编程方式启用/禁用“设置”->“辅助功能”选项下列出的辅助功能服务。

I could start Accessibility Intent like below:我可以像下面这样启动辅助功能意图:

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

But I don't have any idea on how to enable the services listed in the view through my code.但是我不知道如何通过我的代码启用视图中列出的服务。

Please, provide me your views.请提供您的意见。

I found a solution worked for me by calling我通过致电找到了适合我的解决方案

Settings.Secure.putString(getContentResolver(), 
    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "pkgname/classname");
Settings.Secure.putString(getContentResolver(), 
    Settings.Secure.ACCESSIBILITY_ENABLED, "1");

Where the pkgname is your package name and the classname is the class name of your accessibility service.其中pkgname是您的 package 名称, classname是您的无障碍服务的 class 名称。

If you need to enable several services or you don't want to destory the previous settings you might want to use : to seperate other services.如果您需要启用多个服务或者您不想破坏以前的设置,您可能想使用:来分离其他服务。

Also you might need to run as a system application and you might need the following permissions此外,您可能需要作为系统应用程序运行,并且您可能需要以下权限

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

However, according to @Rupert Rawnsley this might not work on some versions of Android, I am working on Android 4.0.4 and hope it works for you.然而,根据@Rupert Rawnsley的说法,这可能不适用于 Android 的某些版本,我正在研究 Android 4.0.4,希望它对你有用。

PS.附言。 If it doesn't work, maybe you could find some luck in /data/data/com.android.providers.settings/databases/settings.db/secure , that's where Android stores secure settings.如果它不起作用,也许您可以在/data/data/com.android.providers.settings/databases/settings.db/secure中找到一些运气,这是 Android 存储安全设置的地方。

From Android 6.0 you can use:从 Android 6.0 你可以使用:

adb shell settings put secure enabled_accessibility_services packagname/servicename

The settings.db from old releases is no longer present on Android 6.0. Android 6.0 上不再存在旧版本的 settings.db。

In Android 7 (API 24), an AccessibilityService can programmatically disable itself by calling the disableSelf() method.在 Android 7 (API 24) 中,AccessibilityService 可以通过调用disableSelf()方法以编程方式禁用自身。

AccessibilityService is special and cannot be started programmatically. AccessibilityService 比较特殊,不能以编程方式启动。

The best you can do is manualy open the accessibilty settings with:您可以做的最好的事情是使用以下方法手动打开辅助功能设置:

Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)意图 intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)

and start the intent - you can also do it from the prefernece xml file:并启动意图 - 您也可以从 prefernece xml 文件中执行此操作:

intent android:action="android.settings.ACCESSIBILITY_SETTINGS"意图 android:action="android.settings.ACCESSIBILITY_SETTINGS"

Just in case anybody still seeks to turn off talkback from adb when you are stuck in your lock screen entering the password or pin.以防万一当您卡在锁定屏幕上输入密码或 pin 时,仍然有人试图关闭来自 adb 的对讲。 One thing you can try is adb shell am force-stop com.google.android.marvin.talkback您可以尝试的一件事是adb shell am force-stop com.google.android.marvin.talkback

In instrumented tests I start my accessibility service like this:在仪器测试中,我像这样启动无障碍服务:

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)
}

I tested on Android 6 and 8. This also works for non-system apps.我在 Android 6 和 8 上进行了测试。这也适用于非系统应用程序。

Here is the working solution (if your activity is not running it will disable itself)这是有效的解决方案(如果您的活动未运行,它将自行禁用)

@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;
}

You can enable accessibility services for multiple apps by separating them by a colon, like this:您可以通过用冒号分隔它们来为多个应用程序启用辅助功能服务,如下所示:

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

enabled_accessibility_services contains all the enabled services separated by ':'. enabled_accessibility_services 包含所有以“:”分隔的已启用服务。 It's something like 'serviceA:serviceB:serviceC'类似于“serviceA:serviceB:serviceC”

If you replace the string, it will enable your service, but you will also disable everyone else's.如果您替换该字符串,它将启用您的服务,但您也会禁用其他人的服务。

The correct code would be:正确的代码是:

    fun enableAccessibility(activity: Activity) {
        var accessibilityServices: String? = Settings.Secure.getString(
            activity.contentResolver,
            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
        )

        if (accessibilityServices == null) {
            accessibilityServices = ""
        } else if (accessibilityServices.isNotEmpty()) {
            accessibilityServices = ":$accessibilityServices"
        }
        Settings.Secure.putString(
            activity.contentResolver,
            Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
            "${activity.applicationInfo.packageName}/${ForegroundDetectorService::class.java.canonicalName}$accessibilityServices"
        )
        Settings.Secure.putString(
            activity.contentResolver,
            Settings.Secure.ACCESSIBILITY_ENABLED, "1"
        )
    }

You only need to declare this permission:你只需要声明这个权限:

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

You can only enable this permission if you are rooted or via adb.如果您是 root 用户或通过 adb,您只能启用此权限。

I found this post: How to programmatically check if a service is declared in AndroidManifest.xml?我找到了这篇文章: 如何以编程方式检查是否在 AndroidManifest.xml 中声明了服务? . . The top answer talks about PackageManager, which tells you what is running.最佳答案是关于 PackageManager 的,它会告诉您正在运行的是什么。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM