我想以编程方式启用/禁用“设置 - >辅助功能”选项下列出的辅助功能服务。
我可以像下面一样启动Accessibility Intent:
Intent intent = new Intent(android.provider.Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivityForResult(intent, 0);
但我不知道如何通过我的代码启用视图中列出的服务。
请给我你的看法。
我通过电话找到了一个解决方案
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存储安全设置的地方。
从Android 6.0开始,您可以使用:
adb shell settings put secure enabled_accessibility_services packagname/servicename
Android 6.0上不再提供旧版本中的settings.db。
在Android 7(API 24)中,AccessibilityService可以通过调用disableSelf()方法以编程方式禁用自身。
AccessibilityService很特殊,无法以编程方式启动。
您可以做的最好的事情是手动打开辅助功能设置:
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
并启动意图 - 您也可以从首选项xml文件中执行此操作:
intent android:action =“android.settings.ACCESSIBILITY_SETTINGS”
万一当你被困在锁定屏幕输入密码或密码时,任何人仍然试图关闭adb的对讲。你可以尝试的一件事是adb shell am force-stop com.google.android.marvin.talkback
在检测测试中,我启动了这样的辅助功能服务:
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上测试过。这也适用于非系统应用程序。
这是工作解决方案(如果您的活动未运行,它将自行禁用)
@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;
}
我发现这个帖子:How to programmatically check if a service is declared in AndroidManifest.xml?。最常见的答案是关于PackageManager,它告诉你正在运行的是什么。