导图社区 Auto.js安卓自动化工具
Auto.js导语、基础、语法、连接VS Code、函数、资源(常用代码、源码下载、教程)等,希望这份脑图会对你有所帮助。
编辑于2023-05-09 15:40:10 云南Auto.js安卓自动化工具
导语
脚本基于javascript,所以在写脚本方面代码难度较大
运行环境
非ROOT
android 7.0
打开无障碍
可以在代码开头加一行auto.waitFor();
功能是,获取无障碍服务权限
如果已经有了,那就继续运行下面的代码
如果没有,就跳转到给无障碍服务权限的界面
ROOT
Tap(x,y);用法和click(x,y);完全一样
基于root权限的操作并没有长按功能
Swipe(x1,x2,y1,y2,t);用法和swipe(x1,x2,y1,y2,t);完全一样
基础
变量
1.变量的创建-var
语法是:var 变量名=值
注意
不能已数字开头,变量名不可重复,不能和运行关键词while,for,if,try等等的单词完全相同。
中文变量名在js是可以用,但是不推荐使用。
构造函数
作用:在创建的时候,还有另一种情况我们需要先创建一个变量,但是在这时,我们还不知道这个变量的数值或者我们要定义的这个变量根本没有数值,但一定要规定数据类型。
语法是var 变量名=new 数据类型(传入值)
数组的构造函数:比如语句是var d=new Array()
么这边语句里传入值是空的呢?这种构造函数,在创建时候不需要传入任何值,被叫做无参构造函数
有参构造函数
需要传入创建出来的数组的长度
比如我要创建一个长度(整数类型)为5的数组(数组里面能放5个变量)名字叫e的数组,语句是var e=new Array(5)
当一个类有多个无参构造函数时,在创建的时候系统会根据你传入的值的个数和类型选择对应的构造函数。
2.基本数据类型
数字型(Number),
布尔型(Boolean),
true和false只有两个值
字符串型(String),
表示字符串的时候必须要注意用英文输入法的双引号套住
不明(Undefined)
空(null)等。
2.5 信息输出
日志(控制台)
console.log()
console.log("这是log");
白色文字
在Auto.js中封装成了全局函数
可以直接用语法:log(要输出的内容);来输出
作用:一般用来输出运行的普通信息
可以是任何类型的,但终究是用文字的形式表示出来。
日志打开方法:脚本编辑界面->右上角三个点->日志
console.info("分享成功!");
绿色文字
console.verbose("要输出的内容");颜色为灰色,一般用来打印不重要内容。
灰色
console.warn("要输出的内容");颜色为蓝色,一般用来打印运行警报。
蓝色
console.error("要输出的内容");颜色为红色,一般用来打印运行报错信息。
红色
气泡输出:语法:toast("要输出内容");
对话框输出:语法:alert("标题","内容");
3.变量赋值
3.5 代码规范
行级注释://注释内容
块级注释: /*注释内容*/
4.变量间的运算
相同数据类型间的
①字符串,字符串的拼接用加号进行运算。
②数字间加减乘除运算,乘号用*,除号用/
③布尔值运算
非:感叹号(!),感叹号的作用是布尔值取反,比如本来为true的数据类型,用了!值为false,本来为false的变为true。
都:&&,连接两个布尔值,如果两个值都为true,那么返回true,否则返回false
任意:||,连接两个布尔值,如果两个中有一个为true,那么整体返回true,否则返回false
返回不同数据类型间的
比如两个数字相同则返回true不同返回false,就是返回不同数据类型间的计算,关系运算符。
①判断是否相等,所有数据类型都可以使用
双等于号==,判断两个变量是否相同,连接两个变量,如果左右两个变量完全相同,则整体返回true,不同返回false。
感叹号等于号!=,判断两个变量是否不同,连接两个变量,如果左右两个变量,不同,返回true,相同则返回false。
②判断数字大小,只用于连接两个数字,返回布尔值
大于:> 小于:< 大于等于:>= 小于等于:<=
运算符
+=
A=A+B
-=
A=A-B
语句
判断
1.基本if语句
格式:if(判断内容){运行的代码块}
大括号括起来的内容,叫做一个代码块,用于放代码。
2.if else语句
语法:if(判断内容){true的运行代码}else{false的运行代码}
3.if-else if-else语句
if(第一个判断内容){第一个执行代码}else if(第二个判断内容){第二个执行代码}esle{其他情况的执行代码}
else if可以无限加
只要判断对就执行对应的执行语句,并结束整个else语句
如果不对就继续往下,一直到else
4.switch语句
语法: switch(变量){ case 值1: 运行代码1 break; case 值2: 运行代码2 break; default: 其他可能性运行的代码 break; }
注意!每个case后面运行的代码结束后一定要有break; 作者:Henry浩然 https://www.bilibili.com/read/cv1035858 出处:bilibili
5.代码规范 缩进
try...catch
作用
作用是测试代码中的错误。
try 语句允许我们定义在执行时进行错误测试的代码块。
catch 语句允许我们定义当 try 代码块发生错误时,所执行的代码块。
语法
try { //在此运行代码 } catch(err) { //在此处理错误 }
注意:
try...catch 使用小写字母。大写字母会出错。
err变量(可以自己任意定义)包含一个错误对象,详细说明了所发生的事情。
执行过程
1、首先,执行代码try {...}。
2、如果没有错误,则忽略catch(err){....},执行完try {...}后就跳过catch(err){....},直接执行下一条语句。
3、如果发生错误,则try停止执行,开始执行catch(err){...}。
语法
注释
单行注释://
代码段注释
/*
*/
弹出文字
toast("防息屏");
toastLog ('hallo word'); // 提示信息 + log 记录
log ('hallo word'); // 记录 log
弹出对话框
alert ("标题","内容"); // 对话框输出
箭头函数(arrow function):=>
是ES6标准中新增的一种新的函数
表达式的语法比函数表达式更简洁
没有自己的this,arguments,super或new.target
更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
格式
(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
相当于:(param1, param2, …, paramN) =>{ return expression; }
当只有一个参数时,圆括号是可选的:
(singleParam) => { statements }
singleParam => {statements }
没有参数的函数应该写成一对圆括号:
() => { statements }
函数体
箭头函数可以有一个“简写体”或常见的“块体”。
在一个简写体中,只需要一个表达式,并附加一个隐式的返回值。在块体中,必须使用明确的return语句。
var func = x => x * x; // 简写函数 省略return(简写体) var func = (x, y) => { return x + y; }; //常规编写 明确的返回值(块体) ———————————————— 版权声明:本文为CSDN博主「狗狗狗狗狗乐啊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_44122062/article/details/105330189
例:
(x) => x + 6
相当于
function(x){ return x + 6; }
x => x * x
即相当于: function (x) { return x * x; }
elements.map(element => element.length); // [8, 6, 7, 9]
// 当箭头函数只有一个参数时,可以省略参数的圆括号 elements.map(element => { return element.length; }); // [8, 6, 7, 9] // 当箭头函数的函数体只有一个 `return` 语句时,可以省略 `return` 关键字和方法体的花括号 elements.map(element => element.length); // [8, 6, 7, 9] ———————————————— 版权声明:本文为CSDN博主「狗狗狗狗狗乐啊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_44122062/article/details/105330189
forEach() 方法
也叫增强for循环,foreach其实是for循环的一个特殊简化版。
但是并不是说foreach就比for更好用
foreach适用于循环次数未知,或者计算循环次数比较麻烦情况下使用效率更高,但是更为复杂的一些循环还是需要用到for循环效率更高。
语法
array.forEach(function(currentValue, index, arr), thisValue)
连接VS Code
VS Code操作
安装中文语言包
打开VS Code,点击“扩展”图标。
搜索“chinese”,点击安装后,
等待安装成功,重启VS Code。
安装auto.js pro插件
打开VS Code,点击“插件图标”。
搜索autojs或者hyb1996,安装“Auto.js-Pro-Ext”,等待安装成功后重启VS Code。
注意,不需要安装下面的Auto.js-VSCodeExt,这是免费版Auto.js的扩展,当然安装了也不会冲突。
连接手机
确保手机和电脑在同一个局域网中。
以将手机和电脑都连到同一个Wifi上,或者电脑开启热点给手机连接,或者手机开启热点给电脑连接。
如果以上都无法做到,你还可以通过USB线连接手机,参考《adb连接手机(USB)》。
打开Auto.js Pro客户端,打开侧拉菜单,开启调试服务。
记住或复制这个IP地址,后面有用。
在VS Code中按快捷键
Ctrl + Shift + P
,弹出命令窗口,输入Pro,可以看到以下命令。
选择"Auto.js Pro: 连接到新设备"。
点击“输入设备IP地址”。
将步骤1的IP地址输入到这里,点击回车。
当VS Code右上角出现这个提示时,表示连接成功。
如果连接没有成功,请尝试暂时关闭Windows防火墙后重试。(关闭防火墙只是暂时的,为了安全起见,应该增加一个允许9317端口通过防火墙的规则)
adb连接手机(USB)
函数
环境
setScreenMetrics(width, height);
设置屏幕宽高
启动
launch ("app 包名"); // 通过包名启动 app 应用
实测:速度最快
launchApp ("名字"); // 通过 app 名字启动 app 应用
sleep(暂停)
sleep(10*60*1000);
10分钟
sleep (random (1000,5000)); // 随机等待 1 到 5 秒
自动化
注意:click,press,swipe只有安卓7.0及以上才可以使用
点击
click
click (x,y); // 单点击坐标,
click ("加好友"); // 点击 "加好友" 按钮
text ("属性值").findOne ().parent ().click ();
//parent 通过子控件查找父控件,常用于子控件不能点击,而通过子控件查找到父控件完成点击
遇到问题:文字的按键点击无效
原因:因为这些按钮上的文字并不是真正的文字,而是一个图标
例如QQ下方的"联系人"按钮,用click("联系人")是无效的
解决办法:如何点击图标按钮?
方法1:可以开启悬浮窗,选择布局范围分析,之后点击要点击的图标,在弹出的窗口中的"bounds"一栏即图标在屏幕上的区域
例如:通过id, desc等选择器来定位图片
方法2:录制脚本:通过图标在屏幕上的位置来点击
press
格式:press(x,y,t)
t
手机内一般认定半秒,即500毫秒的点击,是长按
默认为100
技巧
t设为1豪秒,可快速点击
可替代click
swipe(直线滑动)
语法:swipe(x1,x2,y1,y2,t)
(t:time 表示滑动的时间)
home(); // 回到桌面
back(); // 返回上一步
选择器
auto
id
id ("xxxx").find (); // 按元素 id 查找元素
className ("xxxx").find (); // 按元素类型查找
text
作用:获取控件的文本
text ("xxxx").find (); // 按控件文本查找,, 也可使用 findOne ()
例:等待文字出现
text("欢迎发表你的观点").waitFor();
text ("进入游戏").find ().click (); // 点击进入游戏 (先查找再点击)
text("欢迎").find()[0].parent().child(3).click();
查找text属性为欢迎的所有控件,选择第一个结果的父控件的第4个子控件进行点击。。
text ("属性值").findOne ().childCount (); // 获取控件中子控件的数量
text ("进入游戏").findOne (3000).click (); // 点击进入游戏___查询超时就报错,,(text () 是完全匹配)
textContains
作用:为当家选择器附加控件的筛选条件
textContains ("手机").find ().click (); // 匹配页面包含手机的元素
UiSelector
desc(str)
作用:返回选择器自身以便链式调用
控件的desc属性是对一个控件的描述
desc ("xxxx").find (); // 按描述信息查找
find()[0]
表示:找到组合中第一个控件
技巧
找不到控件是方法不对
可以用同层的其他能识别的控件,然后parent().child(索引)
textStartsWith ("手机").find ().click (); // 匹配以 "手机" 开头的元素
textEndsWith ("手机").find ().click (); // 匹配以 "手机" 结尾的元素
atextMatches ("\\d+"); // 以正则匹配
模块
App
打开链接
app.openUrl(url)
其它
app.uninstall ("包名"); // 卸载 app
getpackagename (' 应用名 '); // 通过应用名获取 app 包名
图像识别
百度OCR识别
//传入路径就可以使用 function Baidu_OCR(imgFile) { access_token = http.get("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=YIKKfQbdpYRRYtqqTPnZ5bCE&client_secret=hBxFiPhOCn6G9GH0sHoL0kTwfrCtndDj").body.json().access_token; url = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic" + "?access_token=" + access_token; imag64 = images.toBase64(images.read(imgFile)); res = http.post(url, {headers: {'Content-Type': 'application/x-www-form-urlencoded'},image: imag64,image_type: "BASE64",}); str = JSON.parse(res.body.string()).words_result.map(val => val.words).join('\n'); return str; }
资源
常用代码
一直等待,直到出现
while
while(!click("微信运动"))
等待并单击
while(!desc("学习").exists());//等待加载出主页
代码2:等待评论框
while(!textContains("欢迎发表你的观点").exists())//如果没有找到评论框则认为没有进入文章界面,一直等待 { delay(1); console.log("等待进入文章界面") }
id
等待按钮出现
id("activity_main_course").waitFor();
text
法宣在线:直到text“选修课”出现,就点击,否则循环等待
// 点击选修课 var btn_radio = text("选修课").findOne(); if (btn_radio) { btn_radio.click(); sleep(5000); }
className
var video = className ("android.widget.FrameLayout").find (); if (video) { video.click(); //sleep(5000); }
控件翻页
listView.scrollForward();//翻页
scrollDown()
点击指定区域
例1
while (true) { click(500, 380);}
例2:点击7次(for计次循环)
for (var i = 0; i < 7; i++) {click(500, 380);}
如何点击图标按钮(非文字)
获取图标在屏幕上的位置
开启悬浮窗,选择布局范围查看,之后点击要点击的图标,在弹出的窗口中的"bounds"一栏即图标在屏幕上的区域。
方法1:录制脚本(需ROOT)
1.0 脚本点的速度能不能快点
第一行代码前面加上auto("fast");
click改成press(500, 380, 50),50的意思是按住时间为50毫秒,越小越快。
微信
实现微信朋友圈点赞
评论=desc("评论").findOne(); log(评论); 评论.click(); sleep(1000); 赞 = text("赞").findOne(); 赞的父控件 = 赞.parent(); 赞的父控件.click();
步骤:
找到评论按钮
点击评论按钮
找到点赞按钮
点击点赞按钮
设备
设备解锁
auto.waitFor(); sleep(1000) device.wakeUpIfNeeded() //唤醒设备 sleep(1000); Swipe(500, 1700, 500, 500, 1500); //进入解锁 //上滑屏幕
源码下载
https://github.com/snailuncle/autojsDemo
学习强国
0.9 OSCHINA:bug小哥哥
优点
可滑动文章
xxqg-helper
教程
免费
2.0 【免root脚本制作教程】总览Auto.js(Auto.js使用教程)
收费
飞云脚本
500元
操作方式
基于控件的操作
依赖于“无障碍服务”
方式1(推荐方式):在脚本开头使用auto()函数
确保“无障碍服务启用”
方式2:也可在脚本开关使用"auto"
注意:必须在最开头
方式3:auto.waitFor();
语句增加是非常必要的这个在你没有无障碍时候会提示你无障碍模式的开启。并且开启之后,会接着继续运行.
(1)什么是控件?
控件可以有自己的属性和方法
属性
是控件数据的简单访问者
方法
是控件的一些简单而可见的功能
控件创建过程包括设计、开发、调试工作, 然后是控件的使用。
可以通过他们的属性用脚本获取到他们
也可以通过控件类的函数对他进行一定的操作和获取信息等
(2)我们如何获取到控件信息
通过悬浮窗
布局范围分析
可以直接看到当前页面上所有控件的边框即控件位置,这样可以清晰的了解各种控件的位置以及大小
缺点
比如有两个完全相同大小的控件重叠在一起就看不见了,这时候就要用到布局层次分析。
布局层次分析
根据软件当前页面的源码布局层次进行观察
以看到所有控件及其层次
缺点
对于比较复杂的布局很难进行观察,毕竟内容较多,距离远的话难以比较
技巧
所以在布局层次和布局范围中进行切换查看是比较好的获取控件信息的方法。
控件属性
主要的
id即控件的id属性
text控件的文本属性
注意
有些控件会把text控件放空,并把上面的文本写入desc值
bounds控件的边框位置
desc控件的desc值
clickable/longClickable控件是否可以点击/长按
如果控件的clickable为false那么点击也没用
checked控件是否选中
depth在第几层次
indexInParent在父控件中是第几个
生成代码
一般情况只会选择最简洁的代码
和我们需要实现的功能可能会稍有偏差,需要我们人为进行修改
比较复杂的布局暂时可能会有获取失败的情况
2.如何写控件操作脚本,控件操作的脚本编程思想是什么?
要对一个控件进行操作,首先我们要让脚本识别的那个函数
在js的基于空间的操作中有三大类:
控件选择器,控件合集,控件
这三个类都有各自的方法
id(),text(),.findOne(),.click()分别都是上面那三个类中的函数
id()这个函数是控件选择器的函数
可以直接作为脚本开头(全局函数)
返回值还是控件选择器,所以后面接的函数还是控件选择器的函数,
text()
返回值还是控件选择器,所以后面继续接控件选择器的函数findOne()然后这个函数的返回值是控件,所以后面接控件的函数click()
总结:我们写控件操作的代码时,不但·要实现需要实现的功能,还要注意返回值和之后使用的函数,以及如何切换来实现需要的功能。
3.控件选择器
含有对控件进行筛选的功能
常用控件选择器函数的使用方法
例子
假如有desc属性为ab,abcd,abcde,cde,cd
选择器desc()也就是匹配desc值为传入字符串的控件
desc("cd")这样子的话只会匹配出上面desc值为cd的一个控件
用descContains("cd"),desc属性包含传入的字符串的话,那就能匹配出desc值为abcd,abcde,cde,cd的控件
descStartsWith()和descEndsWith()即为分别匹配以传入的字符串开头或者结尾的·desc值的控件
descMatches(正则表达式),这个用于传入正则表达式
性数据类型是字符串的控件都有着五个选择器函数进行选择
text() , textContains() , textStartsWith() , textEndsWith() , textMatches() , id() , idContains() , idStartsWith() , idEndsWith() , idMatches() ,还有className,package等
布尔值的属性的筛选器
clickable属性的选择器函数clickable(要匹配的找值)
可以作为全局函数
clickable(true)这个函数就可以筛选当前页面上所有可以点击的控件
checkable()控件是否可以勾选
selected()控件是否已经勾选
longClickable()控件是否可以长按
enabled()控件是否已经启用
scrollable()控件是否可以滑动
editable()控件是否可以编辑
例子
要写一个选择器筛选当前页面上可以点击,长按的控件,
clickable(true).longClickable(true)
像QQ那种故意的,所有属性要么没有,要么都一样
可以用控件的边框位置来进行筛选
主要有两个比较常用的函数,bounds()和boundsInside()
要传入的变量就是控件的位置范围,由四个整数值组成
前两个值为控件长方形左上角的坐标,后两个值是控件右下角点的坐标。
boundsInside(233,233,666,666)
这个框内部的所有·控件会全部筛选出来
bounds()这个函数相对来说不算很常用
作用是匹配出边框是传入的四个值的控件,必须完全一样,
在很多属性都一样的时候,这个功能非常的常用,因为bounds属性完全相同的控件就是完全重叠的那些,一般都只有一个
很大的缺点那就是做适配功能很难,在·两个分辨率不同的手机上大部分控件的bounds是完全不一样的
所以这个功能一般用于特定分辨率,不需要适配的脚本中。
drawingOrder()
用于筛选控件在其父控件中是否是第某个
可以作为全局函数使用
drawingOrder(0)
筛选出所有在父控件中的第一个控件
当然最外层的布局也是第0个
并且从筛选触来的内容角度来说,最外层控件肯定在第一个·,那直接使用findOne()就可以直接获取到UI外层控件了。
过滤函数-最强的万能选择器函数-
传入的内容是一个返回布尔值的匿名函数
函数的传入值是当前符合的所有控件
会把会让函数返回值为false的内容全部过滤掉
例子
过滤出text属性有10个字符的控件
代码是filter(function(w){return w.text().length==10})
function是新函数的意思
return在函数中即是函数的结束也是函数返回内容的代码
函数中先获取了控件w,即传入进来的控件的一个,的·text属性(即后面要讲的控件.text(),获取控件信息的函数)
这个属性值是字符串
可以用length属性来获取到他的长度,
然后用关系运算符 == (作用是比较左右两边内容是否相同,相同返回true,不同false)把他和我们要过滤出来的10进行比较
即他最后返回的布尔值数据类型
然后他会过滤出那些所有返回值为true,即符合的控件。
注意:
现在开始说的函数都不能作为全局函数放在开头使用
最主要常见的函数就是findOne()了
他的作用是寻找屏幕上符合前面控件选择器的函数,直到出现,并返回第一个出现的控件
外他还可以传入一个参数—最大查找时间
如果到了时间还没有找到的话,直接返回undifined,以继续脚本。
他相似的还有一个函数是findOnce(),不同于之前那个函数,这个函数只会寻找一次,如果当前屏幕上没有,则直接返回null,他也可以传入一个参数
4.控件
可以获取到控件信息的函数
最主要有text(),desc(),id()
相同的还有classname,clickable,packagename等等,所有悬浮窗中有的属性都可以直接这样用函数获取到。
className就更多重复的了
childCount()用来返回这个控件有多少个子控件
drawingOrder()用语返回他他在父控件中的绘制顺序
bounds
可以对控件做出操作
函数click()就可以直接点击一个控件
clickable的值为false,那点击效果是没有用的
1.0 如果明明是个按钮控件,clickable值却是false那,一般,切换到布局层次可以看到有和他重叠的clickable值为true的控件。
判断
当 clickable = true 时候,直接使用控件click();
当 clickable = false 时候(无法直接直接点击),利用bounds找中心点坐标,然后使用click(x,y) 或press(x,y, 100); 100ms
longClick()长按
setText()设置输入框内内容
例子
要把id为edit的输入框控件内的文字改为123456
代码为id("edit").findOne().setText("123456");
setText ("城南花已开") ; // 在光标处输入数据
可以用来找到与这个控件有关的控件的函数
比如他的父控件和他的子控件
安卓的控件是由控件多层嵌套出来的,所以控件可以含有他的子控件,也有他的父控件(最外层不算)。
通过控件函数.parent()可以获得到这个函数的父控件函数
通过child(第几个),获取到他的第几个子控件,注意序号从零开始。
children()用于返回这个控件的所有子控件
findByText(str)需要传入一段文
这个函数返回他所有子控件或者孙控件中text或者desc属性中包含这段文字的所有控件
5.控件合集
控件集合
他的底层类似于一个控件数组,可以存放多个控件
也可以用上一章讲的中括号下标的方法来获取到其中第几个控件
也可以用控件合集里的get(下标)函数来获取
还有就是size()获取合集大小
即为里面有多少个控件
和数组的length属性相同
是一个类
继承数组类
也就是有所有数组里的功能和属性
也有自己的新函数
对控件的操作,比如点击 长按 选中之类的功能,这里控件合集也能用
比如点击一个控件合集,他会自动按顺序点击控件合集里的每一个控件
内部有一个自动遍历数组的功能each(遍历函数) 里面传入一个函数,写对每个控件的操作,这个函数的参数是控件。
这样不需要自己写循环来遍历方便了很多。
总结
首先,最基本的就是通过控件选择器根据控件的独特特点是筛选出要操作的控件
再用函数转换成合集或者控件
最后再用控件的函数对其进行操作或者获取信息,具体方法根据实际情况而定