前言赘述:
本博客只对使用Android AccessibilityService实现自动抢单测试程序Demo的api使用,不对AccessibilityService的类结构及相关配置信息做详细说明,如需了解,请查阅谷歌安卓AccessibilityService的说明文档。
google Android官网AccessibilityService的文档说明:AccessibilityService | Android Developers
我最早是想在哈罗出行上做个脚本来抢单/找单,思考着要如何来实现这样一个功能。用lua脚本?用Android Monkey?很明显,这些都有局限性,实现不了。有一天,我想到某个电视台中的情景:某个电视台中,说的是小米集团(小米手机),在一个工作房间中的机架上整整齐齐的摆放着有上千乃至上万台的手机,每个手机的屏幕都在疯狂的闪烁着。后来才知道原来那是在做自动化交互测试。我在想:我的这个需求功能,是不是也是自动化交互测试方面的技术点?百度了一下,并由此接触到了Android AccessibilityService。
public abstract class AccessibilityService
extends Service
java.lang.Object ↳android.content.Context ↳android.content.ContextWrapper ↳android.app.Service ↳android.accessibilityservice.AccessibilityService
继承于android四大组件之Service,其使用方式与service基本相同。但它是一个系统级别的“监听器”服务,可监听手机上所有应用所产生的小变化、大变化(比如某个被监听应用的发生的点击事件、控件文本内容变化、消息通知等)。另它有自己独立的生命周期(思路有点类似于微信公众号开发中消息与事件的处理),如下:
onCreate()
onServiceConnected()
onAccessibilityEvent(AccessibilityEvent event)//线程阻塞式
onInterrupt()
下面进入主题:
第一步.注册服务
1.1在清单文件中注册服务
<service
android:name=".service.HaloAccessibilityServiceV5"
android:enabled="true"
android:exported="true"
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/accessibilityservice_setting" />
</service>
1.2meta-data引入配置
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibilityservice_setting" />
1.3accessibilityservice.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="flagReportViewIds|flagRetrieveInteractiveWindows"
android:canPerformGestures="true"
android:canRetrieveWindowContent="true"
android:description="@string/accessibilityservice_setting"
android:notificationTimeout="100"
android:packageNames="填写你要监听的应用完整包名以逗号隔开可填写多个"></accessibility-service>
1.4须手动为apk应用程序打开无障碍权限开关。
位置在设置->快捷与辅助->无障碍,找到自己的apk辅助程序应用,手动将开关打开。
第二步.实现辅助功能
思路:实现辅助功能的关键是接受到事件,并使用AccessibilityService相关api来获取应用控件信息,以及回应适当的事件,来完成"辅助"功能。
1.1下面先来看一下AccessibilityService做为"系统级"服务可以监听到指定应用的哪些事件,或者说可以监听到应用的哪些变化。
Event types支持的事件类型(全面)
AccessibilityEvent#TYPE_VIEW_CLICKED//View控件点击事件
AccessibilityEvent#TYPE_VIEW_LONG_CLICKED//长按事件
AccessibilityEvent#TYPE_VIEW_FOCUSED//焦点事件
AccessibilityEvent#TYPE_VIEW_SELECTED//选择事件
AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED//文本变化
AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED//窗口状态变化
AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED//消息通知状态变化
AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START//手势START
AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END//手势END
AccessibilityEvent#TYPE_VIEW_HOVER_ENTER//悬停
AccessibilityEvent#TYPE_VIEW_HOVER_EXIT//悬停
AccessibilityEvent#TYPE_VIEW_SCROLLED//滚动
AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED//文本选择变化
AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED//窗口连接变化
AccessibilityEvent#TYPE_ANNOUNCEMENT//公告
AccessibilityEvent#TYPE_GESTURE_DETECTION_START//手指检测START
AccessibilityEvent#TYPE_GESTURE_DETECTION_END//手指检测END
AccessibilityEvent#TYPE_TOUCH_INTERACTION_START//触摸互动START
AccessibilityEvent#TYPE_TOUCH_INTERACTION_END//触摸互动END
AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUSED//可访问性
AccessibilityEvent#TYPE_WINDOWS_CHANGED//窗口变化
AccessibilityEvent#TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED//可访问性清除
1.2获取应用控件信息的方式有两种
1).通过id寻找控件,id格式为:(包名:id/+制定控件的id),对第三方应用无效。这里引入一个工具,就是Android Sdk下自带的monitor监测器工具,可以使用它来初步的分析第三方应用的页面控件结构,如id、控件文本、层次关系等信息。~/Android/Sdk/tools$ ./monitor。
List<AccessibilityNodeInfo> list = rowNode.findAccessibilityNodeInfosByViewId("com.jingyao.easybike:id/tvAmount");
2).通过控件的text寻找控件
List<AccessibilityNodeInfo> list = rowNode.findAccessibilityNodeInfosByText("不拼车");
1.3.可回应的事件
1)节点可回应执行的操作
android.view.accessibility.AccessibilityNodeInfo#performAction(int action)
有
android.view.accessibility.AccessibilityNodeInfo#ACTION_CLICK//节点点击
android.view.accessibility.AccessibilityNodeInfo#ACTION_FOCUS
android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_FOCUS
android.view.accessibility.AccessibilityNodeInfo#ACTION_SELECT
android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_SELECTION
android.view.accessibility.AccessibilityNodeInfo#ACTION_CLICK
android.view.accessibility.AccessibilityNodeInfo#ACTION_LONG_CLICK
android.view.accessibility.AccessibilityNodeInfo#ACTION_ACCESSIBILITY_FOCUS
android.view.accessibility.AccessibilityNodeInfo#ACTION_CLEAR_ACCESSIBILITY_FOCUS
android.view.accessibility.AccessibilityNodeInfo#ACTION_NEXT_AT_MOVEMENT_GRANULARITY
android.view.accessibility.AccessibilityNodeInfo#ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY
android.view.accessibility.AccessibilityNodeInfo#ACTION_NEXT_HTML_ELEMENT
android.view.accessibility.AccessibilityNodeInfo#ACTION_PREVIOUS_HTML_ELEMENT
android.view.accessibility.AccessibilityNodeInfo#ACTION_SCROLL_FORWARD
android.view.accessibility.AccessibilityNodeInfo#ACTION_SCROLL_BACKWARD
android.view.accessibility.AccessibilityNodeInfo#ACTION_COPY//复制
android.view.accessibility.AccessibilityNodeInfo#ACTION_PASTE//粘贴
android.view.accessibility.AccessibilityNodeInfo#ACTION_CUT//剪切
android.view.accessibility.AccessibilityNodeInfo#ACTION_SET_SELECTION
android.view.accessibility.AccessibilityNodeInfo#ACTION_EXPAND
android.view.accessibility.AccessibilityNodeInfo#ACTION_COLLAPSE
android.view.accessibility.AccessibilityNodeInfo#ACTION_DISMISS
android.view.accessibility.AccessibilityNodeInfo#ACTION_SET_TEXT
android.view.accessibility.AccessibilityNodeInfo#LAST_LEGACY_STANDARD_ACTION
android.view.accessibility.AccessibilityNodeInfo#ACTION_TYPE_MASK
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_MOVEMENT_GRANULARITY_INT
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_HTML_ELEMENT_STRING
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_SELECTION_START_INT
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_SELECTION_END_INT
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_ROW_INT
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_COLUMN_INT
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_PROGRESS_VALUE
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_MOVE_WINDOW_X
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_MOVE_WINDOW_Y
android.view.accessibility.AccessibilityNodeInfo#ACTION_ARGUMENT_ACCESSIBLE_CLICKABLE_SPAN
2)全局回应可执行的操作
android.accessibilityservice.AccessibilityService#performGlobalAction(int action)
有
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_BACK//后退,相当于手机后退按键
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_HOME//回到手机HOME屏幕
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_RECENTS
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_NOTIFICATIONS
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_QUICK_SETTINGS
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_POWER_DIALOG
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_TOGGLE_SPLIT_SCREEN
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_LOCK_SCREEN
android.accessibilityservice.AccessibilityService#GLOBAL_ACTION_TAKE_SCREENSHOT
第三步.写个自动化测试DEMO应用。
下面贴部分对哈罗出行自动化测试抢单/找单的主要逻辑代码,HaloAccessibilityServiceV5.java
**第四步.**运行效果
部分Log日志与运行截图(如需完整源码安装包请邮件wangyetao_binary@126.com联系博主):
城际路线
2021-10-06 02:51:04.218 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [0]10月12日 10:00-10:15
2021-10-06 02:51:04.224 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [1]东莞市·华为(凤岗店)
2021-10-06 02:51:04.234 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [2]61.4km
2021-10-06 02:51:04.238 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [3]深圳市·深圳南北小筑客栈
2021-10-06 02:51:04.243 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [4]93.1
2021-10-06 02:51:04.252 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [5]元
2021-10-06 02:51:04.266 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [6]3人
2021-10-06 02:51:04.266 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [7]不拼车
2021-10-06 02:51:04.269 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: FreerideOrder{insertTime='1633459864266', pointoftime='10月12日 10:00-10:15', begin='东莞市·华为(凤岗店)', end='深圳市·深圳南北小筑客栈', fromkm=61.4, price=93.1, peopleNum=3, type='不拼车'}
市内路线
2021-10-06 02:52:32.808 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [0]明天 15:30-15:40
2021-10-06 02:52:32.818 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [1]距你12.6km
2021-10-06 02:52:32.822 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [2]石龙广场
2021-10-06 02:52:32.827 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [3]东莞市·南岗
2021-10-06 02:52:32.833 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [4]广州新华学院东莞校区(西门)
2021-10-06 02:52:32.837 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [5]62.7
2021-10-06 02:52:32.841 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [6]元
2021-10-06 02:52:32.849 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [7]已预付
2021-10-06 02:52:32.852 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [8]2人
2021-10-06 02:52:32.852 22973-22973/com.example.driverslanguage I/HaloAccessibilityServiceV5: [9]不拼车
在此记录与总结,2021年 10月 06日 星期三 02:29:23 CST。
免责声明:本程序仅为辅助点击工具与IT开发、测试人员之间交流学习使用,无任何黑科技功能,禁止用于任何违法违规行为,否则后果自负,请遵纪守法。
UPDATE2,完结版本
UPDATE2,完结版本,2021年 10月 29日 星期五 03:25:36 CST
部分软件截图
UPDATE3,衍生版本
UPDATE3,衍生版本,2021年 11月 04日 星期四 20:00:33 CST
v2.0.3.2
v2.0.3.2安装包下载
程序更新地址:
链接: https://pan.baidu.com/s/1D_q_43XaLQZtRCgQ6U-T5Q 密码: pu1s,gif录制的效果图片:
bilibili短视频 【诺亚方舟-哔哩哔哩】 https://b23.tv/Eht88x0
诺亚方舟2.1.5
添加短视频,2021年 12月 28日 星期二 03:52:03 CST。
版权归原作者 dnbug Blog 所有, 如有侵权,请联系我们删除。