探索无障碍权限开启的最佳体验
作者: 抠脚本人
拟解决的问题
通过代码,最大程度的简化无障碍权限的打开逻辑,降低用户的操作难度,提升脚本使用体验
解决思路
1)判断是否有无障碍权限
2)没有无障碍权限时,通过判断其他可用权限,选择最佳的权限打开方式
3)打开无障碍权限,执行脚本主要逻辑内容
具体步骤
使用之前,我们先导入两个需要用到的安卓的class,以及定义一下频繁用到的变量。
importClass("android.content.pm.PackageManager");
importClass("android.provider.Settings");
const myPackageName = context.getPackageName();//获取应用的包名
我们一般通过auto.service的值判断是否开启了无障碍服务,但是这里在安卓11以上设备上偶尔会存在bug,能通过auto.service获取到AccessibilityService,但是实际无障碍权限不能用,因此我选择了使用auto.rootInActiveWindow,直接获取控件,同时没有开启无障碍权限也是返回null,相对可以准确一些。
if (!auto.rootInActiveWindow) {
//去打开无障碍
}
当没有无障碍权限时,打开无障碍权限的方式,这里优先采用静默打开的方式。需要用到 android.permission.WRITE_SECURE_SETTINGS 权限,因此需要先判断是否有这个需要的权限,这里对获取权限的方法进行了简单的封装,传入权限的字符串类型,获取返回值即可。
function checkPermission(permission) {
pm = context.getPackageManager();
return PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, context.getPackageName().toString());
}
如果有该权限,我们可以直接通过此权限设置对应的键值对的内容,即可打开无障碍权限,这里对打开的方法进行封装,方便调用。
function openAccessibility() {
let mServices = ":" + myPackageName + "/com.stardust.autojs.core.accessibility.AccessibilityService";
let enabledServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES).replace(new RegExp(mServices, "g"), "");
Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServices + mServices);
}
此权限也可修改其他一些系统设置,具体可参考安卓文档[android.provider.Settings.Secure](Settings.Secure | Android Developers (google.cn)),有详细的介绍。
如果没有该权限,我们需要先获取到此权限,可以使用root或者adb权限,因此我们需要获取设备是否具有root或adb权限,可以通过autojspro自带的$shell.checkAccess(“adb”)以及$shell.checkAccess(“root”)的返回值判断,有权限时,先授权WRITE_SECURE_SETTINGS,再去打开无障碍服务,没有权限时通过intent跳转,让用户去手动开启无障碍权限,同时为用户复制adb命令到剪切板,方便用户将手机连接电脑取激活,具体代码如下:
if ($shell.checkAccess("adb")) {
shell("pm grant " + myPackageName + " android.permission.WRITE_SECURE_SETTINGS", {
adb: true,
});
toastLog("adb授权成功");
openAccessibility();
} else {
if ($shell.checkAccess("root")) {
shell("pm grant " + myPackageName + " android.permission.WRITE_SECURE_SETTINGS", {
root: true,
});
toastLog("root授权成功");
openAccessibility();
} else {
console.info("\n也可使用WRITE_SECURE_SETTINGS权限开启无障碍服务\n授权代码已复制,使用adb激活");
setClip("adb shell pm grant " + myPackageName + " android.permission.WRITE_SECURE_SETTINGS");
app.startActivity({
action: "android.settings.ACCESSIBILITY_SETTINGS",
});
}
}
使用电脑连接手机激活时,通过adb授权WRITE_SECURE_SETTINGS,如下示意图,pm grant + 包名 + android.permission.WRITE_SECURE_SETTINGS
本文完整源码已上传本人gitee,点击查看,下一期将讲解在此代码的基础上,将无障碍权限和ui界面关联,实现同步静默开启。同时拓展讲解悬浮窗权限,后台弹出权限等常见权限在ui界面的展示效果。