Android无障碍开发(AccessibilityService)入门

一、AccessibilityService

根据官方的介绍,是指开发者通过增加类似contentDescription的属性,从而在不修改代码的情况下,让残障人士能够获得使用体验的优化,大家可以打开AccessibilityService来试一下,点击区域,可以有语音或者触摸的提示,帮助残障人士更好的使用App

官方文档:https://developer.android.com/guide/topics/ui/accessibility/service

二、AccessibilityService 开发流程

  1. 确定执行脚本的APK安装包
  2. 通过UIAutomator 获取包名及UI控件ID,或者下载一个开发者助手apk,也可以进行控件ID获取,代码君已经帮你下载好了,需要自取
    http://share.dmjzy.cn/f/17143538-501591536-a374b2(访问密码:8401)
  3. 编写脚本代码
  4. 调试、兼容性处理

三、核心代码

  1. AccessibilityService主要是实现onAccessibilityEvent
public class AccessibilitySampleService extends AccessibilityService{

    /**当无障碍服务连接之后回调*/
   @Override
   public void  onServiceConnected() {
        super.onServiceConnected()
    }

    /**当触发了需要监听的无障碍事件后回调*/
   @Override 
   public void onAccessibilityEvent(AccessibilityEvent event){
       // 获取包名
       String pkgName = event.getPackageName().toString();
       int eventType = event.getEventType();
 
       AccessibilityOperator.getInstance().updateEvent(this, event);
       //过滤出目标包,如果要检测所有包,可以去掉此判断
       if (pkgName.equals(pageName)) {
           AccessibilityLog.printLog("eventType: " + eventType + " pkgName: " + pkgName);
 
           switch (eventType) {
               case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                   //执行具体的脚本
                   toOperator();
                   break;
               case AccessibilityEvent.TYPE_VIEW_CLICKED:
                   break;
               case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:
                   break;
               case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
                   break;
           }
       }
   } 
   /**无障碍服务断开后回调*/
   @Override 
   public void onInterrupt(){
       // TODO Auto-generated method stub 
   }
}
方法说明
1. onServiceConnected

当声明的无障碍服务连接之后, 系统会回调此方法.
在这个方法里, 可以做一些初始化工作. 比如保存服务的实例 标识服务连接的状态等.

也可以通过android.accessibilityservice.AccessibilityService#getServiceInfo动态更改xml配置文件中声明的无障碍配置信息.

2. onAccessibilityEvent

当监听的事件触发时, 系统会回调此方法, 比如view被点击了 window内容改变了等.

可以用android.view.accessibility.AccessibilityRecord#getSource获取对象AccessibilityNodeInfo, 这个对象就是无障碍操作的核心对象, 通常可以理解为android开发中的view控件.

可以通过AccessibilityNodeInfo对象, 进行控件的点击操作 输入文本操作 滚动操作 获取文本操作等

3. onInterrupt

当中途关闭了无障碍服务时回调, 通常这个时候无障碍服务不可用, 调用api都会失败.

4. AccessibilityService 其他方法说明
方法名方法说明
disableSelf()禁用当前服务,也就是在服务可以通过该方法停止运行
findFoucs(int falg)查找拥有特定焦点类型的控件
getRootInActiveWindow()如果配置能够获取窗口内容,则会返回当前活动窗口的根结点
performGlobalAction(int action)执行全局操作,比如返回,回到主页,打开最近等操作,此方法可以模拟用户点击返回键和home键,操作见下面的官方文档
setServiceInfo(AccessibilityServiceInfo info)设置当前服务的配置信息
getSystemService(String name)获取系统服务
onKeyEvent(KeyEvent event)如果允许服务监听按键操作,该方法是按键事件的回调,需要注意,这个过程发生了系统处理按键事件之前

更多AccessibilityService参数说明见官方文档:
https://developer.android.google.cn/reference/kotlin/android/accessibilityservice/AccessibilityService

AccessibilityEvent
字段名字段说明
TYPE_NOTIFICATION_STATE_CHANGED通知栏状态变化
TYPE_VIEW_CLICKED视图被点击
TYPE_WINDOW_CONTENT_CHANGED窗口内容变化
TYPE_WINDOW_STATE_CHANGED窗口状态变化,即切换activity
  1. AndroidManifest.xml注册服务
<!-- 注册辅助功能服务-->
       <service
           android:name=".AccessibilitySampleService"
           android:exported="true"
           android:label="码君助手"
           android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
           android:process=":BackgroundService">
           <intent-filter>
               <action android:name="android.accessibilityservice.AccessibilityService" />
           </intent-filter>
           <!--       通过xml文件完成辅助功能相关配置,也可以在onServiceConnected中动态配置-->
           <meta-data
               android:name="android.accessibilityservice"
               android:resource="@xml/accessibility_config" />
       </service>

  1. 在资源文件夹新增xml文件夹,新建accessibility_config文件,代码如下
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:canRetrieveWindowContent="true"
    android:canPerformGestures="true"
    android:description="@string/accessibility_desc"
    android:notificationTimeout="10" />

<!--  canPerformGestures  //申请手势权限-->
<!--accessibility_desc:码君助手,让你的手机更智能一点 -->

accessibility_config说明

官方文档说明:https://developer.android.google.cn/reference/android/R.styleable#AccessibilityService
这里列举一些比较常用的

字段名字段说明
accessibilityEventTypes表示该服务对界面中的哪些变化感兴趣,即哪些事件通知,比如窗口打开,滑动,焦点变化,长按等.具体的值可以在AccessibilityEvent类中查到,如typeAllMask表示接受所有的事件通知
accessibilityFeedbackType表示反馈方式,比如是语音播放,还是震动。feedbackGeneric代表所有
canRetrieveWindowContent表示该服务能否访问活动窗口中的内容.也就是如果你希望在服务中获取窗体内容的化,则需要设置其值为true
notificationTimeout接受事件的时间间隔,通常将其设置为100即可
packageNames表示对该服务是用来监听哪个包的产生的事件。如果不写代表监听所有的应用。中间可以用";"来分割。
canPerformGestures表示可以执行手势属性
canTakeScreenshot是否能够截屏

4、编写执行脚本

try {
           Thread.sleep(2000);
           AccessibilityOperator.getInstance().clickById("com.xxxx.packagename:id/btn_later");// 关闭弹框
 
           Thread.sleep(1000);
           AccessibilityOperator.getInstance().clickById("com.xxxx.packagename:id/tab_work");//切换到工作tab
           AccessibilityLog.printLog("切换到工作tab: ");
 
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
AccessibilityNodeInfo
方法名方法说明
findAccessibilityNodeInfosByText()通过字符串查找节点元素
findAccessibilityNodeInfosByViewId()通过视图id查找节点元素
performAction()在节点上执行一个动作,比如点击、向上滑动等,更多操作见下面的官方文档
getParent()获取父节点
getChild()获取子节点
isEnabled()判断节点是否激活
isClickable()判断节点是否可以点击
isScrollable()判断节点是否可以滚动
isSelected()判断节点是否选中
isPassword()判断节点是否是密码输入框
isFocusable()判断节点是否可以获取焦点
getText()获取节点的文本信息
getContentDescription()节点的内容描述
getViewIdResourceName()获取节点控件的id ,获取到的值大概是这样的:com.ss.android.ugc.aweme:id/afy
getBoundsInScreen()获取节点在屏幕中的位置
getClassName()获取节点的类型/类名,值:android.widget.LinearLayout
getChild()获取子节点的AccessibilityNodeInfo信息

更多请查看官方文档:
https://developer.android.google.cn/reference/android/view/accessibility/AccessibilityNodeInfo

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农掘金

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值