无障碍检测

2,224 阅读2分钟

牙叔教程 简单易懂

无障碍概念

无障碍服务是一种应用程序,给有残疾的用户或暂时无法与设备完全交互的用户提供了更好的无障碍用户交互功能, 比如驾驶、照顾小孩或者在吵闹的派对上可能需要额外或者替代的交互反馈。 ​

Android提供标准的辅助功能服务,包括TalkBack,开发人员可以创建和分发自己的服务。

环境

Autojs版本: 9.0.8 安卓版本: 11 手机: 小米11pro ​

检测无障碍方式

1. 普通的无障碍检测
let am = context.getSystemService(android.content.Context.ACCESSIBILITY_SERVICE);
let isAccessibilityEnabled_flag = am.isEnabled();
log(isAccessibilityEnabled_flag);
2. TalkBack检测, 0关闭1开启
// 检查无障碍服务是否以TalkBack的方式开启
let isExploreByTouchEnabled_flag = isScreenReaderActive(context);
log(isExploreByTouchEnabled_flag);

function isScreenReaderActive(context) {
  // 通过Intent方式判断是否存在以TalkBack方式提供服务的Service,还需要判断开启状态
  let SCREEN_READER_INTENT_ACTION = "android.accessibilityservice.AccessibilityService";
  let SCREEN_READER_INTENT_CATEGORY = "android.accessibilityservice.category.FEEDBACK_SPOKEN";
  let screenReaderIntent = new Intent(SCREEN_READER_INTENT_ACTION);
  screenReaderIntent.addCategory(SCREEN_READER_INTENT_CATEGORY);
  let screenReaders = context.getPackageManager().queryIntentServices(screenReaderIntent, 0);
  if (screenReaders == null || screenReaders.size() <= 0) {
    log("没有TalkBack类型的service");
    return false;
  }

  let hasActiveScreenReader = false;
  if (Build.VERSION.SDK_INT >= 26) {
    // 高版本可以直接判断服务是否处于开启状态
    len = screenReaders.size();
    for (var i = 0; i < len; i++) {
      screenReader = screenReaders.get(i);
      log(screenReader);
      hasActiveScreenReader |= isAccessibilitySettingsOn(
        context,
        screenReader.serviceInfo.packageName + "/" + screenReader.serviceInfo.name
      );
    }
  } else {
    // 判断正在运行的Service里有没有上述存在的Service
    let runningServices = new ArrayList();
    let manager = context.getSystemService(Context.ACTIVITY_SERVICE);
    let services = manager.getRunningServices(java.lang.Integer.MAX_VALUE);
    var len = services.size();
    for (var i = 0; i < len; i++) {
      service = runningServices.get(i);
      runningServices.add(service.service.getPackageName());
    }

    len = screenReaders.size();
    for (var i = 0; i < len; i++) {
      screenReader = screenReaders.get(i);
      if (runningServices.contains(screenReader.serviceInfo.packageName)) {
        hasActiveScreenReader |= true;
      }
    }
  }

  return hasActiveScreenReader;
}

// To check service is enabled
function isAccessibilitySettingsOn(context, service) {
  let mStringColonSplitter = new TextUtils.SimpleStringSplitter(":");
  let settingValue = Settings.Secure.getString(
    context.getApplicationContext().getContentResolver(),
    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
  );
  if (settingValue != null) {
    mStringColonSplitter.setString(settingValue);
    while (mStringColonSplitter.hasNext()) {
      let accessibilityService = mStringColonSplitter.next();
      if (accessibilityService.equalsIgnoreCase(service)) {
        return true;
      }
    }
  }
  return false;
}

TalkBack界面.jpg

TalkBack使用踩坑

点击一次=选中, 选中后点击两次=选择, 滑动用两根手指

TalkBack概念

TalkBack 是安卓设备内置的一款屏幕阅读器。 TalkBack 会为您提供语音反馈,保证您在视力不便的情况下也能使用移动设备。 ​

在点击到按钮或开关的时候以语音的形式告知您这个按钮/开关的名称, 在选中的基础上双击两次屏幕将其打开, ​

您也可以按住屏幕进行拖动以便了解到当前页面都有哪些按钮/开关及其他可点击的控件。

TalkBack类名
com.google.android.marvin.talkback/com.google.android.marvin.talkback.TalkBackService 
对应的app

无障碍套件.jpg

检测方式

要么黑名单, 要么白名单

  • 黑名单, 就是拉黑autojs, easyclick, ctrljs, android开发工具箱, 等等此类的包名或者其他特征
  • 白名单, 只允许小米, 华为, 一加, oppo等手机自带的无障碍服务

名人名言

思路是最重要的, 其他的百度, bing, stackoverflow, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程

声明

部分内容来自网络 本教程仅用于学习, 禁止用于其他用途