Auto.js食用指南

控件点击是autojs特有的一项功能,基于安卓的无障碍功能的,在软件上有很好的支持,常用于办公软件等......

前言:

软件选择:

auto.js 8.0pro版本(对比4.0版本有阉割,wx和zfb不能点)

  • 客户端模式
  • 服务器模式

    auto.js 4.0版本有一种模式:
  • 客户端模式

设备和电脑连接:

手机:

服务器模式:手机和电脑在同一局域网下相互连接。(手机电脑同wifi远程连接,稳定)

客户端模式:电脑连接以太网(不是虚拟机的wlan端口(wifi)),cmd输入ipconfig查看ipv4地址和手机ip地址比对,前面的192.168.31一样就行,说明在一个ip地址上,就可以连接(推荐4.0版本手机连接)(直接输入电脑ipv4地址即可)

模拟器:

客户端模式:直接模拟器打开客户端模式,输入cmd命令行ipconfig查看的ipv4地址,进行连接,简单快速(模拟器极为推荐)(推荐逍遥模拟器)

桥接模式:模拟器打开桥接模式连接,比如雷电模拟器无法和电脑在同一局域网下,只能使用桥接模式(没有搞成)

模拟器桥接模式的目的:为了模拟器和电脑在同一个虚拟网桥下。

桥接模式就是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。

vs.code的配置和使用:

基础配置不用说,也就一个汉化插件。

需要加入的插件有两个:

  • auto.js (4.0版本适用)

    在使用时要先start,然后connect
  • auto.js.pro (pro的8.0版本)

    不需要start,直接连接设备

在使用时如果两个插件同时打开,运行程序时,两个插件同时占有’F5‘运行键,会冲突,所以一般打开一个。

在上方任务栏的帮助栏里可以切换开发者工具,打开看日志

一个快捷键:

ctrl+shift+p:打开命令面板

save on device:保存到指定设备

学习:

1.Auto.js的API文档

Auto.js Pro文档

2.Bilibili学习教程

初级教程

中级教程

获取并分析查找控件属性:

使用方法如图:







阻塞机制:用findOne()、waitFor()、exists()等方法寻找控件会引起线程阻塞,导致脚本莫名卡死。故转而使用findOne(timeout)、findonce(i)方法。

示例:findOne(3000):在3秒内寻找控件。

findOnce(2):寻找筛选出来符合要求的第三个控件。

在findOne找不到指定控件时不妨使用findOne()进行深度搜索。

属性选取的方法(常用className,text,desc,id等进行查找控件):

单属性查找:

className("android.view.View").findOne(5000);

多属性查找:

className("android.widget.EditText").depth(9).drawingOrder(0).indexInParent(2).findOne(5000);

text包含:

textContains("大家都在搜")

text开头:

textStartsWith("QQ")

text结尾:

textEndsWith("QQ")

text正则:

textMatches("\d+")

关于正则表达式:https://www.runoob.com/regexp/regexp-syntax.html

desc属性类似使用

注意:

软件中id会经常改变的,使用text,desc比id靠谱

UI的使用:

指定UI模式:

带有ui的脚本的的最前面必须使用"ui";指定ui模式,否则脚本将不会以ui模式运行。

ui";

垂直布局与水平布局:

垂直布局:

"ui";
ui.layout(
<vertical>
<button text="第一个按钮"/>
<button text="第二个按钮"/>
</vertical>
);

水平布局:

"ui";
ui.layout(
<horizontal>
<button text="第一个按钮"/>
<button text="第二个按钮"/>
</horizontal>
);

文字框控件:

<text textSize="16sp" textColor="black" text="请输入名称:" />

输入框控件:

<input id="name" />

按钮控件:

<button id="ok1" text="确定" />

图片控件:

<img src="https://www.baidu.com/img/bd_logo1.png"/>

多线程的使用:

1.子线程开启函数

var 子线程 = threads.start(function(){
while(true){
log("子线程");
}
}); 12345

2.子线程停止函数

子线程.interrupt();
threads.shutDownAll();
//停止所有通过threads.start()启动的子线程。

3.等待线程执行完成

子线程.join([timeout]);
//等待线程执行完成。如果timeout为0,则会一直等待直至该线程执行完成;否则最多等待timeout毫秒的时间。

4.返回线程是否存活

子线程.isAlive()
//返回线程是否存活。

5.等待线程开始执行

子线程.waitFor()
//等待线程开始执行。调用threads.start()以后线程仍然需要一定时间才能开始执行

5.单次定时器

var 子线程 = threads.start(function(){
setTimeout(function(){
//do something
}, 1000);
});
子线程.setTimeout(function(){
//do something
}, 1000);

6.循环定时器

var 子线程 = threads.start(function(){
setInterval(function(){
//do something
}, 1000);
});
子线程.setInterval(function(){
//do something
}, 1000);

7.多线程里的定时器

var thread = threads.start(function () {
log("先运行这一句,然后开启定时器,1s后输出\"子线程:\",开启定时器后就继续运行,开启单次定时器,运行主线程");
//在子线程执行的定时器
setInterval(function () {
log("子线程:");
}, 1000);
});//只能放在前面,不然运行到主线程,若有死循环就没法开启子线程 //等待子线程启动
thread.waitFor();
//在子线程执行的定时器
thread.setTimeout(function () {//单次定时器
//在子线程执行的定时器
log("运行到此定时器后,2s后输出此行");
}, 2000); for(i=0;i<5;i++) {
log("当前线程为主线程-"+i);
sleep(3000)
} sleep(5000);
thread.interrupt();
exit()

8.弹窗检测

var 弹窗检测 = threads.start(function () {
//在子线程执行的定时器
setInterval(function () {
log("弹窗检测中");
if(){
toastLog("弹窗出现");
}
}, 2000);
});

注意:

子线程用完记得关闭thread.interrupt();

下面是一些源码成品,可直接使用:

脚本体验卡:

function IntTime() {
try {
var recode_suning = http.get("http://quan.suning.com/getSysTime.do");
var suningTime = recode_suning.body.json();
return suningTime.sysTime1;
} catch (e) {}
}
let ntime = 20220817210627;//设置截至时间 if (toTime() < ntime || IntTime() < ntime) {
toastLog("正常");
//代码放这里运行
} else {
toastLog("已过期");
engines.stopAll();
} function toTime() {
return new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}

屏幕解锁:

setScreenMetrics(1080, 2340);
var { password } = hamibot.env;
var { select } = hamibot.env;
var { slide_time } = hamibot.env; function number_click(num) {
var number = text(num).findOne().bounds();
click(number.centerX(), number.centerY());
} function scroll() {
if (select == 'a') {
swipe(device.width / 2, device.height * 12 / 15, device.width / 2, device.height * 6 / 15, Number(slide_time));
} else {
swipe(device.width / 2, device.height * 6 / 15, device.width / 2, device.height * 12 / 15, Number(slide_time));
}
} function input_password() {
for (var i = 0; i < password.length; i++) {
switch(password[i]) {
case '1': number_click('1'); break;
case '2': number_click('2'); break;
case '3': number_click('3'); break;
case '4': number_click('4'); break;
case '5': number_click('5'); break;
case '6': number_click('6'); break;
case '7': number_click('7'); break;
case '8': number_click('8'); break;
case '9': number_click('9'); break;
case '0': number_click('0'); break;
default: toast("密码输入错误");
exit();
}
}
} while (!device.isScreenOn()) {
device.wakeUpIfNeeded();
sleep(1000);
scroll();
if (password) {
while (!text('1').exists()) scroll();
input_password();
}
} home();

屏幕解锁(json)

[
{
"name": "password",
"type": "text",
"label": "开屏密码",
"help": "开屏密码只能是数字形式,比如:123456,如果无密码不需要填写"
},
{
"name": "select",
"type": "select",
"label": "亮屏后是上滑开锁还是下滑",
"options": {
"a": "上滑",
"b": "下滑"
},
"validation": "required",
"help": "如果不需要滑动就选择默认上滑"
},
{
"name": "slide_time",
"type": "number",
"label": "滑动时间(以毫秒ms为单位)",
"validation": "required",
"help": "默认为10ms,因不同手机而异,如果解锁不成功可以尝试其他数值"
}
]

联众接码:

// 读取图片
var imgPath = '/sdcard/1.png'
var img = images.read(imgPath)
// 配置文件, 如果要使用以下代码, 请更改username和password
var config = {
baseUrl: 'https://v2-api.jsdama.com/upload',
headers: {
"Host": 'v2-api.jsdama.com',
"Connection": 'keep-alive',
"Accept": 'application/json, text/javascript, */*; q=0.01',
"Content-Type": 'text/json',
"User-Agent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5 Quark/2.4.2.986"
},
softwareSecret: 'FjXYcWGeVRaReAuW92PrsTKnkG9HuLoy3DXhJc5H',
softwareId: '12330',
username: 'autojs',
password: 'lianzhong',
captchaData: images.toBase64(img, format = "png"),
captchaType: '1001',
captchaMinLength: '4',
captchaMaxLength: '4'
}
// 配置参数中有三个参数需要注意一下: // captchaType:图像类型, 图像类型有很多种,比如汉字,中英文,车牌号,箭头等,
// 具体请查看 图像类型
// captchaMinLength:验证码最小长度
// captchaMaxLength:验证码最大长度
// 识别图片
var url = config.baseUrl
var data = {
softwareSecret: config.softwareSecret,
softwareId: config.softwareId,
username: config.username,
password: config.password,
captchaData: config.captchaData,
captchaType: config.captchaType,
captchaMinLength: config.captchaMinLength,
captchaMaxLength: config.captchaMaxLength,
}
var options = {
headers: config.headers
}
try {
http.__okhttp__.setTimeout(3e4);
var res = http.postJson(url, data, options);
log('请求开始')
var html = res.body.json();
log('请求结束')
log(html)
if (html.code === '0') {
console.log('联众识别结果=', html.data.recognition)
// return html.data.recognition
} else {
log("识别图片出现错误,请检查账号信息是否正确")
}
} catch (e) {
log(e)
}

dy达人广场采集:

device.keepScreenOn(3600 * 1000)
while (1) {
//第一
var 粉丝数 = className("android.view.View").textContains("粉丝").boundsInside(0, 1/5*device.height,device.width, device.height).findOne(5000)
if (粉丝数) {
click(粉丝数.bounds().centerX(), 粉丝数.bounds().centerY())
// press(粉丝数.bounds().centerX() - 200, 粉丝数.bounds(), 500);
sleep(2000)
var 昵称 = className("android.widget.TextView").id("lem").findOne(5000)
if (昵称) {
log(昵称.text())
files.append("/sdcard/抖音数据.txt", '\n' + 昵称.text(), [encoding = "utf-8"]);
sleep(200);
var 抖音号 = className("android.widget.TextView").textContains("抖音号").findOne(5000)
if (抖音号) {
log(抖音号.text())
files.append("/sdcard/抖音数据.txt", '\n' + 抖音号.text(), [encoding = "utf-8"]);
var 更多 = className("android.widget.ImageView").desc("更多").findOne(5000)
if (更多) {
click(更多.bounds().centerX(), 更多.bounds().centerY())
sleep(500)
var 发私信 = className("android.widget.TextView").text("发私信").findOne(5000)
if (发私信) {
click(发私信.bounds().centerX(), 发私信.bounds().centerY())
sleep(2000)
var 文字按钮 = className("android.widget.ImageView").boundsInside(0, 5 / 6 * device.height, device.width, device.height).findOne(2000)
if (文字按钮) {
click(文字按钮.bounds().centerX(), 文字按钮.bounds().centerY())
}
sleep(1000)
setText("你好");
sleep(500)
var 发送 = className("android.widget.ImageView").desc("发送").findOne(5000)
if (发送) {
click(发送.bounds().centerX(), 发送.bounds().centerY())
back()
sleep(500)
back()
} }
}
}
}
}
//第一个
var 粉丝数 = className("android.view.View").textContains("粉丝").boundsInside(0, 1 / 5 * device.height, device.width, device.height).findOne(5000)
if (粉丝数) {
log(粉丝数.text())
files.append("/sdcard/抖音数据.txt", '\n' + 粉丝数.text(), [encoding = "utf-8"]);
} // var 带货等级 = className("android.view.View").textContains("带货等级").boundsInside(0, 1 / 5 * device.height, device.width, device.height).findOne(5000)
var 带货等级 = className("android.widget.TextView").textContains("带货等级").boundsInside(0, 1 / 5 * device.height, device.width, device.height).findOne(5000)
if (带货等级) {
log(带货等级.text())
files.append("/sdcard/抖音数据.txt", '\n' + 带货等级.text(), [encoding = "utf-8"]);
}
files.append("/sdcard/抖音数据.txt", '\n------------------------------');
swipe(device.width / 2, device.height * 5 / 8, device.width / 2, device.height * 3 / 8, 500);
sleep(3000)
}

百度文字识别:

//截图当前屏幕并识别截图中的文字
auto()
//请求截图
if(!requestScreenCapture()){
toast("请求截图失败");
exit();
}
log("识别开始")
requestUrl="https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic"
accessToken = '24.45e9e852ec0cc0f41a268e11ce7b2f3f.2592000.1535634423.282335-10386148'
requestUrl = requestUrl + "?access_token=" + accessToken
imgFile="/sdcard/test.jpg"
function img64(imgFile){
var img = captureScreen();
let img64=images.toBase64(img)
return img64
}
imageBase64=img64(imgFile)
imageBase64=encodeURI(imageBase64)
console.show();
var res = http.post(requestUrl, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
image:imageBase64,
image_type:"BASE64",
});
var html = res.body.string();
log(html)
log("识别结束")

auto.jspro商店整蛊脚本:

/*
* @Author: 旭阳
* @QQ:1912452912
* @versioin: 1.0
* @Date: 2022-09-06 15:46:30
*/
"ui";
var resources = context.getResources();
var statusBarHeight = resources.getDimensionPixelSize(resources.getIdentifier('status_bar_height', 'dimen', 'android'));//通知栏高度
var navigationBarHeight = getNavigationBarHeight()//导航栏高度
var deviceheight = device.height - statusBarHeight - navigationBarHeight
var rect = new android.graphics.Rect
ui.layout(
<frame w="*" h="*" >
<vertical id="main" w="450px" h="200px" layout_gravity="center" bg="#00ffff">
<text h="100px" text="你愿意给我10元红包吗" textColor="#000000" gravity="center"/>
<frame>
<text id="touch" w="200px" h="100px" text="愿意" bg="#363636" gravity="center" textColor="#ffffff" />
<text id="fake" w="200px" h="100px" layout_gravity="right|bootom"/>
</frame>
</vertical>
<text id="untouch" w="200px" h="100px" text="不愿意" bg="#363636" textColor="#ffffff" gravity="center"/>
</frame>
)
setTimeout(function() {
ui.fake.getBoundsOnScreen(rect)
ui.untouch.x = rect.left
ui.untouch.y = rect.top - statusBarHeight
}, 50)
ui.touch.on("click", () => {
app.startActivity({
data: "mqqapi://card/show_pslcard?src_type=internal&source=sharecard&version=1&uin=1912452912"
});
toast("请加QQ1912452912并发10元红包")
})
ui.untouch.on("touch_down", () => {
ui.untouch.getBoundsOnScreen(rect)
let l = rect.left
let t = rect.top - statusBarHeight
let r = rect.right
let b = rect.bottom - statusBarHeight
let w = rect.width()
let h = rect.height()
//以下if-else语句是为了保持按钮在屏幕内并尽量随机变换按钮位置
if (l < w) {
ui.untouch.x = random(l + w, device.width - w)
if (t < h || new Date().getTime % 2)
ui.untouch.y = random(t + h, deviceheight - h)
else
ui.untouch.y = random(0, b - h)
} else if ((device.width - r) < w) {
ui.untouch.x = random(0, r - w)
if ((deviceheight - b) < h || new Date().getTime % 2)
ui.untouch.y = random(0, b - h)
else
ui.untouch.y = random(t + h, deviceheight - h)
} else if (new Date().getTime % 2) {
ui.untouch.x = random(l + w, device.width - w)
if (t < h || new Date().getTime % 2)
ui.untouch.y = random(t + h, deviceheight - h)
else
ui.untouch.y = random(0, b - h)
} else {
ui.untouch.x = random(0, r - w)
if ((deviceheight - b) < h || new Date().getTime % 2)
ui.untouch.y = random(0, b - h)
else
ui.untouch.y = random(t + h, deviceheight - h)
}
}) function getNavigationBarHeight() {
var navigationBarHeight = 0;
var rid = context.getResources().getIdentifier("config_showNavigationBar", "bool", "android");
if (rid != 0) {
var resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
navigationBarHeight = context.getResources().getDimensionPixelSize(resourceId);
}
return navigationBarHeight;
}

Auto.js食用指南的更多相关文章

  1. 【vue.js权威指南】读书笔记(第一章)

    最近在读新书<vue.js权威指南>,一边读,一边把笔记整理下来,方便自己以后温故知新,也希望能把自己的读书心得分享给大家. [第1章:遇见vue.js] vue.js是什么? vue.j ...

  2. Node.js开发指南中的例子(mysql版)

    工作原因需要用到nodejs,于是找到了<node.js开发指南>这本书来看看,作者BYVoid 为清华大学计算机系的高材生,年纪竟比我还小一两岁,中华地广物博真是人才辈出,佩服. 言归正 ...

  3. 《JS权威指南学习总结》

    JS权威指南学习总结:http://www.cnblogs.com/ahthw/category/652668.html

  4. 《JS权威指南学习总结--开始简介》

    本书共分成了四大部分: 1.JS语言核心 2.客户端JS 3.JS核心参考 4.客户端JS核心参考 其中 <JS权威指南学习总结--1.1语法核心> 是:第一部分JS语言核心 各章节重点 ...

  5. 《JS权威指南学习总结--1.1语言核心》

    1.1语言核心 --本节主要介绍<js权威指南>基础部分各章讲解内容和一些简单的示例 本小节内容: 一.第二章讲解js注释.分号和Unicode,第三章主要讲解js变量和赋值 简单示例: ...

  6. Sencha Cmd 6 和 Ext JS 6 指南文档(部分官方文档中文翻译)

    近期组织了几个程序员网友,正在翻译一部分官方的Sencha Cmd 6 和 Ext JS 6 指南文档. 眼下还没翻译完,大家能够先看看 Sencha Cmd 6 和 Ext JS 6 指南文档  ( ...

  7. 学习Nodejs:《Node.js开发指南》微博项目express2迁移至express4过程中填的坑

    <Node.js开发指南>项目地址https://github.com/BYVoid/microblog好不容易找到的基础版教程,但书中是基于express2的,而现在用的是express ...

  8. Auto.js 初试-Android开发JS利器

    GitHub地址:https://github.com/hyb1996/Auto.js 文档地址:https://hyb1996.github.io/AutoJs-Docs/#/?id=%E7%BB% ...

  9. 【Auto.js images.matchTemplate() 函数的特点】

    Auto.js  images.matchTemplate() 函数的特点 官方文档:https://hyb1996.github.io/AutoJs-Docs/#/images?id=imagesm ...

  10. d3.js 入门指南 - 仪表盘

    D3的全称是Data-Driven Documents(数据驱动的文档),是一个用来做数据可视化的JavaScript函数库,而JavaScript文件的后缀通常为.js,所以D3被称为D3.js. ...

随机推荐

  1. [Spring MVC]@RequestMapping 与 @RequestMapping+@RequestResponse的区别

    假定:返回格式均为JSON,JSON实体对象myJson的属性有:data.message.code.status. 二者的区别在于: @RequestMapping:会在最外层包裹 data属性,将 ...

  2. 关键字——static

    static 关键字具有共享属性,放在方法区中

  3. Linux 阶段二

    1.2 安装JDK JDK具体安装步骤如下: 1). 上传安装包 使用FinalShell自带的上传工具将jdk的二进制发布包上传到Linux 由于上述在进行文件上传时,选择的上传目录为根目录 /,上 ...

  4. Nginx常用配置及和基本功能讲解

    作者:京东物流 殷世杰 Nginx已经广泛应用于J-one和Jdos的环境部署上,本文对Nginx的常用的配置和基本功能进行讲解,适合Nginx入门学习. 1 核心配置 找到Nginx安装目录下的co ...

  5. C# Nuget版本号排序

    Nuget包版本号和我们软件应用版本号一样,不过因为稳定性等的考虑,组件版本有更高的要求.预发布版本使用频率更高 版本号介绍,详见我朋友胡承老司机的博客:Nuget包的版本规范 (qq.com) 我这 ...

  6. Python + 超级鹰 识别图形验证码

    前言: 一.下载 1.进入官网:http://www.chaojiying.com/,注册完成后,进行登录 2.点击开发文档,点击Python语言示例 3.进行示例下载 4.解压后的文件 注:关注公众 ...

  7. Yolov5 根据自己的需要更改 预测框box和蒙版mask的颜色

    1.首先找到项目中 utils/plots.py 文件,打开该代码 将原来的 Colors类注释掉(或删掉),改成如下Colors类 class Colors: def __init__(self): ...

  8. 2022-05-08:给你一个下标从 0 开始的字符串数组 words 。每个字符串都只包含 小写英文字母 。words 中任意一个子串中,每个字母都至多只出现一次。 如果通过以下操作之一,我们可以

    2022-05-08:给你一个下标从 0 开始的字符串数组 words .每个字符串都只包含 小写英文字母 .words 中任意一个子串中,每个字母都至多只出现一次. 如果通过以下操作之一,我们可以从 ...

  9. 2021-09-06:给表达式添加运算符。给定一个仅包含数字 0-9 的字符串 num 和一个目标值整数 target ,在 num 的数字之间添加 二元 运算符(不是一元)+、- 或 * ,返回所有

    2021-09-06:给表达式添加运算符.给定一个仅包含数字 0-9 的字符串 num 和一个目标值整数 target ,在 num 的数字之间添加 二元 运算符(不是一元)+.- 或 * ,返回所有 ...

  10. vue全家桶进阶之路26:Vue.js 3.0与Vue.js 2.x 的比较和注意事项

    Vue.js 3.0 是 Vue.js 框架的最新版本,于 2020 年 9 月正式发布.Vue.js 3.0 主要的改进和新特性包括: 更好的性能:Vue.js 3.0 使用了更快的虚拟 DOM 实 ...