AccessibilityService实现模拟点击

AccessibilityService

AccessibilityService介绍

AccessibilityService可以检测当前界面中UI事件的变化,在开发者的手中,可以利用它实现自动化测试。

google 官方文档 ANDROID_API

创建AccessibilityService

AccessibilityService是系统级的service,我们创建一个Service继承AccessibilityService。

/**
 * 这个服务是不需要你在activity里去开启的,属于系统级别辅助服务 需要在设置里去手动开启 和我们平常app里
 * 经常使用的service 是有很大不同的 非常特殊
 * 你可以在 \sdk\samples\android-23\legacy\ApiDemos 这样的目录下 找到这个工程 这个工程下面有一个accessibility
 * 包 里面有关于这个服务的demo 当然他们那个demo 非常复杂,但是信息量很大,有兴趣深入研究的同学可以多看demo
 * 我这里只实现最基本的功能 且没有做冗余和异常处理,只包含基础功能,不能作为实际业务上线!
 */
public class MyAccessibilityService extends AccessibilityService {
    public MyAccessibilityService() {
    }

    /**
     * AccessibilityService 这个服务可以关联很多属性,这些属性 一般可以通过代码在这个方法里进行设置,
     * 我这里偷懒 把这些设置属性的流程用xml 写好 放在manifest里,如果你们要使用的时候需要区分版本号
     * 做兼容,在老的版本里是无法通过xml进行引用的 只能在这个方法里手写那些属性 一定要注意.
     * 同时你的业务如果很复杂比如需要初始化广播啊之类的工作 都可以在这个方法里写。
     */
    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
    }

    /**
     * 当你这个服务正常开启的时候,就可以监听事件了,当然监听什么事件,监听到什么程度 都是由给这个服务的属性来决定的,
     * 我的那些属性写在xml里了。
     */
    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        /**
         * 事件是分很多种的,我这里是最简单的那种,只演示核心功能,如果要做成业务上线 这里推荐一个方法可以快速理解这里的type属性。
         * 把这个type的int 值取出来 并转成16进制,然后去AccessibilityEvent 源码里find。顺便看注释 ,这样是迅速理解type类型的方法
         */
    }

    @Override
    public void onInterrupt() {

    }
}

使用这个Service需要在manifest.xml中添加权限

   <uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>

在res中创建Service的配置文件。

<!--
这个就是给我们的AccessibilityService 设置属性的,当然你也可以在代码里 的 connnect函数里 手动设置。可以向下兼容。
accessibilityFeedbackType 这个属性如果不设置的话 我们那个onAccessibilityEvent 这个回调函数 根本回调不了 所以这里要注意
packageNames 这个属性 就是捕获什么app的行为的,比如我这里写的包名是packageinstaller 那就肯定只能捕获安装器的 事件了
有的rom 安装器可能不是这个包名 那你就要进行特殊设置了,此外这个属性你如果什么都不写 就意味着 你可以捕获所有手机的动作
如果你要做流氓软件的话 可以packageNames 里面什么都不写。。。甚至可以操作支付宝 给你打钱。。。如果你知道用户密码的话。
当然你如果真这么做了 相信捕获一次用户输入密码的行为 也是很容易的。。细思极恐 我就不往下深入了。。。

description 这个就是对你那个申请服务的时候说明了,可以写的煽情一点 让用户打开这个服务的可能性更高一点。。。
-->
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:accessibilityEventTypes="typeAllMask"
    android:notificationTimeout="100"
    android:packageNames="com.android.packageinstaller"
    android:accessibilityFeedbackType="feedbackSpoken"
    android:canRetrieveWindowContent="true"
    android:description="@string/hint" />

并且在manifest.xml中声明这个Service,并设置上面的配置文件。

        <!-- label 这个就是在设置界面显示的label 应该比较好理解了-->
        <service
            android:name=".service.MyAccessibilityService"
            android:exported="true"
            android:label="Liking"
            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/taskbackconfig" />
        </service>

这样就创建完成了一个AccessibilityService。

AccessibilityService使用

onAccessibilityEvent中去设置

            switch (eventType) {
                case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
                    //这个地方没什么好说的 你就理解成 找到当前界面 包含有安装 这个关键词的 所有节点就可以了。返回这些节点的list
                    //注意这里的find 其实是contains的意思,比如你界面上有2个节点,一个节点内容是安装1 一个节点内容是安装2,那这2个节点是都会返回过来的
                    //除了有根据Text找节点的方法 还有根据Id找节点的方法。考虑到众多手机rom都不一样,这里需要大家多测试一下,有的rom packageInstall
                    //定制的比较深入,可能和官方rom里差的很远 这里就要做冗余处理,可以告诉大家一个小技巧 你就把这些rom的 安装器打开 然后
                    //通过ddms里 看view结构的按钮 直接进去看就行了,可以直接看到那个界面属于哪个包名,也可以看到你要捕获的那个按钮的id是什么 很方便!
                    List<AccessibilityNodeInfo> list  = event.getSource().findAccessibilityNodeInfosByText("确定");

                    if (null != list) {
                        for (AccessibilityNodeInfo info : list) {
                            if (info.getText().toString().equals("确定")) {
                                //找到你的节点以后 就直接点击他就行了
                                info.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
                                info.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            }
                        }
                    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,716评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,789评论 25 709
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,100评论 6 342
  • 今年2.26的时候,我去看了一部电影《高跟鞋先生》。这是网上的剧情简介: 我再剧透一下,女装杭远成为网络红人是因为...
    Lynette_C阅读 4,790评论 0 8
  • 有的时候自己在出差途中,或者在干什么事的时候,会突然从内心感觉到孤独,哪时你想打个电话来宣泄你的孤独感,为了不觉得...
    冯凯源阅读 3,544评论 0 0