我想出了一个想法,使用一个静态布尔值来指示 Accessibility Service 的状态,并将其与Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
. 我已经在多台设备上进行了测试,没有发现这种方法有任何问题。
1.在无障碍服务中声明一个静态布尔值。
private static boolean bServiceRunning = false;
2.在无障碍服务中,设置布尔值onServiceConnected
和onUnbind
@Override
protected void onServiceConnected() {
super.onServiceConnected();
bServiceRunning = true; //put this at the very beginning to reduce time gap
}
@Override
public boolean onUnbind(Intent intent) {
bServiceRunning = false;
return super.onUnbind(intent);
}
3.在Accessibility Service中创建静态函数
public static boolean bGetServiceStatus(){
return bServiceRunning;
}
使用布尔标志,我可以知道无障碍服务是否以所需的状态运行。当服务被强制停止时,onUnbind
将被调用,因此布尔值变为 false。
4.我们Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
用来获取无障碍服务切换状态
public static boolean bIsAccessibilityServiceEnabled(Context context, Class<?> accessibilityService) {
ComponentName expectedComponentName = new ComponentName(context, accessibilityService);
String strServicesSettingResult = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (strServicesSettingResult == null){
return false;
}
TextUtils.SimpleStringSplitter colonSplitter = new TextUtils.SimpleStringSplitter(':');
colonSplitter.setString(strServicesSettingResult);
while (colonSplitter.hasNext()) {
String strComponentName = colonSplitter.next();
ComponentName enabledService = ComponentName.unflattenFromString(strComponentName);
if (enabledService != null && enabledService.equals(expectedComponentName))
return true;
}
return false;
}
5.这就是我们想要的,我们用上面两种方法检查确定无障碍服务的真实状态。
public static int intIsAccessibilityServiceEnabled_WithCrashCheck(Context context, Class<?> accessibilityService){
//return 0 if Accessibility Service enabled and running
//return -1 if Accessibility Service disabled and not running
//return -2 if Accessibility Service enabled but stopped working or crashed
//first check Accessibility Service boolean
if(bGetServiceStatus()){
//service is running
return 0;
}else{
//service not running, now double check with Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
boolean bResult = bIsAccessibilityServiceEnabled(context, accessibilityService);
if(!bResult){
//Accessibility Service is disabled
return -1;
}else{
//Accessibility Service is enabled, but service is not actually running, Accessibility Service is crashed
return -2;
}
}
}
使用“AccessibilityManager”也同样有效,但我更喜欢带有静态布尔值的更“轻量级”版本以获得更好的性能。
注意:Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
在没有其他双重检查的情况下使用会导致错误。该值未同步。结果并不总是代表真实的服务状态。以下步骤可以创建这样的案例:
- 启动辅助功能服务,然后转到应用设置强制停止应用。
- 现在您可以看到无障碍服务开关已关闭。(目前看来足够了,但下一步会产生问题)
- 再次启动无障碍服务,在Android 9.0+的设备上你会发现开关打开了,但服务实际上没有运行,现在它显示“不工作。点击获取信息。”