目录
官方方法
auto()
auto.waitFor()
auto.setMode(mode)
优点
简单好用,自动会跳转到无障碍开启页面。
缺点
优点之一就是缺点,只能自动跳转到无障碍开启页面。最大的问题就是剥夺了用户的选择权。如果你取消操作,就一直打开, 没完没了。
解决思路
把打开无障碍拆页面分为两步,完成第一步后可以再界面上提示用户操作,再引导用户点击进行页面跳转。这里跳过提示步骤,问题就是下面2个:
- 判断无障碍是否打开
- 选择性跳转到无障碍设置页面
直接上代码
判断无障碍是否打开
- 获取系统已打开无障碍的服务列表
- 检测当前包是否在列表中
importClass(android.provider.Settings);
let AccessibilityService = Settings.Secure.getString(context.contentResolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
if(AccessibilityService){
check_auto = new RegExp((context.getPackageName()).replace('.','\\.')).test(AccessibilityService)
}else{
check_auto = false
}
无障碍服务列表返回内容如下:
com.autopay/com.stardust.autojs.core.accessibility.AccessibilityService:org.autojs.autojs/com.stardust.autojs.core.accessibility.AccessibilityService
可见格式为:
以 : 分割 ,各项内容为:
应用包名/com.stardust.autojs.core.accessibility.AccessibilityService
打开无障碍设置页面
importClass(android.provider.Settings);
context.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
这里的代码是autojs内的代码,Android > JavaScript 。
问题到答案
作为一个安卓小白,要怎么解决上诉问题还是比较头疼的。
但是我有了个思路,当然是,看源码。
autojs 源码
项目地址
hyb1996/Auto.js
思路分享和记录
首先 autojs 界面上就有一个打开无障碍按钮,也就是说autojs源码中必然有检测和跳转这2个步骤的代码。
- 项目内搜索“无障碍”,无内容
- 搜索“服务”
app/src/main/res/values/strings.xml
<string name="text_cannot_read_file">无法读取文件</string>
<string name="text_service">服务</string>
<string name="text_notification_permission">通知读取权限</string>
- 搜索“text_service”,这里已经看到mAccessibilityServiceItem,说明接近了
app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.java
new DrawerMenuGroup(R.string.text_service),
mAccessibilityServiceItem,
mStableModeItem,
- 搜索“mAccessibilityServiceItem”,点击跳转到文件
注意第四个参数enableOrDisableAccessibilityService,从字面意思可以看到 ,这里就是切换无障碍的动作的状态
private DrawerMenuItem mAccessibilityServiceItem = new DrawerMenuItem(R.drawable.ic_service_green, R.string.text_accessibility_service, 0, this::enableOrDisableAccessibilityService);
- 点击跳转到 “enableOrDisableAccessibilityService”
这里我补充下代码的备注
void enableOrDisableAccessibilityService(DrawerMenuItemViewHolder holder) {
boolean isAccessibilityServiceEnabled = isAccessibilityServiceEnabled();
boolean checked = holder.getSwitchCompat().isChecked();
if (checked && !isAccessibilityServiceEnabled) {
enableAccessibilityService();
} else if (!checked && isAccessibilityServiceEnabled) {
if (!AccessibilityService.Companion.disable()) {
AccessibilityServiceTool.goToAccessibilitySetting();
}
}
}
可以取得2个关键性函数
a. isAccessibilityServiceEnabled();
无障碍服务是否开启
b. AccessibilityServiceTool.goToAccessibilitySetting();
跳转到设置
- 点击 AccessibilityServiceTool.goToAccessibilitySetting(); 跳转到函数详情
public static void goToAccessibilitySetting() {
Context context = GlobalAppContext.get();
if (Pref.isFirstGoToAccessibilitySetting()) {
GlobalAppContext.toast(context.getString(R.string.text_please_choose) + context.getString(R.string.app_name));
}
try {
AccessibilityServiceUtils.INSTANCE.goToAccessibilitySetting(context);
} catch (ActivityNotFoundException e) {
GlobalAppContext.toast(context.getString(R.string.go_to_accessibility_settings) + context.getString(R.string.app_name));
}
}
这里我们找到步骤二 打开无障碍设置页面
AccessibilityServiceUtils.INSTANCE.goToAccessibilitySetting(context);
- 点击 isAccessibilityServiceEnabled(); 跳转到函数详情
public static boolean isAccessibilityServiceEnabled(Context context) {
return AccessibilityServiceUtils.INSTANCE.isAccessibilityServiceEnabled(context, sAccessibilityServiceClass);
}
看起来找到了答案,但是运行时捏,提示错误。
AccessibilityServiceUtils.INSTANCE.isAccessibilityServiceEnabled 不存在
这里我卡了很长一段时间。
- 最后搜索 AccessibilityServiceUtils
好的找到你了,答案就在这里,也就是说打开无障碍设置页面这一步还是麻烦了,可以更直接一点。
package com.stardust.view.accessibility
import android.accessibilityservice.AccessibilityService
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.provider.Settings
import android.text.TextUtils
import java.util.Locale
object AccessibilityServiceUtils {
fun goToAccessibilitySetting(context: Context) {
context.startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
}
fun isAccessibilityServiceEnabled(context: Context, accessibilityService: Class<out AccessibilityService>): Boolean {
val expectedComponentName = ComponentName(context, accessibilityService)
val enabledServicesSetting = Settings.Secure.getString(context.contentResolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
?: return false
val colonSplitter = TextUtils.SimpleStringSplitter(':')
colonSplitter.setString(enabledServicesSetting)
while (colonSplitter.hasNext()) {
val componentNameString = colonSplitter.next()
val enabledService = ComponentName.unflattenFromString(componentNameString)
if (enabledService != null && enabledService == expectedComponentName)
return true
}
return false
}
}
总结
如果对安卓开发有了解的应该都不用这么麻烦,这里只是分享一下问题到思路到找到解决办法的过程。
最重要的是在Github上看源码的过程确实很享受!!!
最后在看了一丢丢的Android源码和部分文档后,恭喜自己在“Android从入门到劝退”踏出了第一步。
补充
还有一个auto pro 文档才有的方法
// 此时根据无障碍服务的开启情况,同步开关的状态
auto.service != null