一、vscode环境配置快速启动、调试
【前置条件】:优先开启物障碍模式 左上角功能按钮->无障碍快捷方式->更多下载的服务 【根据不同的app】
1、vscode 插件: Auto.js-VSCodeExt 安装 (注意插件一定要选对!)
2、按 Ctrl+Shift+P 或点击"查看"->"命令面板"可调出命令面板,输入 Auto.js 可以看到几个命令,移动光标到命令Auto.js: Start Server,按回车键执行该命令。
3、启动auto js start server 后vscode 右下角会显示ip :端口
4、打开手机auto.js 功能页,选择连接电脑,输入上面的ip地址若无,可通过cmd窗口ipconfig获取
二、全局方法
waitForPackage(package[, period = 200])//等待指定的应用出现。
waitForPackage("com.tencent.mm")//例如等待当前界面为微信
waitForActivity(activity[, period = 200])//等待指定的Activity出现,period为检查Activity的间隔。
waitForActivity("com.ss.android.ugc.aweme.following.ui.FollowRelationTabActivity")//等待抖音其他用户的关注列表页面出现:
sleep(n)//毫秒数
log("message")//打印日志
toast("message")//气泡提示
toastLog("message")//打印日志并气泡提示
setClip("text")//设置剪贴板内容
exit()//立即停止脚本运行
random(min, max)//随机数
三、应用方法
launch("包名")//通过包名启动应用
launchPackage("包名")//通过包名启动应用
launchApp(appName)//通过名称启动应用
getPackageName(appName)//获取应用名称对应的已安装的应用的包名
getAppName("包名")//获取应用包名对应的已安装的应用的名称
app.openAppSetting("包名")//打开应用的详情页(设置页)。返回false; 否则返回true(全局)
app.editFile("/sdcard/1.txt/);//用其他应用编辑文件文本文件
app.uninstall("com.tencent.mobileqq");//卸载应用
app.openUrl("包名");//浏览器打开网站,Url,如果不以"http://"或"https://“开头则默认是"http://”
四、坐标方法
setScreenMetrics(width, height)在width*height的设备中,坐标操作自适应
width {number} //屏幕宽度,单位像素
height {number} //屏幕高度,单位像素
click(x, y)//点击
longClick(x, y)//长按
press(x, y, duration)//按住
swipe(x1, y1, x2, y2, duration)//滑动
swipeEx(x1, y1, x2, y2, duration)//仿真随机曲线滑动
gesture(duration, [x1, y1], [x2, y2], …)//手势路径,时长2s
gestures([delay1, duration1, [x1, y1], [x2, y2], …], [delay2, duration2, [x3, y3], [x4, y4], …], …)//延时多点手势路径
五、控件方法
5.1、 文本控件
setText([i, ]text)//输入框的文本置为text//返回是否输入成功。当找不到对应的文本框时返回false。//i表示i + 1个输入框
input([i, ]text)//输入框文本追加内容text//返回是否输入成功。当找不到对应的文本框时返回false。//i表示i + 1个输入框
click(text[, i])//点击大部分包含文字的按钮
while(!click("扫一扫"));//通常与while同时使用以便点击按钮直至成功
longClick(text[, i]))//长按文本
5.2、滑动控件
scrollUp([i])//找到第i+1个可滑动控件上滑或左滑。
scrollDown([i])//找到第i+1个可滑动控件下滑或右滑
className("ImageView").depth(10).findOne().click()//多条件定位点击
5.3、选择器控件
UiSelector.text(str)//text控件str
UiSelector.textContains(包含)//包含
UiSelector.textStartsWith(前缀)//前缀
UiSelector.textEndsWith(后缀)//后缀
UiSelector.textMatches(正则)//正则
UiSelector.desc(str)//desc控件str
UiSelector.descContains(前缀)//前缀
UiSelector.descStartsWith(prefix)//
UiSelector.descEndsWith(suffix)//
UiSelector.descMatches(正则)//正则
UiSelector.id(str)//id控件str
UiSelector.idContains(包含)//包含
UiSelector.idStartsWith(前缀)//前缀
UiSelector.idEndsWith(后缀)//后缀
UiSelector.idMatches(正则)//正则
UiSelector.className(str)//className控件str
UiSelector.classNameContains(包含)包含
UiSelector.classNameStartsWith(前缀)//前缀
UiSelector.classNameEndsWith(后缀)//后缀
UiSelector.classNameMatches(正则)为正则
UiSelector.packageName(str)packageName控件str
UiSelector.packageNameContains(包含)包含
UiSelector.packageNameStartsWith(前缀)//前缀
UiSelector.packageNameEndsWith(后缀)//后缀
UiSelector.packageNameMatches(正则)//正则
(左边距;上边距;下边距;右边距)
UiSelector.bounds(left, top, right, buttom)//定位控件的bounds属性为屏幕上显示的范围。
UiSelector.boundsInside(left, top, right, buttom)在参数构成的范围里面查找符合条件的控件。用于限制选择器在某一个区域选择控件。
UiSelector.boundsContains(left, top, right, buttom)在参数构成的范围里面查找符合条件的控件。用于限制控件的范围必须包含所给定的范围。
UiSelector.drawingOrder(number)//为一个控件在父控件中的绘制顺序,通常可以用于区分同一层次的控件。为当前选择器附加控件"drawingOrder等于order"的条件。
UiSelector.clickable([b = true])为当前选择器附加控件是否可点击的条件。类名为android.view.View的控件大多可点击
UiSelector.longClickable([b = true])为当前选择器附加控件是否可长按的条件。
UiSelector.checkable([b = true])为当前选择器附加控件是否可勾选的条件。
UiSelector.selected([b = true])为当前选择器附加控件是否已选中的条件。
UiSelector.enabled([b = true])为当前选择器附加控件是否已启用的条件。
UiSelector.scrollable([b = true])为当前选择器附加控件是否可滑动的条件。可以用这个条件来寻找可滑动控件来滑动界面。
UiSelector.editable([b = true])为当前选择器附加控件是否可编辑的条件;一般来说可编辑的控件为输入框(EditText)但不是所有
UiSelector.multiLine([b = true])为当前选择器附加控件是否文本或输入框控件是否是多行显示的条件。
UiSelector.findOne()对屏幕上的控件进行搜索,找不到控件,当屏幕内容发生变化时会重新寻找,直到屏幕上出现并返回该控件。未出现则阻塞
UiSelector.findOne(timeout)毫秒的时间内没有找到终止搜索并返回null
UiSelector.findOnce()对屏幕上的控件进行搜索,只找一次;返回第1个符合条件的控件;否则返回null
UiSelector.findOnce(i)对屏幕上的控件进行搜索,只找一次;返回第 i + 1 个符合条件的控件;否则返回null
UiSelector.find()对屏幕上的控件进行搜索,找到所有满足条件的控件集合并返回。只进行一次
empty()函数判断找到的是否为空
UiSelector.untilFind()对屏幕上的控件进行搜索,直到找到至少一个满足条件的控件为止,并返回所有满足条件的控件集合。
UiSelector.exists()判断屏幕上是否存在控件符合选择器所确定的条件;一般搭配if使用
UiSelector.waitFor()等待屏幕上出现符合条件的控件;在满足该条件的控件出现之前,该函数会一直保持阻塞。
UiSelector.filter(f)为当前选择器附加自定义的过滤条件。
六、UiSelector选择器
6.1、控件属性
className 类名。类名表示一个控件的类型,例如文本控件为"android.widget.TextView", 图片控件为"android.widget.ImageView"等。
packageName 包名。包名表示控件所在的应用包名,例如QQ界面的控件的包名为"com.tencent.mobileqq"。
bounds 控件在屏幕上的范围。
drawingOrder 控件在父控件的绘制顺序。
indexInParent 控件在父控件的位置。
clickable 控件是否可点击。
longClickable 控件是否可长按。
checkable 控件是否可勾选。
checked 控件是否可已勾选。
scrollable 控件是否可滑动。
selected 控件是否已选择。
editable 控件是否可编辑。
visibleToUser 控件是否可见,可以筛选在屏幕可视范围内的组件。
enabled 控件是否已启用。
depth 控件的布局深度。
6.2、 控件类型
android.widget.TextView//文本控件
android.widget.ImageView//图片控件
android.widget.Button//按钮控件
android.widget.EditText//输入框控件
android.widget.AbsListView//列表控件
android.widget.LinearLayout//线性布局
android.widget.FrameLayout//帧布局
android.widget.RelativeLayout//相对布局
android.widget.RelativeLayout//相对布局
android.support.v7.widget.RecyclerView//通常也是列表控件
七、选择器操作
exits() 判断控件是否存在
waitFor() 等待控件出现
UiObject.click()//点击该控件,并返回是否点击成功。
UiObject.longClick()//长按该控件,并返回是否点击成功。
UiObject.setText(text)//设置输入框控件的文本内容,并返回是否设置成功。
UiObject.copy()//对输入框文本的选中内容进行复制,并返回是否操作成功。
UiObject.cut()//对输入框文本的选中内容进行剪切,并返回是否操作成功。
UiObject.paste()//对输入框控件进行粘贴操作,把剪贴板内容粘贴到输入框中,并返回是否操作成功。
UiObject.setSelection(start, end)//对输入框控件设置选中的文字内容,并返回是否操作成功。
UiObject.scrollForward()//对控件执行向前滑动的操作,并返回是否操作成功。
UiObject.scrollBackward()//对控件执行向后滑动的操作,并返回是否操作成功。
UiObject.select()//对控件执行"选中"操作,并返回是否操作成功。"选中"和isSelected()的属性相关
UiObject.collapse()//对控件执行折叠操作,并返回是否操作成功。
UiObject.expand()//对控件执行操作,并返回是否操作成功。
UiObject.show()//对集合中所有控件执行显示操作,并返回是否全部操作成功。
UiObject.scrollUp()//对集合中所有控件执行向上滑的操作,并返回是否全部操作成功。
UiObject.scrollDown()//对集合中所有控件执行向下滑的操作,并返回是否全部操作成功。
UiObject.scrollLeft()//对集合中所有控件执行向左滑的操作,并返回是否全部操作成功。
UiObject.scrollRight()//对集合中所有控件执行向右滑的操作,并返回是否全部操作成功。
children()//返回该控件的所有子控件组成的控件集合。可以用于遍历一个控件的子控件
childCount()//返回子控件数目。
parent()//返回该控件的父控件。如果该控件没有父控件,返回null。
bounds()//返回控件在屏幕上的范围,其值是一个Rect对象。
boundsInParent()//返回控件在父控件中的范围,其值是一个Rect对象。
drawingOrder()//返回控件在父控件中的绘制次序。
id()//获取控件的id,如果一个控件没有id,则返回null。
text()//获取控件的文本,如果控件没有文本,返回""。
findByText(str)//根据文本text在子控件中递归地寻找并返回文本或描述(desc)包含这段文本str的控件,返回它们组成的集合。
findOne(selector)//根据选择器selector在该控件的子控件、孙控件…中搜索符合该选择器条件的控件,并返回找到的第一个控件;如果没有找到符合条件的控件则返回null。
find(selector)//根据选择器selector在该控件的子控件、孙控件…中搜索符合该选择器条件的控件,并返回它们组合的集合。
UiCollection//控件集合, 通过选择器的find(), untilFind()方法返回的对象。
UiCollection.size()//返回集合中的控件数。历史遗留函数,相当于属性length。
UiCollection.get(i)//返回集合中第i+1个控件(UiObject)。历史遗留函数,建议直接使用数组下标的方式访问元素。
UiCollection.each(func)//遍历集合。历史遗留函数,相当于forEach。参考forEach。
empty()//返回控件集合是否为空。
nonEmpty()//返回控件集合是否非空。
UiCollection.find(selector)//根据selector所确定的条件在该控件集合的控件、子控件、孙控件…中找到所有符合条件的控件并返回找到的控件集合。
UiCollection.findOne(selector)//根据选择器selector在该控件集合的控件的子控件、孙控件…中搜索符合该选择器条件的控件,并返回找到的第一个控件;
如果没有找到符合条件的控件则返回null。
八、按键模拟
back()返回
home()Home键
recents()显示最近任务
powerDialog()电源键菜单
notifications()拉出通知栏
quickSettings()显示快速设置(下拉通知栏到底)
splitScreen()分屏
九、常用功能函数
sleep(n)暂停运行n毫秒,常见的情况是,软件的运行速度“跟不上”脚本,因此需要一定时间的等待(尤其是需要点击的控件以滑动的方式进入,若不等待可能点击不到)
toast(message)显示气泡信息
log(message)在控制台中输出信息
toastLog(message)上面两个函数的合体
exit()立即停止脚本运行
十、阿里系滑块实战
/*
滑块地址:https://ditu.amap.com/detail/get/detail?id=B0014014AD
*/
var y = 1305 //设置滑动按钮高度
//设置随机滑动时长范围
var timeMin= 1500
var timeMax= 4500
//显示控制台-测试便于观察控制台
// console.show()
// console.setPosition(200, 200)
//启动
start()
function start() {
auto.waitFor()
while(true){
var slider_page = text('亲,请拖动下方滑块完成验证').findOnce();
var slider_exists = text('向右滑动验证').findOnce();
if (slider_page != null){
// sleep(10000)
if (slider_exists != null){
log('ex slider!')
trigger_slider()
}else{
log('fail ex slider!')
trigger_slider()
}
}else{
log('not ex slider!')
}
sleep(5000)
// console.hide()
}
}
function refresh(){
if(text('刷新').findOnce()){
text('刷新').findOne().click();
}
}
function trigger_slider(){
randomSwipe(200, y, 900, y) // 滑块起始、终点值,y轴值固定
}
function open_slider(){
launchApp("浏览器");
app.openUrl("https://ditu.amap.com/detail/get/detail?id=B0014014AD")
sleep(6000)
}
function bezierCreate(x1,y1,x2,y2,x3,y3,x4,y4){
//构建参数
var h=100;
var cp=[{x:x1,y:y1+h},{x:x2,y:y2+h},{x:x3,y:y3+h},{x:x4,y:y4+h}];
var numberOfPoints = 100;
var curve = [];
var dt = 1.0 / (numberOfPoints - 1);
//计算轨迹
for (var i = 0; i < numberOfPoints; i++){
var ax, bx, cx;
var ay, by, cy;
var tSquared, tCubed;
var result_x, result_y;
cx = 3.0 * (cp[1].x - cp[0].x);
bx = 3.0 * (cp[2].x - cp[1].x) - cx;
ax = cp[3].x - cp[0].x - cx - bx;
cy = 3.0 * (cp[1].y - cp[0].y);
by = 3.0 * (cp[2].y - cp[1].y) - cy;
ay = cp[3].y - cp[0].y - cy - by;
var t=dt*i
tSquared = t * t;
tCubed = tSquared * t;
result_x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
result_y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
curve[i] = {
x: result_x,
y: result_y
};
// log("轨迹计算"+'x:'+result_x+'y:'+result_y)
}
//轨迹转路数组
var array=[];
for (var i = 0;i<curve.length; i++) {
try {
var j = (i < 100) ? i : (199 - i);
xx = parseInt(curve[j].x)
yy = parseInt(Math.abs(100 - curve[j].y))
} catch (e) {
break
}
array.push([xx, yy])
}
return array
}
/**
* 真人模拟滑动函数
*
* 传入值:起点终点坐标
* 效果:模拟真人滑动
*/
function randomSwipe(sx,sy,ex,ey){
//设置控制点极限距离
var leaveHeightLength=500
//根据偏差距离,应用不同的随机方式
if(Math.abs(ex-sx)>Math.abs(ey-sy)){
var my=(sy+ey)/2
var y2=my+random(0,leaveHeightLength)
var y3=my-random(0,leaveHeightLength)
var lx=(sx-ex)/3
if(lx<0){lx=-lx}
var x2=sx+lx/2+random(0,lx)
var x3=sx+lx+lx/2+random(0,lx)
}else{
var mx=(sx+ex)/2
var y2=mx+random(0,leaveHeightLength)
var y3=mx-random(0,leaveHeightLength)
var ly=(sy-ey)/3
if(ly<0){ly=-ly}
var y2=sy+ly/2+random(0,ly)
var y3=sy+ly+ly/2+random(0,ly)
}
//获取运行轨迹,及参数
var time=[0,random(timeMin,timeMax)]
var track=bezierCreate(sx,sy,x2,y2,x3,y3,ex,ey)
log("随机控制点A坐标:"+x2+","+y2)
log("随机控制点B坐标:"+x3+","+y3)
log("随机滑动时长:"+time[1])
//滑动
gestures(time.concat(track))
// press(850, y,10000);
// sleep(1000);
}