安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView
因蚂蚁森林界面UI更新,本方法原理已失效
于2020年11月30日 更新
应用界面
前言
最初,我有一个朋友问我能不能有办法监听到另一个App界面的内容,一旦有特定的消息出现就提醒用户,就这样,我接触到了AccessibityService。这个项目很好写,所以很快就实现了。主要是那个app结点都能直接获取到,也都能点击。有一天,我收蚂蚁森林能量,好友比较多,就在想,我能不能写一个基于AccessibilityService的自动收集能量的应用,造福一下懒人
运行效果
APP已放在末尾,欢迎大家测试
所用技术
AccessibilityService + 多线程 + 手势
项目开始
实现逻辑
说明
所有判断页面是否加载完成,用户名是否匹配的操作都是在开辟的子线程(图中橙色部分)中进行,主线程的MainHandler 接收来自子线程发送的消息,进行处理。
一些问题的解决
一、怎么获得webView中的结点信息
二、怎么判断webView加载完成了
三、怎么点击按钮
第一个问题,webView就像浏览器一样,里面的内容是网页的内容。
在webView中,所有的通过搜索获取结点List的方法失效了,但是可以通过不停地得到子节点、判断、得到子节点、判断的方法粗略的得到结点信息。
可以借助安卓的 uiautomatorviewer 工具查看结点树,但是这里的结点树也可能和实际运行的有点点出入,主要是webview 加载成功和不成功 之间有些变化,其他的结点结构是固定的,所以可取。
我是用dfs的方式得到webView的结点
private AccessibilityNodeInfo returnWebView(AccessibilityNodeInfo nowNode){if(nowNode==null) return null;if(nowNode.getClassName().toString().equals("android.webkit.WebView")){return nowNode;}if(nowNode.getChildCount()==0) return null;int size = nowNode.getChildCount();AccessibilityNodeInfo webViewNode = null;for(int i=0;i<size;i++){webViewNode = returnWebView(nowNode.getChild(i));if(webViewNode!=null) return webViewNode;}return null;
}
UIautomatorviewer具体怎么使用网上有很多博客,就不说了
第二个问题,怎么判断webView是否加载完成。
老实说,没有特别好的办法。你看一般的浏览器加载网页,有些时候加载的快,有些时候加载得慢,网页上很多东西的加载都是异步的。我很难准确的找到一个判定条件说网页绝对加载完成了。我用的办法是子线程判断关键信息是否加载完成了,只要我要点击的按钮加载完成了,就判定webView加载完成了。
private void LoadingForest(){//判定已载入的规则:只包含能量的view节点子孩子数大于等于4new Thread(new Runnable() {@Overridepublic void run() {debug("加载蚂蚁森林...");Message message = Message.obtain();int MaxCount = MAX_REQUEST_TIME;WebViewNode = null;while(MaxCount > 0 ){MaxCount--;sleep(500);rootNode = getRootInActiveWindow();//Frameif(rootNode==null || rootNode.getChildCount()==0) continue;WebViewNode = returnWebView(rootNode);if(WebViewNode==null || WebViewNode.getChildCount()==0) continue;nowNode = WebViewNode.getChild(0);if(nowNode==null || nowNode.getChildCount()==0) continue;nowNode = nowNode.getChild(0);if (nowNode==null || nowNode.getChildCount()<3) continue;nowNode = nowNode.getChild(2);
// dfs(nowNode);if(nowNode.getChildCount()>=4) break;}if(MaxCount==0){message.what = -1;}else{message.what = 6;}MainHandler.sendMessage(message);}}).start();
}
第三个问题 ,怎么点击
通过手势,可以实现滑动 和点击
滑动
private void scroll(){new Thread(new Runnable() {@Overridepublic void run() {int sx = (nowUserEntrance.left+nowUserEntrance.right)>>1;int sy = nowUserEntrance.bottom;int ey = nowUserEntrance.top-21;dispatchGestureScroll(2,sx,sy,sx,ey);sleep(100);Message message = Message.obtain();message.what = 10;MainHandler.sendMessage(message);}}).start();
}private void dispatchGestureScroll(final int flag, int sx, int sy,int ex,int ey) {// debug("sx:"+sx+"sy:"+sy+"ex:"+ex+"ey:"+ey);GestureDescription.Builder builder = new GestureDescription.Builder();Path p = new Path();p.moveTo(sx, sy);p.lineTo(ex, ey);builder.addStroke(new GestureDescription.StrokeDescription(p, 0L, 100L));GestureDescription gesture = builder.build();dispatchGesture(gesture, new AccessibilityService.GestureResultCallback() {@Overridepublic void onCompleted(GestureDescription gestureDescription) {super.onCompleted(gestureDescription);Log.d(TAG, flag+"onCompleted: 完成..........");}@Overridepublic void onCancelled(GestureDescription gestureDescription) {super.onCancelled(gestureDescription);Log.d(TAG, flag+"onCompleted: 取消..........");}}, null);
}
点击
/*** 模拟点击事件* @param flag 点击的控件类型(1 能量) (0 用户入口)* @param x 横坐标* @param y 纵坐标*/
private boolean dispatchGestureView(final int flag, int x, int y) {boolean res = false;GestureDescription.Builder builder = new GestureDescription.Builder();Path p = new Path();p.moveTo(x, y);p.lineTo(x, y);builder.addStroke(new GestureDescription.StrokeDescription(p, 0L, 100L));GestureDescription gesture = builder.build();Log.d("","点击了位置"+"("+x+","+y+")");sleep(200);res = dispatchGesture(gesture, new GestureResultCallback(){}, null);return res;
}
关于点击
为什么不直接用
Node.performAction(AccessibilityNodeIndo.CLICK)
来点击呢。呵,最初我就是这么做的,而且UIautomatorviewer也显示该按钮的clickable是true 但是就是点不了呀,后来研究了一下,发现安卓的按钮还有
btn.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {//点击事件return false;}
});
来实现点击事件,注意这里的return false ,返回false的时候,点击按钮onClick和onTouch 都会执行,而当返回true的时候,只有onTouch会执行。所以我打算用OnTouch来实现点击事件,蚂蚁森林能给我的只有按钮的坐标,通过给指定坐标的View分发TouchEvent
/*** 模拟点击事件* @param x 横坐标* @param y 纵坐标*/
private void onTouchClick(int x,int y){final long downTime = SystemClock.uptimeMillis();View b1 = findViewById(R.id.button);Log.d("","onTouchClick");MotionEvent downEvent = MotionEvent.obtain(downTime,downTime, MotionEvent.ACTION_DOWN,x,y,0);MotionEvent upEvent = MotionEvent.obtain(downTime,SystemClock.uptimeMillis(), MotionEvent.ACTION_UP,x,y,0);b1.dispatchTouchEvent(downEvent);b1.dispatchTouchEvent(upEvent);downEvent.recycle();upEvent.recycle();
}
理论上可以通过坐标来获取view,网上有方法。但是我试了很多办法也获取不到第三方的AppDecorView
,因为连第三方的Activity
实例都获取不到。我当时卡了好久,差点想放弃这个项目,因为连点击都不能实现还怎么收能量。。
幸好,后来发现了手势也可以实现点击,才使得前面的努力没有白费。
想要了解更多,您也可以看看续篇
蚂蚁森林自动收集能量(续)
安卓AccessibilityService实现蚂蚁森林自动收集能量 最新 多线程 + 手势 + 深搜webView相关推荐
- Python 蚂蚁森林自动收集能量脚本
不需要root权限,不需要xposed框架支持 演示视频 加好友一起偷能量吗(疯狂暗示) 1962976634@qq.com 1.原理 使用adb指令模拟操作屏幕 2.准备 2.1 安装python3 ...
- 如何使用 AccessibilityService 实现蚂蚁森林自动收取能量,无需Root,无需连接电脑
如何使用 AccessibilityService 实现蚂蚁森林自动收取能量,无需Root,无需连接电脑 AccessibilityService 设计初衷在于帮助残障用户使用android设备和应用 ...
- auto.js蚂蚁森林收能量
auto.js蚂蚁森林收能量 在网上看了一些自动收能量的脚本 写了一个脚本 使用AutoJs运行 AutoJS下载地址 :here 运行步骤如下: 1.解锁(点亮屏幕,切换到输入密码界面,输入密码) ...
- iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手
iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手 前言 发现iOS支付宝逆向的分析并不多,蚂蚁森林基于H5应用 套着UIWebView 基本也没这类JS和原生交互分析的帖子,就拿此练手吧 作技术分享 ...
- 模拟蚂蚁森林的能量产生过程
模拟蚂蚁森林的能量产生过程 for i in range(100):print(""" 能量查询请输入能量来源!退出程序请输入0 能量来源如下: 生活缴费.行走捐.共享单 ...
- Python+uiautomator2定时偷取蚂蚁森林好友能量
文章目录 前言 一.系统环境 二.使用步骤 1.引入库 2.电脑连接手机并打开支付宝软件 3.aircv图片识别 4.收取自己的能量 5.跳转到好友能量 6.收取好友能量 7.能量雨代码求助 三.完整 ...
- iphone快捷指令蚂蚁森林能量_iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手...
iOS逆向-手把手教你写支付宝蚂蚁森林收集能量助手 前言 发现iOS支付宝逆向的分析并不多,蚂蚁森林基于H5应用 套着UIWebView 基本也没这类JS和原生交互分析的帖子,就拿此练手吧 作技术分享 ...
- 蚂蚁森林给别人浇水能量不足怎么解决 蚂蚁森林增加能量方法
现在支付宝中已经退出了很多公益小游戏,比如蚂蚁庄园和蚂蚁森林了.玩过蚂蚁森林中的朋友们都知道在森林中可以给别人浇水,蚂蚁森林给别人浇水能量不足怎么解决 蚂蚁森林增加能量方法,但是如果遇到了浇水能量不足 ...
- AccessibilityService 进行蚂蚁森林能量收集 demo
1. 原理 基于 AccessibilityService 模拟辅助功能 2. Demo下载 https://github.com/sufadi/AccessibilityServiceMonitor ...
最新文章
- HSV的数据结构各分量H S V的直观理解其实就是对应图片位置的的像素一一对应的矩阵表示
- linux命令之查看动态库符号-nm
- Linux——进程控制(总结)
- explicit关键字详解(C++ )
- 数据结构与算法--二叉树实现原理
- Android入门(12)| 数据持久化
- python复制代码会被发现吗,我发现了一个记忆代码片段,我想知道它在复制。复制...
- C/C++ 中的指针
- gcc和arm-linux-gcc区别
- html5d调用百度语音,易语言调用百度语音平台实现文字转换语音功能的代码
- 注释驱动的 Spring cache 缓存介绍
- README.md怎么写比较好
- Android中ListView复用导致布局错乱的解决方案
- “站长也疯狂,开车盛宴”——如何选择运维产品
- android httpclient 设置超时
- 计算机 在电厂的应用,计算机自动控制系统在火电厂中的应用
- 数学建模学习:因子分析
- ORB-SLAM2安装以及遇到问题
- 友情链接对网站优化有什么作用
- matlab编写多目标测试函数SCH, ZDT, MOP, DTLZ