2023年11月28日发(作者:)

AutoJs4.1.1实战教程

中⽂⽂档:

pro 版本⽀持

AutoJs Pro 7.0.4-1 实战教程---史上最全快⼿、抖⾳极速版

⽰例:

是⼀个⽀持⽆障碍服务的 Android 平台上的 JavaScript IDE。Autojs 主要是基于安卓系统的⽆障碍服务,实现⾃动化操控和监

控⼿机信息处理。

根据官⽅⽂档定义: 是⼀款⽆需 root 权限的 JavaScript ⾃动化软件。如何理解它?

1. 是⼀款安卓⼿机应⽤,和微信⼀样,安装在⼿机上使⽤

2. 是⼀款⾃动化软件,根据脚本内容便可以⾃动地执⾏相关的操作,并且⼿机⽆需root

最新版已经开始收费,下载地址:

⼿机安装 应⽤

开启⼿机⽆障碍服务,⽬的是为了让脚本能执⾏。

开启悬浮框(为了查看控件信息)

电脑上有代码编辑器,vscode最佳(作者提供了vscode的插件便于调试)

接下来需要写脚本了,可以

r()

var appName = "⼿机淘宝";

launchApp(appName);

sleep(3000);

//寻找领喵币按钮并点击

var lingmiaobi = text("领喵币").findOnce();

if (lingmiaobi) {

();

sleep(1000);

}

else {

点击去进店/去浏览 2.

//开始执⾏任务

execTask();

function execTask() {

while(true) {

var target = text("去进店").findOnce() || text("去浏览").findOnce();

if (target == null) {

toast("任务完成");

break;

}

();

sleep(3000);

//浏览⽹页20s

viewWeb(20);

back();

sleep(1000);

}

}

viewWeb 是⼀会要写的函数,⽬的是模拟浏览⽹页20s的操作,虽说淘宝要求15s就⾏了,但是可能部分⼿机加载耗时⽐较多,所以多写

本次淘宝的活动最开始滑动⼀次,之后等着时间够了即可,故代码中没有再额外滑动。在浏览⼴告完毕后back()模拟返回键返回值任务栏页

⾯。

这段代码定位组件⽤到了desc(),之所于⽤desc是因为该控件的desc信息是"任务完成",还记得如何查看控件信息吧?总之,想定位控

1. 右下⾓+号,新建⽂件夹命名为 double11

2. 在 double11 ⽂件夹中加载对应脚本

3. 如图选择,打包 apk

6. 选择、定位

1. 选择器筛选条件:除使⽤ text、desc 筛选选择器外,组件的⼤多数属性都可以筛选,详情见。单⼀的筛选条件常常⽆法定位到元素,那

function print_lian_xi_ren(){

/* 找控件 */

log(text("通讯录").findOne().parent().parent());

/* 当找到的控件 "点击属性" false 时,可能是这个控件本⾝嵌套在另⼀个控件中,

外层控件是内层控件的⽗控件,查看⽗控件是否可点击,

如果⽗控件 "点击属性" 仍然是 false 时,继续查找⽗控件,

直到找到 "点击属性" true 时,即可 点击

*/

var btn_txl = text("通讯录").findOne().parent().parent();

btn_();

sleep(1000)

/* 打印联系⼈ */

var lxr = id(":id/ft6").find()

h(element => {

people_name = ();

log(people_name);

click(people_name);

sleep(1000);

back();

sleep(1000);

});

}

function cha_kan_peng_you_quan(){

/* 控件坐标 */

var bounds = text("发现").findOne().bounds()

var x = X();

var y = Y();

click(x,y);

sleep(3000)

var btn_pyq = text("朋友圈").findOne();

x = btn_().centerX();

y = btn_().centerY();

click(x,y);

sleep(1000);

var android_widget = className("ew")

while(true){

/* 滚动浏览朋友圈 */

android_Down();

sleep(1000);

}

}

r();

// home();

/*等待界⾯出现出现的三种⽅法*/

//⽅法 1

while(true){

if(text("控件上的⽂字").exists()){

break;

}

}

//⽅法2

text("控件上的⽂字").waitFor();

//⽅法3

text("控件上的⽂字").findOne();

⽰例:

// 启⽤按键监听

eKey();

// 监听⾳量 上键 按下

own("volume_up", function(event){

toast("⾳量上键被按下");

});

own('volume_down', function(){

toast("菜单键被按下");

exit();

});

("key", function(key_code, event){

if(key_code == _up && ion() == _UP){

toast("菜单键被按下");

事件

4、图⽚ 颜⾊

从⼊门到精通:

找图、找⾊

images 模块提供了⼀些⼿机设备中常见的图⽚处理函数,包括截图、读写图⽚、图⽚剪裁、旋转、⼆值化、找⾊找图等。

该模块分为两个部分:

找图找⾊部分

图⽚处理部分

颜⾊转换⽅法

/*

// 返回颜⾊值得字符串,格式为 "#AARRGGBB"

ng(colorNum)

(Num | str) // 返回颜⾊ color R 通道的值,范围 0~255

(Num | str) // 返回颜⾊ color G 通道的值,范围 0~255

(Num | str) // 返回颜⾊ color B 通道的值,范围 0~255

(Num | str) // 返回颜⾊ color alpha (透明度) 的值,范围 0~255

// 返回 redNum, greenNum, blueNum 构成的颜⾊值,alpha255,即不透明

(redNum, greenNum, blueNum)

(alpha, redNum, greenNum, blueNum)

// 返回颜⾊的整数值

olor(colorStr)

*/

判断颜⾊是否相似或者相等

if(!requestScreenCapture()) {

toast("请求截图权限失败");

exit();

}

toast("请求截图权限成功")

sleep(5000);

function getImg(x1, y1, x2, y2, imgSavePath){

var screen = eScreen();

var img = (screen, x1, y1, x2-x1, y2-y1);

(imgSavePath);

e();

}

// 保存路径的⽬录必须存在

getImg(0,0,100,500,"/sdcard/Download/");

// 使⽤线程

// (function(){

// // 在新线程中执⾏的代码

// while(true){

// if(text("⽴即执⾏").findOne()){

// text("⽴即执⾏").findOne().click();

// }else{

// sleep(3000);

// }

// }

// })

images 中的 requestScreenCapture、captureScreen 这两个函数是可以当做全局函数来使⽤的。注意:captureScreen 返回的

图⽚,不需要进⾏回收。。。

在图⽚中寻找颜⾊、以及 point 对象

⽰例代码:

// lor(image, color, options)

// findColor(image, color, options) // 全局函数

// 循环找⾊⽰例

tScreenCapture();

// 循环找⾊,找打红⾊ (#ff0000) 时停⽌,并返回坐标

while(true){

var img = eScreen();

var point = lor(img, "#ff0000");

if(point){

toast("找到 '红⾊',坐标为(" + point.x + "," + point.y + ")")

break

}

sleep(500);

}

//区域找⾊⽰例

//读取本地图⽚ /sdcard/

var img = ("/sdcard/");

// 判断图⽚是否加载成功

if(!img){

toast("没有找到要加载的图⽚");

exit();

}

// 在该图⽚中找⾊。

// 指定找⾊区域:位置(400,500)的宽为300长为200的区域,指定找⾊临界值为4

var point = findColor(img, "#00ff00", {

region:[400,500,300,200],

threshold: 4

});

if(point){

toast("找到位置:" + point);

}else{

toast("没有找到");

}

区域找⾊ --- 简单⽅法

findColorInRegion(img, color, x, y, width, height, threshold);

// 或者

lorInRegion(img, color, x, y, width, height, threshold);

图⽚中寻找颜⾊完全相等的颜⾊点

⽰例:

img {Image} 图⽚

该函数也可以作为全局函数使⽤。

⽰例: (通过找QQ红点的颜⾊来判断是否有未读消息)

⽰例代码:

requestScreenCapture();

launchApp("QQ");

sleep(1200);

var p = findColorEquals(captureScreen(), "#f64d30");

if(p){

toast("有未读消息");

}else{

toast("没有未读消息");

}

多点找⾊

img {Image} 要找⾊的图⽚

firstColor {number} | {string} 第⼀个点的颜⾊

colors {Array} 表⽰剩下的点相对于第⼀个点的位置和颜⾊的数组,数组的每个元素为[x, y, color]

options {Object} 选项,包括:

region {Array} 找⾊区域。是⼀个两个或四个元素的数组。(region[0], region[1])表⽰找⾊区域的左上⾓;region[2]*region[3]

表⽰找⾊区域的宽⾼。如果只有region只有两个元素,则找⾊区域为(region[0], region[1])到屏幕右下⾓。如果不指定region选

/*

ltiColors(img, firstColor, [color_1, color_2, ...], options);

⽰例:

ltiColors(img, "#123456", [[10,20,"#ffffff"], [30,40,"#000000"]], options);

ltiColors(img, "#123456", [[5,10,"#ffffff"], [15,20,"#123456"]], {threshold:0});

*/

if(!tScreenCapture()){

toast("请求截图权限失败");

exit();

}

text("微信").waitFor();

sleep(1500);

var img = eScreen();

sleep(500);

if(!requestScreenCapture()){

toast("请求截图权限失败");

exit();

}

text("排⾏榜").waitFor();

sleep(1000);

//找到点赞控件。

// find() 不会阻塞操作,

// findOne() 会阻塞操作,直到找到⼀个在继续后续流程

var like = id(":id/bo_").find();

//获取该控件中点坐标

var x = ().centerX();

var y = ().centerY();

//截图

var img = captureScreen();

//判断在该坐标的颜⾊是否为橙红⾊

if(sColor(img, "#fed9a8", x, y)){

//是的话则已经是点赞过的了,不做任何动作

}else{

//否则点击点赞按钮

();

}

根据选项 options 调⽤邮箱应⽤发送邮件。这些选项均是可选的。如果没有安装邮箱应⽤,则抛出ActivityNotException

//发送邮件给10086@10001@

ail({

email: ["10086@", "10001@"],

subject: "这是⼀个邮件标题",

text: "这是邮件正⽂"

});

:启动 的特定界⾯。该函数在 内运⾏则会打开 内的界⾯,在打包应⽤中运⾏则会打开打包应⽤的相应界⾯。

name {string} 活动名称,可选的值为:console ⽇志界⾯、settings 设置界⾯

⽰例代码:

// pSetting(kageName("微信"));

// sleep(1000)

// pSetting(kageName("QQ"));

// sleep(1000)

ctivity("console");

sleep(1000)

ctivity("settings")

//l("")

//sleep(1000)

6、进阶: 意图 Intent

7、悬浮窗 --- Floaty

floaty 模块提供了悬浮窗的相关函数,可以在屏幕上显⽰⾃定义悬浮窗,控制悬浮窗⼤⼩、位置等。悬浮窗在脚本停⽌运⾏时会⾃动关闭,

因此,要保持悬浮窗不被关闭,可以⽤⼀个空的setInterval 来实现,例如:setInterval(()=>{}, 1000);

--- 创建、关闭 悬浮窗

创建和关闭悬浮窗( ui 界⾯设置 ):

layout {xml} | {View} 悬浮窗界⾯的XML或者View

指定悬浮窗的布局,创建并显⽰⼀个悬浮窗,返回⼀个FloatyWindow对象。

该悬浮窗⾃带关闭、调整⼤⼩、调整位置按键,可根据需要调⽤setAdjustEnabled()函数来显⽰或隐藏。其中layout参数可以是xml布局或者

⼀个View,更多信息参见ui模块的说明。例⼦:

var w = (

悬浮⽂字

);

setTimeout(()=>{

();

}, 2000);

这段代码运⾏后将会在屏幕上显⽰悬浮⽂字,并在两秒后消失。另外,因为脚本运⾏的线程不是UI线程,⽽所有对控件的修改操作需要在UI

线程执⾏,此时需要⽤,例如:

(function(){

t("⽂本");

});

完整⽰例:

// frame 是⼀个重叠布局,如果再添加 ⼀个 button,则两个会重叠到⼀块

// 更多布局,可以参看:/AutoJs-Docs/#/ui?id=垂直布局-vertical

var w = (

悬浮⽂字

);

// setTimeout(()=>{

// ();

// }, 2000);

--- 指定悬浮窗的布局

layout {xml} | {View} 悬浮窗界⾯的XML或者View

指定悬浮窗的布局,创建并显⽰⼀个原始悬浮窗,返回⼀个FloatyRawWindow对象。与()函数不同的是,该悬浮窗不会增加任

何额外设施(例如调整⼤⼩、位置按钮),您可以根据⾃⼰需要编写任何布局。⽽且,该悬浮窗⽀持完全全屏,可以覆盖状态栏,因此可以

做护眼模式之类的应⽤。 ⽰例代码:

var xfc_1 = dow(

悬浮⽂字

);

var xfc_2 = dow(

悬浮⽂字

);

setInterval(()=>{}, 1000);

xfc_ition(500, 500);

--- 关闭所有本脚本的悬浮窗。

悬浮窗对象,可通过 FloatyWindow.{id} 获取悬浮窗界⾯上的元素。例如, 悬浮窗 window 上⼀个控件的 id 为 aaa, 那么 即可

获取到该控件,类似于 ui。

下⾯的 window 都是指 FloatyWindow 对象,⽽不是 FloatyRawWindow

enabled {boolean} 是否启⽤悬浮窗调整(⼤⼩、位置)。如果 enabled 为 true,则在悬浮窗左上⾓、右上⾓显⽰可供位置、⼤⼩调整

的标⽰,就像控制台⼀样; 如果 enabled 为 false,则隐藏上述标⽰。

var xfc_1 = (

悬浮⽂字

);

xfc_ustEnabled(true);

// xfc_e(-1, -1); // -1 表⽰按最⼤值计算,占满整个屏幕

xfc_e(500, 500);

setInterval(()=>{}, 1000);

设置悬浮窗位置。

返回悬浮窗位置的X坐标。

返回悬浮窗位置的Y坐标。

设置悬浮窗宽⾼。

返回悬浮窗宽度。

返回悬浮窗⾼度。

关闭悬浮窗。如果悬浮窗已经是关闭状态,则此函数将不执⾏任何操作。

使悬浮窗被关闭时⾃动结束脚本运⾏。

原始 悬浮窗对象 --- FloatyRawWindow

原始悬浮窗对象,可通过window.{id}获取悬浮窗界⾯上的元素。例如, 悬浮窗window上⼀个控件的id为aaa, 那么即可获取到该

控件,类似于ui。

touchable {Boolean} 是否可触摸

设置悬浮窗是否可触摸,如果为true, 则悬浮窗将接收到触摸、点击等事件并且⽆法继续传递到悬浮窗下⾯;如果为false, 悬浮窗上的触

摸、点击等事件将被直接传递到悬浮窗下⾯。处于安全考虑,被悬浮窗接收的触摸事情⽆法再继续传递到下层。

可以⽤此特性来制作护眼模式脚本,⽰例代码:

var w = dow(

8、脚本引擎

在脚本引擎中运⾏脚本

name {string} 要运⾏的脚本名称。这个名称和⽂件名称⽆关,只是在任务管理中显⽰的名称。

script {string} 要运⾏的脚本内容。

config {Object} 运⾏配置项

delay {number} 延迟执⾏的毫秒数,默认为0

loopTimes {number} 循环运⾏次数,默认为1。0为⽆限循环。

interval {number} 循环运⾏时两次运⾏之间的时间间隔,默认为0

path {Array} | {string} 指定脚本运⾏的⽬录。这些路径会⽤于require时寻找模块⽂件。

在新的脚本环境中运⾏脚本script。返回⼀个对象。

所谓新的脚本环境,指定是,脚本中的变量和原脚本的变量是不共享的,并且,脚本会在新的线程中运⾏。

最简单的例⼦如下:ript("hello world", "toast('hello world')");

如果要循环运⾏,则:

//每隔3秒运⾏⼀次脚本,循环10

ript("hello world", "toast('hello world')", {

loopTimes: 10,

interval: 3000

});

⽤字符串来编写脚本⾮常不⽅便,可以结合 ng()的⽅法来执⾏特定函数:

function helloWorld(){

//注意,这⾥的变量和脚本主体的变量并不共享

toast("hello world");

// toast("脚本引擎⽰例")

// // ⽰例 1

// ript("js_engines_test", 'toast("⽰例 1");home();', {

// delay: 2000,

// loopTimes: 3,

// interval: 2000

// });

// // ⽰例 2

// function func_test(){

// toast("⽰例 2");

// }

// ript("js_test", func_ng() + "func_test();")

// ⽰例 3

function func_aaa(args){

toast(args.a + args.b);

}

function func_exec(func, args){

(ng());

(ng());

args = args || {};

var func_to_string = ng();

var re_string = /functions*(w*)/i;

var result_list = re_(func_to_string);

var func_name = result_list[1];

ript(func_name, ng()+func_name+"("+ify(args)+");")

path {Array} | {string} 指定脚本运⾏的⽬录。这些路径会⽤于require时寻找模块⽂件。

在新的脚本环境中运⾏录制⽂件path。返回⼀个对象。

toFile("/sdcard/脚本/");

脚本引擎的控制⽅法

停⽌所有正在运⾏的脚本。包括当前脚本⾃⾝。

停⽌所有正在运⾏的脚本并显⽰停⽌的脚本数量。包括当前脚本⾃⾝。

ript("test_test", "sleep(10000);");

sleep(3000);

lAndToast();

返回当前脚本的脚本引擎对象()

[v4.1.0新增] 特别的,该对象可以通过execArgv来获取他的运⾏参数,包括外部参数、intent等。例如:

log(ne().execArgv);

普通脚本的运⾏参数通常为空,通过定时任务的⼴播启动的则可以获取到启动的intent。

返回 {Array}

返回脚本执⾏的路径。对于⼀个脚本⽂件⽽⾔为这个脚本所在的⽂件夹;对于其他脚本,例如字符串脚本,则为null或者执⾏时的设置值。

返回

返回当前脚本引擎正在执⾏的脚本对象。

log(ne().getSource());

⽰例代码:

var script_execution_obj = riptFile("/sdcard/脚本/");

sleep(1000);

var script_engine = script_execution_ine()

log("脚本引擎对象 ---> " + script_engine);

var script_config = script_execution_fig()

log("脚本运⾏配置 ---> " + script_config);

log("执⾏路径 ---> " + script_());

log("脚本源码 ---> " + script_rce());

script_top()

基本引擎之间的通信

eventName {string} 事件名称

...args {any} 事件参数

向该脚本引擎发送⼀个事件,该事件可以在该脚本引擎对应的脚本的events模块监听到并在脚本主线程执⾏事件处理。

延迟执⾏的毫秒数

{number}

循环运⾏时两次运⾏之间的时间间隔

{number}

循环运⾏次数

返回 {Array}

返回⼀个字符串数组表⽰脚本运⾏时模块寻找的路径。

9、⽤户界⾯ --- UI

From:

教程(第⼗四期)-界⾯UI教程(全⽹最全最详细):

界⾯设计类似 HTML

ui 模块提供了编写⽤户界⾯的⽀持。带有 ui 的脚本的的最前⾯必须使⽤ "ui"; 指定 ui 模式,否则脚本将不会以 ui 模式运⾏。正确⽰范:

"ui";

//脚本的其他代码

字符串 "ui" 的前⾯可以有注释、空⾏和空格[v4.1.0新增],但是不能有其他代码。

视图(View) --- ( 控件、布局 )

界⾯ 是由 视图(View) 组成的。View 分成两种:

控件(Widget)。控件 (Widget) ⽤来具体显⽰⽂字、图⽚、⽹页等,⽐如⽂本控件(text)⽤来显⽰⽂字,按钮控件(button)则可以显⽰

⼀个按钮并提供点击效果,图⽚控件(img)则⽤来显⽰来⾃⽹络或者⽂件的图⽚,除此之外还有输⼊框控件(input)、进度条控件

(progressbar)、单选复选框控件(checkbox)等;

布局(Layout)。布局 (Layout) 则是装着⼀个或多个控件的 "容器",⽤于控制在他⾥⾯的控件的位置,⽐如 垂直布局(vertical) 会把他

⾥⾯的控件从上往下依次显⽰(即纵向排列),⽔平布局(horizontal) 则会把他⾥⾯的控件从左往右依次显⽰(即横向排列),以及 帧布局

(frame),他会把他⾥⾯的控件直接在左上⾓显⽰,如果有多个控件,后⾯的控件会重叠在前⾯的控件上。

我们使⽤ xml 来编写界⾯,并通过 ()函数指定界⾯的布局 xml。举个例⼦:

"ui";

(

"ui";

(