美文网首页
Android AccessibilityService使用方法

Android AccessibilityService使用方法

作者: _道友请留步_ | 来源:发表于2019-06-04 10:53 被阅读0次
  1. 原理
    大致简述一下,谷歌已经在View、ViewGroup、TextView等控件的文字改变、滑动、UI变化埋下了接口,当这些状态变化时控件会回调系统API,API系统然后对这些对象的数据进行组装,为了数据的安全性,系统会重新创建一些对象(AccessibilityEvent、AccessibilityNodeInfo)来间接保存这些数据,然后通过跨进程将这些数据返回给对应的Service中。

  2. 使用范围
    首先,辅助功能不可能直接操作外部对象,辅助功能只能在本进程调用指定系统方法,由系统再分发给指定外部对象,辅助功能做的事基本和用户能做的差不多(比如回复微信, 微信抢红包)

AccessibilityService用法

  1. 首先, AccessibilityService本质上也是一个Service, 所以在Manifest.xml 中还是需要注册对应的Service内容, 并且声明权限, 示例如下:
<service
            android:name=".RobService"
            android:enabled="true"
            android:exported="true"
            android:label="学习强国"
            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService" />
        </intent-filter>

        <meta-data
                android:name="android.accessibilityservice"
                android:resource="@xml/myaccessibility"/>
        </service>

其中resource中的配置项是单独创建一个myaccessibility.xml文件

<?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:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
    android:canRetrieveWindowContent="true" //表示该服务能否访问活动窗口中的内容.也就是如果你希望在服务中获取窗体内容的话,则需要设置其值为true.
    android:notificationTimeout="100" // 接受事件的时间间隔
    android:canPerformGestures="true" //分发手势
    android:packageNames="com.tencent.mm"/>
  1. 在注册服务完成后, 就可以创建一个Service继承AccessibilityService, 并且实现它的onServiceConnectedonAccessibilityEvent方法, 其中, 在onServiceConnected方法中放一些资源的初始化操作, 此方法会在开启了AccessibilityService权限的时候被调用. 在onAccessibilityEvent实现对事件的处理, 比如屏幕改变事件, 消息通知事件.

  2. 控件的查找与操作
    控件的操作主要分为几个步骤:

    1. 获取到当前界面的根节点AccessibilityNodeInfo rootNode = getRootInActiveWindow();

    2. 通过id或者text文本查找到对应的节点

      • 在sdk-tools/tools目录下, 有一个monitor.bat脚本, 双击这个脚本打开Android Device Monitor
      • 在电脑连接了安卓手机并且开启了USB调试模式的情况下, Android Device Monitor会显示出对应的手机, 点击上面的Dump View按钮, 此时工具会自动对当前手机界面进行分析, 并生成一个dump
      • 最后得到类似下图, 用鼠标移动到对应的控件上, 即可看到控件的属性和文本等


        截图
        控件属性
    3. 对节点进行操作, 这里要注意到, 有一些程序做了特殊处理, 有时候在Android Device Monitor看到clickable属性为true, 但不一定它就会响应click事件, 是否响应事件要按实际情况分析.

//获取当前聊天页面的根布局
AccessibilityNodeInfo rootNode = getRootInActiveWindow();
List<AccessibilityNodeInfo> listChat = rootNode.findAccessibilityNodeInfosByViewId("android:id/text1"); //根据id查找控件
//List<AccessibilityNodeInfo> listChat = rootNode.findAccessibilityNodeInfosByText("发送"); //根据文本查找控件
for (AccessibilityNodeInfo nodeInfo : listChatRecord) {
   nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK); //点击控件
}
  1. 手势
    Android提供了特殊类型的触摸屏事件,如捏合,双击,滚动,长按和退缩。这些都被称为手势。
 //发送一个点击事件
Path mPath=new Path();//线性的path代表手势路径,点代表按下,封闭的没用
mPath.moveTo(500, 500);
service.dispatchGesture(new GestureDescription.Builder().addStroke(new GestureDescription.StrokeDescription
(mPath, 手势开始时间比如立即开始0, 手势总时长比如100)).build(), 回调函数(可以为null), 回调的线程(null表示主线程));

扩展使用

  1. 使用webview通过js调用android代码
    在android的方法定义中, 加上@JavaScriptInterface注释后, 在webView.addJavascriptInterface(new JsInterface(), "Android");
    然后在js中执行"Android.方法名"

附录

  • accessibilityEventTypes的取值
    | constant | value | 描述 |
    | - | - | - |
    | typeAllMask|ffffffff|所有类型的事件
    |typeAnnouncement|4000|一个应用产生一个通知事件
    |typeAssistReadingContext|1000000|辅助用户读取当前屏幕事件
    |typeContextClicked|800000|view中上下文点击事件
    |typeGestureDetectionEnd|80000|监测到的手势事件完成
    |typeGestureDetectionStart|40000|开始手势监测事件
    |typeNotificationStateChanged|40|收到notification弹出消息事件
    |typeTouchExplorationGestureEnd|400|触摸浏览事件完成
    |typeTouchExplorationGestureStart|200|触摸浏览事件开始
    |typeTouchInteractionEnd|200000|用户触屏事件结束
    |typeTouchInteractionStart|100000|触摸屏幕事件开始
    |typeViewAccessibilityFocusCleared|10000|无障碍焦点事件清除
    |typeViewAccessibilityFocused|8000|获得无障碍的焦点事件
    |typeViewClicked|1|点击事件
    |typeViewFocused|8|view获取到焦点事件
    |typeViewHoverEnter|80|一个view的悬停事件
    |typeViewHoverExit|100|一个view的悬停事件结束,悬停离开该view
    |typeViewLongClicked|2|view的长按事件
    |typeViewScrolled|1000|view的滚动事件,adapterview、scrollview
    |typeViewSelected|4|view选中,一般是具有选中属性的view,例如adapter
    |typeViewTextChanged|10|edittext中文字发生改变的事件
    |typeViewTextSelectionChanged|2000|edittext文字选中发生改变事件
    |typeViewTextTraversedAtMovementGranularity|20000|UIanimator中在一个视图文本中进行遍历会产生这个事件,多个粒度遍历文本。一般用于语音阅读context
    |typeWindowContentChanged|800|窗口的内容发生变化,或者更具体的子树根布局变化事件
    |typeWindowStateChanged|20|新的弹出层导致的窗口变化(dialog、menu、popupwindow)
    |typeWindowsChanged|400000|屏幕上的窗口变化事件,需要API 21+

  • `accessibilityFeedbackType 此服务提供的反馈类型

constant value 描述
feedbackAllMask ffffffff 取消所有的可用反馈方式
feedbackAudible 4 可听见的(非语音反馈)
feedbackGeneric 10 通用反馈
feedbackHaptic 2 触觉反馈(震动)
feedbackSpoken 1 语音反馈
feedbackVisual 8 视觉反馈
  • accessibilityFlags 辅助功能附加的标志,多个使用 ' | '分隔
constant value 描述
flagDefault 1 默认的配置
flagEnableAccessibilityVolume 80 这个标志要求系统内所有的音频通道,使用由STREAM_ACCESSIBILTY音量控制USAGE_ASSISTANCE_ACCESSIBILITY
flagIncludeNotImportantViews 2 表示可获取到一些被表示为辅助功能无权获取到的view
flagReportViewIds 10 使用该flag表示可获取到view的ID
flagRequestAccessibilityButton 100 如果辅助功能可用,提供一个辅助功能按钮在系统的导航栏 API 26+
flagRequestEnhancedWebAccessibility 8 此类扩展的目的是为WebView中呈现的内容提供更好的辅助功能支持。这种扩展的一个例子是从一个安全的来源注入JavaScript。如果至少有一个具有此标志的辅助功能服务, 则系统将使能增强的web辅助功能。因此, 清除此标志并不保证该设备不会使能增强的web辅助功能, 因为可能有另一个使能的服务在使用它。
flagRequestFilterKeyEvents 20 能够监听到系统的物理按键
flagRequestFingerprintGestures 200 监听系统的指纹手势 API 26+
flagRequestTouchExplorationMode 4 系统进入触控探索模式。出现一个鼠标在用户的界面
flagRetrieveInteractiveWindows 40 该标志知识的辅助服务要访问所有交互式窗口内容的系统,这个标志没有被设置时,服务不会收到TYPE_WINDOWS_CHANGE事件。

相关文章

网友评论

      本文标题:Android AccessibilityService使用方法

      本文链接:https://www.haomeiwen.com/subject/gbzvgqtx.html