Auto.js 中文文档:https://pro.autojs.org/docs/

pro 版本支持 Node.js

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

  • :https://blog.csdn.net/zy0412326/article/details/107180887/
  • :https://blog.csdn.net/zy0412326/article/details/107190828

示例:

  • AutoJs 4.1.0 实战教程---终极福利Apk:https://blog.csdn.net/zy0412326/article/details/105120435
  • 自动化篇 | 使用 AutoJS 自动领京豆:https://www.bianchengquan.com/article/589931.html
  • 2021 Autojs 全网最全几十种小游戏和自阅合集 (含源码):脚本赚钱:https://blog.csdn.net/qq_29117491/article/details/118634537
  • 最新热门脚本Autojs源码分享:https://www.jb51.net/article/212542.htm

资料:

  • autojs 类似的脚本开发工具,EasyClick和Auto.js有什么区别?:http://www.feiyunjs.com/2456.html
  • Auto.js 快速入门实战教:https://github.com/ErazerControl/2019double11
  • Auto.js 从入门到精通( 95集 ):https://www.bilibili.com/video/BV1pQ4y1R7Us
  • Auto.js(基础、速成、初中、高阶、终极、实战)

    :https://www.songma.com/product/view338899.html    
        【autojs】中级进阶教程:https://www.bilibili.com/video/BV1eg411L7DD

  • auto.js 安卓脚本游戏脚本( 37集 ):https://www.bilibili.com/video/BV1Po4y1Q7bE

  • autojs 入门视频( 23集 ):https://www.bilibili.com/video/BV1g5411L7G6
  • B站搜索的 autojs :https://search.bilibili.com/all?keyword=autojs

Autojs 从入门到放弃(AcFun 视频)

  • :https://www.acfun.cn/v/ac17943282
  • :https://zhuanlan.zhihu.com/p/156660560

AutoJS4.1.0实战教程:https://blog.csdn.net/zy0412326/article/details/104767602/

:https://blog.csdn.net/zy0412326/article/details/105710886/

Hamibot

类似 autojs 的自动化工具,可以通过浏览器远程控制

官网:https://hamibot.com/

适用于安卓系统的自动化工具,能操控任意 APP,实现自动化操作,提高工作效率。

Hamibot_v1.5.0,全自动操控任意APP,还能兼职赚钱的自动化工具!:https://www.i3zh.com/22556.html

关键字:类似 autojs  、autojs 综合实战

  • 比 autojs 更强大、更简单的一站式辅助解决方案「Android智能辅助平台」:https://aznfz.com/document/sample
  • 开维控制精灵Ctrl.js ( 类似auto.js的脚本开发平台 ):http://www.feiyunjs.com/2266.html

autojs 之权限大全

:https://zhuanlan.zhihu.com/p/359393854

1、前言

Auto.js 是一个支持无障碍服务的 Android 平台上的 JavaScript IDE。Autojs 主要是基于安卓系统的无障碍服务,实现自动化操控和监控手机信息处理。

根据官方文档定义:Auto.js 是一款无需 root 权限的 JavaScript 自动化软件。如何理解它?

  1. Auto.js 是一款安卓手机应用,和微信一样,安装在手机上使用
  2. Auto.js 是一款自动化软件,根据脚本内容便可以自动地执行相关的操作,并且手机无需root
  3. Auto.js 的脚本需要使用JavaScript编写

特性:

  • 由无障碍服务实现的简单易用的自动操作函数
  • 悬浮窗录制和运行
  • 更专业&强大的选择器 API,提供对屏幕上的控件的寻找、遍历、获取信息、操作等。类似于 Google 的 UI 测试框架 UiAutomator,您也可以把他当做移动版UI测试框架使用
  • 采用 JavaScript 为脚本语言,并支持代码补全、变量重命名、代码格式化、查找替换等功能,可以作为一个 JavaScript IDE 使用
  • 支持使用 e4x 编写界面,并可以将 JavaScript 打包为 apk 文件,您可以用它来开发小工具应用
  • 支持使用 Root 权限以提供更强大的屏幕点击、滑动、录制功能和运行 shell 命令。录制录制可产生js文件或二进制文件,录制动作的回放比较流畅
  • 提供截取屏幕、保存截图、图片找色、找图等函数
  • 可作为 Tasker 插件使用,结合 Tasker 可胜任日常工作流
  • 带有界面分析工具,类似 Android Studio 的 LayoutInspector,可以分析界面层次和范围、获取界面上的控件信息

app: 应用。启动应用,卸载应用,使用应用查看、编辑文件、访问网页,发送应用间广播等。
console: 控制台。记录运行的日志、错误、信息等。
device: 设备。获取设备屏幕宽高、系统版本等信息,控制设备音量、亮度等。
engines: 脚本引擎。用于启动其他脚本。
events: 事件与监听。按键监听,通知监听,触摸监听等。
floaty: 悬浮窗。用于显示自定义的悬浮窗。
files: 文件系统。文件创建、获取信息、读写。
http: HTTP。发送HTTP请求,例如GET, POST等。
images, colors: 图片和图色处理。截图,剪切图片,找图找色,读取保存图片等。
keys: 按键模拟。比如音量键、Home键模拟等。
shell: Shell命令。
threads: 多线程支持。
ui: UI界面。用于显示自定义的UI界面,和用户交互。

除此之外,Auto.js 内置了对 Promise。

2、安装

针对网上的多个版本区别做说明

  • autojs 是一个开源的自动化程序,之后因为被某些资本警告,导致该工具无法对某些应用进行操作 ( 例如:微信、支付宝、抖音 等 )。4.1.1 版本是免费版的最后一个版本,可以在所有 app 上进行操作。
    Auto.js 因某种原因全网下架(黑灰产) 。可以从 github 上下载源码编译安装。
    github 地址:https://github.com/hyb1996/Auto.js
    Auto.js 下载地址:https://www.lanzoui.com/b03h4tvwh
  • autojs pro 原作者在 autojs 上提供了一个付费的工具,拥有更强大的功能,同样无法操作某些软件。下载地址(最新版已经开始收费):https://pro.autojs.org/
  • autox.js 网友维护的版本,可操作所有软件,并拥有大量 autojs pro 的功能。 
    autoxjs:http://doc.autoxjs.com/#/

其实版本功能区别不大, 主要在一些打包细节,功能函数的优化,bug修复等有些区别,其他没啥区别,4.1.1 版本、autox.js 完全可以满足几乎所有需求。

  • 手机安装 Auto.js 应用
  • 开启手机无障碍服务,目的是为了让脚本能执行。
  • 开启悬浮框(为了查看控件信息)
  • 电脑上有代码编辑器,vscode最佳(Auto.js作者提供了vscode的插件便于调试)

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

  • 在vscode上写脚本,写好后发给手机,在Auto.js应用中加载运行
  • 在vscode上写脚本,电脑与手机在同一局域网,通过安装auto.js的 vscode插件 ( https://github.com/hyb1996/Auto.js-VSCode-Extension ),实现在vscode上运行,手机就会相应执行脚本
  • 在手机的 Auto.js 应用中直接码代码(不提倡)

autox.js(autojs替代方案) 开发教程

:https://blog.csdn.net/SUNbrightness/article/details/124229682

3、示例:领取淘宝喵币

1. 打开淘宝 ---> 点击领喵币按钮

为了编写脚本简单,淘宝预先打开喵铺主页

auto.waitFor()
var appName = "手机淘宝";
launchApp(appName);
sleep(3000);
//寻找领喵币按钮并点击
var lingmiaobi = text("领喵币").findOnce();
if (lingmiaobi) {lingmiaobi.click();sleep(1000);
}
else {toast("未检查到领喵币按钮");//中止脚本exit();
}

详解:

  1. Auto.js无需root,但是需要对该应用开启无障碍模式,开启后才可以进行屏幕点击等操作auto.waitFor()表示直到检查该应用开启无障碍后才执行其后面的代码,否则一直卡在这里,一般放到脚本的第一行
  2. launchApp()可以打开对应应用,由于不同手机响应速度不同,本代码让它睡眠3s。
  3. 定位组件是autojs的最常见的操作,这很类似前端的定位dom元素。在任何点击之前都需要找到对应的组件,这不同于点击某像素位置,点击组件更能适配不同分辨率的手机。在auto.js中通过各种条件选取到的控件称为UiSelector (  https://hyb1996.github.io/AutoJs-Docs/#/widgetsBasedAutomation?id=uiselector )。那么筛选条件是如何确定呢?打开Auto.js应用的悬浮窗,在喵铺主页,点击Auto.js悬浮窗后选择出现的蓝色按钮,点击布局范围分析后选择领喵币按钮查看控件信息,你就能看到如图2所示的信息。
  4. click() 表示点击该元素。
  5. toast() 表示展示一个消息框。

2. 点击去进店/去浏览

//开始执行任务
execTask();
function execTask() {while(true) {var target =  text("去进店").findOnce() || text("去浏览").findOnce();if (target == null) {toast("任务完成");break;}target.click();sleep(3000);//浏览网页20sviewWeb(20);back();sleep(1000);}
}

viewWeb 是一会要写的函数,目的是模拟浏览网页20s的操作,虽说淘宝要求15s就行了,但是可能部分手机加载耗时比较多,所以多写了5s。当判断任务栏有"去进店"、"去浏览"的组件时,点击跳转至浏览广告,浏览完毕后,返回至任务栏页面,循环执行该操作直到找不到"去进店"、"去浏览"的组件结束(任务完成后按钮文字会变成"已完成")。

3. 浏览广告

function viewWeb(time) {gesture(1000, [300, 600], [300, 300]);var cnt = 1;while(true) {var finish = desc("任务完成").exists() || textStartsWith("已获得").exists();if (finish || cnt > time) {break;}sleep(1000);cnt += 1;}//模拟返回键,返回到任务栏页面back();
}

函数的参数为当前页面的最大停留时间(防止意外而一直停留该页面)。

浏览广告完成的标志:

  • 当前页面出现"任务完成"或"已获得*****"的组件
  • 位于当前页面的时间大于所设定的最大限制

gesture 是指屏幕滑动操作,这是本文唯一涉及屏幕像素的语句。gesture(duration, [x1, y1], [x2, y2]表示用duration的时间,从(x1,y1)点滑到(x2,y2)点,代码中表示如图用1s从黄点滑向红点,故是上滑操作浏览广告。

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

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

4. 测试

代码终于写完了,将脚本发到手机中,在Auto.js应用点击右下角的+号,选择导入,在文件目中寻找对应的脚本加载。

将淘宝打开至喵铺主页,返回 Auto.js,点击运行即可执行脚本,在日志处可以查看脚本运行日志,我还没提到日志?在脚本中你可以使用 log() 函数记录日志,这等同于 print,常用于调试或记录日志信息。

5. 打包成 apk

编写完代码,将代码打包成一个独立的 apk。

  1. 右下角+号,新建文件夹命名为 double11
  2. 在 double11 文件夹中加载对应脚本
  3. 如图选择,打包 apk

6. 选择、定位

1. 选择器筛选条件:除使用 text、desc 筛选选择器外,组件的大多数属性都可以筛选,详情见官方文档。单一的筛选条件常常无法定位到元素,那么可以进行链式调用。如定位任务栏的关闭×按钮:

className("android.widget.Button").depth(18).indexInParent(1).findOnce();

2. 定位选择器:findOnce() 表示找到第一个满足条件的控件,找不到返回null;另外还有findOne(),findOne(time)等方法,具体的可以看文档。这里有一个坑,findOne()如果没找到匹配的组件会一直找,直至所描述的控件出现为止,故该函数不会返回null,找不到可能会卡在这里,所以谨慎使用。

3. click():当定位的元素的clickable属性为true时,才可以点击,如果你查看某控件的clickable为false,那说明此控件不能点!!你可能是想点击它的子/父控件。

源码参考 https://github.com/ErazerControl/2019double11,切换 tag 至 v1.0.0

7. 示例:滚动浏览朋友圈

示例代码:


function print_lian_xi_ren(){/* 找控件 */log(text("通讯录").findOne().parent().parent());/* 当找到的控件 的 "点击属性" 是 false 时,可能是这个控件本身嵌套在另一个控件中,外层控件是内层控件的父控件,查看父控件是否可点击,如果父控件 的 "点击属性" 仍然是 false 时,继续查找父控件,直到找到 "点击属性" 是 true 时,即可 点击*/var btn_txl = text("通讯录").findOne().parent().parent();btn_txl.click();sleep(1000)/* 打印联系人 */var lxr = id("com.tencent.mm:id/ft6").find()lxr.forEach(element => {people_name = element.text();log(people_name);click(people_name);sleep(1000);back();sleep(1000);});
}function cha_kan_peng_you_quan(){/* 控件坐标 */var bounds = text("发现").findOne().bounds()var x = bounds.centerX();var y = bounds.centerY();click(x,y);sleep(3000)var btn_pyq = text("朋友圈").findOne();x = btn_pyq.bounds().centerX();y = btn_pyq.bounds().centerY();click(x,y);sleep(1000);var android_widget = className("android.widget.ListView")while(true){/* 滚动浏览朋友圈 */android_widget.scrollDown();sleep(1000);}
}auto.waitFor();
// home();
var app_name = "微信"
app.launchApp(app_name);
sleep(1000)print_lian_xi_ren();
cha_kan_peng_you_quan()

事件与监听 - Events详细讲解

From ( 事件与监听 - Events详细讲解 QQ消息、微信消息 通知服务 ):https://www.bilibili.com/video/BV14g4y1q7mr

/*等待界面出现出现的三种方法*///方法 1
while(true){if(text("控件上的文字").exists()){break;}
}//方法2
text("控件上的文字").waitFor();//方法3
text("控件上的文字").findOne();

示例:


// 启用按键监听
evenntsevents.observeKey();// 监听音量 上键 按下
events.onKeyDown("volume_up", function(event){toast("音量上键被按下");
});events.onKeyDown('volume_down', function(){toast("菜单键被按下");exit();
});events.on("key", function(key_code, event){if(key_code == keys.volume_up && envets.getAction() == event.ACTION_UP){toast("菜单键被按下");}
});events.observeNotification();
events.onNotification(function(notification){printNotification(notification)
});function printNotification(notification){log("应用包名:" + notification.getPackageName());log("通知文本:" + notification.getText());log("通知优先级:" + notification.priority);log("通知目录:" + notification.category);log("通知时间:" + new Date(notification.when));log("通知数:" + notification.number);log("通知摘要:" + notification.tickerText);
}

事件与监听 - Events

按键事件

  • events.emitter()
  • events.observeKey()
  • events.onKeyDown(keyName, listener)
  • events.onKeyUp(keyName, listener)
  • events.onceKeyDown(keyName, listener)
  • events.onceKeyUp(keyName, listener)
  • events.removeAllKeyDownListeners(keyName)
  • events.removeAllKeyUpListeners(keyName)
  • events.setKeyInterceptionEnabled([key, ]enabled)
  • events.observeTouch()
  • events.setTouchEventTimeout(timeout)
  • events.getTouchEventTimeout()
  • events.onTouch(listener)
  • events.removeAllTouchListeners()

事件

  • 事件: 'key'
  • 事件: 'key_down'
  • 事件: 'key_up'
  • 事件: 'exit`
  • events.observeNotification()
  • events.observeToast()
  • 事件: 'toast'

通知

  • Notification

    • Notification.number
    • Notification.when
    • Notification.getPackageName()
    • Notification.getTitle()
    • Notification.getText()
    • Notification.click()
    • Notification.delete()
  • KeyEvent
    • KeyEvent.getAction()
    • KeyEvent.getKeyCode()
    • KeyEvent.getEventTime()
    • KeyEvent.getDownTime()
    • KeyEvent.keyCodeToString(keyCode)
  • keys
  • EventEmitter
    • EventEmitter.defaultMaxListeners
    • EventEmitter.addListener(eventName, listener)
    • EventEmitter.emit(eventName[, ...args])
    • EventEmitter.eventNames()
    • EventEmitter.getMaxListeners()
    • EventEmitter.listenerCount(eventName)
    • EventEmitter.listeners(eventName)
    • EventEmitter.on(eventName, listener)
    • EventEmitter.once(eventName, listener)#
    • EventEmitter.prependListener(eventName, listener)
    • EventEmitter.prependOnceListener(eventName, listener)
    • EventEmitter.removeAllListeners([eventName])
    • EventEmitter.removeListener(eventName, listener)
    • EventEmitter.setMaxListeners(n)
  • events.broadcast: 脚本间广播

4、图片 和 颜色

Auto.js 从入门到精通:https://www.bilibili.com/video/av715713093/

找图、找色

images 模块提供了一些手机设备中常见的图片处理函数,包括截图、读写图片、图片剪裁、旋转、二值化、找色找图等。

:Auto.js

该模块分为两个部分:

  • 找图找色部分
  • 图片处理部分

示例代码:

 颜色转换方法
/*
// 返回颜色值得字符串,格式为 "#AARRGGBB"
colors.toString(colorNum)colors.red(Num | str)   // 返回颜色 color 的 R 通道的值,范围 0~255
colors.green(Num | str) // 返回颜色 color 的 G 通道的值,范围 0~255
colors.blue(Num | str)  // 返回颜色 color 的 B 通道的值,范围 0~255
colors.alpha(Num | str) // 返回颜色 color 的 alpha (透明度) 的值,范围 0~255// 返回 redNum, greenNum, blueNum 构成的颜色值,alpha为255,即不透明
colors.rgb(redNum, greenNum, blueNum)
colors.argb(alpha, redNum, greenNum, blueNum)// 返回颜色的整数值
colors.parseColor(colorStr)
*/判断颜色是否相似或者相等 if(!requestScreenCapture()) {toast("请求截图权限失败");exit();
}
toast("请求截图权限成功")
sleep(5000);function getImg(x1, y1, x2, y2, imgSavePath){var screen = images.captureScreen();var img = images.clip(screen, x1, y1, x2-x1, y2-y1);img.saveTo(imgSavePath);img.recycle();
}// 保存路径的目录必须存在
getImg(0,0,100,500,"/sdcard/Download/test.png");// 使用线程
// thread.start(function(){
//     // 在新线程中执行的代码
//     while(true){
//         if(text("立即执行").findOne()){
//             text("立即执行").findOne().click();
//         }else{
//             sleep(3000);
//         }
//     }
// })

images 中的 requestScreenCapture、captureScreen 这两个函数是可以当做全局函数来使用的注意:captureScreen 返回的图片,不需要进行回收。。。

在图片中寻找颜色、以及 point 对象

示例代码:

// images.findColor(image, color, options)
// findColor(image, color, options) // 全局函数// 循环找色示例
images.requestScreenCapture();
// 循环找色,找打红色 (#ff0000) 时停止,并返回坐标
while(true){var img = images.captureScreen();var point = images.findColor(img, "#ff0000");if(point){toast("找到 '红色',坐标为(" + point.x + "," + point.y + ")")break}sleep(500);
}//区域找色示例
//读取本地图片 /sdcard/1.png
var img = images.read("/sdcard/1.png");
// 判断图片是否加载成功
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);
// 或者
images.findColorInRegion(img, color, x, y, width, height, threshold);

图片中寻找颜色完全相等的颜色点

示例:Auto.js

images.findColorEquals(img, color[, x, y, width, height])

  • img {Image} 图片
  • color {number} | {string} 要寻找的颜色
  • x {number} 找色区域的左上角横坐标
  • y {number} 找色区域的左上角纵坐标
  • width {number} 找色区域的宽度
  • height {number} 找色区域的高度
  • 返回 {Point}

在图片img指定区域中找到颜色和color完全相等的某个点,并返回该点的左边;如果没有找到,则返回null

找色区域通过xywidthheight指定,如果不指定找色区域,则在整张图片中寻找。

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

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

示例代码:

requestScreenCapture();
launchApp("QQ");
sleep(1200);
var p = findColorEquals(captureScreen(), "#f64d30");
if(p){toast("有未读消息");
}else{toast("没有未读消息");
}

多点找色

images.findMultiColors(img, firstColor, colors[, options])

  • 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选项,则找色区域为整张图片。
    • threshold {number} 找色时颜色相似度的临界值,范围为0~255(越小越相似,0为颜色相等,255为任何颜色都能匹配)。默认为4。threshold和浮点数相似度(0.0~1.0)的换算为 similarity = (255 - threshold) / 255.

多点找色,类似于按键精灵的多点找色,其过程如下:

  1. 在图片img中找到颜色firstColor的位置(x0, y0)
  2. 对于数组colors的每个元素[x, y, color],检查图片img在位置(x + x0, y + y0)上的像素是否是颜色color,是的话返回(x0, y0),否则继续寻找firstColor的位置,重新执行第1步
  3. 整张图片都找不到时返回null

例如,对于代码images.findMultiColors(img, "#123456", [[10, 20, "#ffffff"], [30, 40, "#000000"]]),假设图片在(100, 200)的位置的颜色为#123456, 这时如果(110, 220)的位置的颜色为#fffff且(130, 240)的位置的颜色为#000000,则函数返回点(100, 200)。

如果要指定找色区域,则在options中指定,例如:

var p = images.findMultiColors(img, "#123456", [[10, 20, "#ffffff"], [30, 40, "#000000"]], {region: [0, 960, 1080, 960]
});

示例代码:

/*
images.findMultiColors(img, firstColor, [color_1, color_2, ...], options);示例:
images.findMultiColors(img, "#123456", [[10,20,"#ffffff"], [30,40,"#000000"]], options);
images.findMultiColors(img, "#123456", [[5,10,"#ffffff"], [15,20,"#123456"]], {threshold:0});
*/if(!images.requestScreenCapture()){toast("请求截图权限失败");exit();
}text("微信").waitFor();
sleep(1500);var img = images.captureScreen();
sleep(500);
// 获取图片中某一点的颜色
var color_1 = img.pixel(100, 200);
log(colors.toString(color_1));var color_point = images.findMultiColors(img, "#0d0e22", [[10,20, "#ffffff"], [30,40, "#000000"] ]
);// 打印找到的颜色点的坐标
log(color_point);

图片中某个位置是否是特定颜色

images.detectsColor(image, color, x, y[, threshold = 16, algorithm = "diff"]):Auto.js

  • image {Image} 图片
  • color {number} | {string} 要检测的颜色
  • x {number} 要检测的位置横坐标
  • y {number} 要检测的位置纵坐标
  • threshold {number} 颜色相似度临界值,默认为16。取值范围为0~255。
  • algorithm {string} 颜色匹配算法,包括:

    • "equal": 相等匹配,只有与给定颜色color完全相等时才匹配。
    • "diff": 差值匹配。与给定颜色的R、G、B差的绝对值之和小于threshold时匹配。
    • "rgb": rgb欧拉距离相似度。与给定颜色color的rgb欧拉距离小于等于threshold时匹配。

    • "rgb+": 加权rgb欧拉距离匹配(LAB Delta E)。

    • "hs": hs欧拉距离匹配。hs为HSV空间的色调值。

返回图片image在位置(x, y)处是否匹配到颜色color。用于检测图片中某个位置是否是特定颜色。

一个判断微博客户端的某个微博是否被点赞过的例子:

if(!requestScreenCapture()){toast("请求截图权限失败");exit();
}text("排行榜").waitFor();
sleep(1000);//找到点赞控件。
// find() 不会阻塞操作,
// findOne() 会阻塞操作,直到找到一个在继续后续流程
var like = id("com.tencent.mm:id/bo_").find();
//获取该控件中点坐标
var x = like.bounds().centerX();
var y = like.bounds().centerY();
//截图
var img = captureScreen();
//判断在该坐标的颜色是否为橙红色
if(images.detectsColor(img, "#fed9a8", x, y)){//是的话则已经是点赞过的了,不做任何动作
}else{//否则点击点赞按钮like.click();
}

5、应用 --- App

  • app.versionCode
  • app.versionName
  • app.autojs.versionCode
  • app.autojs.versionName
  • app.launchApp(appName)
  • app.launch(packageName)
  • app.launchPackage(packageName)
  • app.getPackageName(appName)
  • app.getAppName(packageName)
  • app.openAppSetting(packageName) :

    打开应用的详情页(设置页)。如果找不到该应用,返回false; 否则返回true。该函数也可以作为全局函数使用。

  • app.viewFile(path)
  • app.editFile(path)
  • app.uninstall(packageName)
  • app.openUrl(url):用浏览器打开网站 url。如果没有安装浏览器应用,则抛出ActivityNotException。
  • app.sendEmail(options):
    • options {Object} 发送邮件的参数。包括:

      • email {string} | {Array} 收件人的邮件地址。如果有多个收件人,则用字符串数组表示
      • cc {string} | {Array} 抄送收件人的邮件地址。如果有多个抄送收件人,则用字符串数组表示
      • bcc {string} | {Array} 密送收件人的邮件地址。如果有多个密送收件人,则用字符串数组表示
      • subject {string} 邮件主题(标题)
      • text {string} 邮件正文
      • attachment {string} 附件的路径。
    • 根据选项 options 调用邮箱应用发送邮件。这些选项均是可选的。如果没有安装邮箱应用,则抛出ActivityNotException

      //发送邮件给10086@qq.com和10001@qq.com。
      app.sendEmail({email: ["10086@qq.com", "10001@qq.com"],subject: "这是一个邮件标题",text: "这是邮件正文"
      });
  • app.startActivity(name):启动 Auto.js 的特定界面。该函数在 Auto.js 内运行则会打开 Auto.js内的界面,在打包应用中运行则会打开打包应用的相应界面。name {string} 活动名称,可选的值为:console 日志界面、settings 设置界面

示例代码:

// app.openAppSetting(app.getPackageName("微信"));
// sleep(1000)
// app.openAppSetting(app.getPackageName("QQ"));
// sleep(1000)app.startActivity("console");
sleep(1000)
app.startActivity("settings")//app.openUrl("https://www.baidu.com")
//sleep(1000)

6、进阶: 意图 Intent

  • app.intent(options)
  • app.startActivity(options)
  • app.sendBroadcast(options)
  • app.startService(options)
  • app.sendBroadcast(name)
  • app.intentToShell(options)
  • app.parseUri(uri)
  • app.getUriForFile(path)

7、悬浮窗 --- Floaty

floaty 模块提供了悬浮窗的相关函数,可以在屏幕上显示自定义悬浮窗,控制悬浮窗大小、位置等。悬浮窗在脚本停止运行时会自动关闭,因此,要保持悬浮窗不被关闭,可以用一个空的setInterval 来实现,例如:setInterval(()=>{}, 1000);

floaty.window(layout)  --- 创建、关闭 悬浮窗

创建和关闭悬浮窗( ui 界面设置 ):Auto.js从入门到精通_哔哩哔哩_bilibili

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

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

该悬浮窗自带关闭、调整大小、调整位置按键,可根据需要调用setAdjustEnabled()函数来显示或隐藏。其中layout参数可以是xml布局或者一个View,更多信息参见ui模块的说明。例子:

var w = floaty.window(<frame gravity="center"><text id="text">悬浮文字</text></frame>
);
setTimeout(()=>{w.close();
}, 2000);

这段代码运行后将会在屏幕上显示悬浮文字,并在两秒后消失。另外,因为脚本运行的线程不是UI线程,而所有对控件的修改操作需要在UI线程执行,此时需要用ui.run,例如:

ui.run(function(){w.text.setText("文本");
});

完整示例:

// frame 是一个重叠布局,如果再添加 一个 button,则两个会重叠到一块
// 更多布局,可以参看:https://hyb1996.github.io/AutoJs-Docs/#/ui?id=垂直布局-vertical
var w = floaty.window(<frame gravity="center"><text id="text">悬浮文字</text></frame>
);
// setTimeout(()=>{
//     w.close();
// }, 2000);setInterval(()=>{}, 1000);  // 保持悬浮窗不被关闭ui.run(function(){w.text.setText("文本");
});

简单使用 "垂直布局" 示例:

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

var xuanfu_window = floaty.window(<vertical h="100dp"><text id="text_1">悬浮文字 text_1</text><text id="text_2">悬浮文字 text_2</text><text layout_weight="1" text="控件1" bg="#ff0000"/><text layout_weight="1" text="控件2" bg="#00ff00"/><text layout_weight="1" text="控件3" bg="#0000ff"/><button>按钮_1</button></vertical>
);setInterval(()=>{}, 1000);ui.run(function(){xuanfu_window.text_1.setText("text_1_text_1_text_1");xuanfu_window.text_2.setText("text_2_text_2_text_2");
});

floaty.rawWindow(layout) --- 指定悬浮窗的布局

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

指定悬浮窗的布局,创建并显示一个原始悬浮窗,返回一个FloatyRawWindow对象。与floaty.window()函数不同的是,该悬浮窗不会增加任何额外设施(例如调整大小、位置按钮),您可以根据自己需要编写任何布局。而且,该悬浮窗支持完全全屏,可以覆盖状态栏,因此可以做护眼模式之类的应用。 示例代码:

var xfc_1 = floaty.rawWindow(<frame gravity="center"><text id="text">悬浮文字</text></frame>
);
var xfc_2 = floaty.rawWindow(<frame gravity="center"><text id="text">悬浮文字</text></frame>
);
setInterval(()=>{}, 1000);
xfc_2.setPosition(500, 500);

floaty.closeAll() --- 关闭所有本脚本的悬浮窗。

悬浮窗对象 --- FloatyWindow

获取悬浮窗界面上的元素 --- FloatyWindow.{id}

悬浮窗对象,可通过 FloatyWindow.{id} 获取悬浮窗界面上的元素。例如, 悬浮窗 window 上一个控件的 id 为 aaa, 那么 window.aaa 即可获取到该控件,类似于 ui。

下面的 window 都是指 FloatyWindow 对象,而不是 FloatyRawWindow

window.setAdjustEnabled(enabled)

  • enabled {boolean} 是否启用悬浮窗调整(大小、位置)。如果 enabled 为 true,则在悬浮窗左上角、右上角显示可供位置、大小调整的标示,就像控制台一样; 如果 enabled 为 false,则隐藏上述标示。
var xfc_1 = floaty.window(<frame gravity="center"><text id="text">悬浮文字</text></frame>
);xfc_1.setAdjustEnabled(true);// xfc_1.setSize(-1, -1);  // -1 表示按最大值计算,占满整个屏幕
xfc_1.setSize(500, 500);setInterval(()=>{}, 1000);

window.setPosition(x, y)

设置悬浮窗位置。

window.getX()

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

window.getY()

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

window.setSize(width, height)

设置悬浮窗宽高。

window.getWidht()

返回悬浮窗宽度。

window.getHeight()

返回悬浮窗高度。

window.close()

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

window.exitOnClose()

使悬浮窗被关闭时自动结束脚本运行。

原始 悬浮窗对象 --- FloatyRawWindow

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

window.setTouchable(touchable)

  • touchable {Boolean} 是否可触摸

设置悬浮窗是否可触摸,如果为true, 则悬浮窗将接收到触摸、点击等事件并且无法继续传递到悬浮窗下面;如果为false, 悬浮窗上的触摸、点击等事件将被直接传递到悬浮窗下面。处于安全考虑,被悬浮窗接收的触摸事情无法再继续传递到下层。

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

var w = floaty.rawWindow(<frame gravity="center" bg="#44ffcc00"/>
);w.setSize(-1, -1);  // -1 表示按最大值计算,占满整个屏幕
w.setTouchable(false);setTimeout(()=>{w.close();
}, 4000);

8、脚本引擎

:Auto.js

在脚本引擎中运行脚本

engines.execScript(name, script[, config])

  • name {string} 要运行的脚本名称。这个名称和文件名称无关,只是在任务管理中显示的名称。
  • script {string} 要运行的脚本内容。
  • config {Object} 运行配置项
    • delay {number} 延迟执行的毫秒数,默认为0
    • loopTimes {number} 循环运行次数,默认为1。0为无限循环。
    • interval {number} 循环运行时两次运行之间的时间间隔,默认为0
    • path {Array} | {string} 指定脚本运行的目录。这些路径会用于require时寻找模块文件。

在新的脚本环境中运行脚本script。返回一个ScriptExectuion对象。

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

最简单的例子如下:engines.execScript("hello world", "toast('hello world')");

如果要循环运行,则:

//每隔3秒运行一次脚本,循环10次
engines.execScript("hello world", "toast('hello world')", {loopTimes: 10,interval: 3000
});

用字符串来编写脚本非常不方便,可以结合 Function.toString()的方法来执行特定函数:

function helloWorld(){//注意,这里的变量和脚本主体的变量并不共享toast("hello world");
}
engines.execScript("hello world", "helloWorld();\n" + helloWorld.toString());

如果要传递变量,则可以把这些封装成一个函数:

function exec(action, args){args = args || {};engines.execScript(action.name, action + "(" + JSON.stringify(args) + ");\n" + action.toString());
}//要执行的函数,是一个简单的加法
function add(args){toast(args.a + args.b);
}//在新的脚本环境中执行 1 + 2
exec(add, {a: 1, b:2});

综合示例代码:


// toast("脚本引擎示例")// // 示例 1
// engines.execScript("js_engines_test", 'toast("示例 1");home();', {
//     delay: 2000,
//     loopTimes: 3,
//     interval: 2000
// });// // 示例 2// function func_test(){
//     toast("示例 2");
// }
// engines.execScript("js_test", func_test.toString() + "func_test();")// 示例 3function func_aaa(args){toast(args.a + args.b);
}function func_exec(func, args){console.log(func.toString());console.log(args.toString());args = args || {};var func_to_string = func.toString();var re_string = /function\s*(\w*)/i;var result_list = re_string.exec(func_to_string);var func_name = result_list[1];engines.execScript(func_name, func.toString()+func_name+"("+JSON.stringify(args)+");")
}
func_exec(func_aaa, {a:10, b:20});

在脚本引擎中运行 js 文件

engines.execScriptFile(path[, config])

  • path {string} 要运行的脚本路径。
  • config {Object} 运行配置项
    • delay {number} 延迟执行的毫秒数,默认为0
    • loopTimes {number} 循环运行次数,默认为1。0为无限循环。
    • interval {number} 循环运行时两次运行之间的时间间隔,默认为0
    • path {Array} | {string} 指定脚本运行的目录。这些路径会用于require时寻找模块文件。

在新的脚本环境中运行脚本文件path。返回一个ScriptExecution对象。

engines.execScriptFile("/sdcard/脚本/1.js");

在脚本引擎中运行录制的脚本文件

fasengines.execAutoFile(path[, config])

  • path {string} 要运行的录制文件路径。
  • config {Object} 运行配置项
    • delay {number} 延迟执行的毫秒数,默认为0
    • loopTimes {number} 循环运行次数,默认为1。0为无限循环。
    • interval {number} 循环运行时两次运行之间的时间间隔,默认为0
    • path {Array} | {string} 指定脚本运行的目录。这些路径会用于require时寻找模块文件。

在新的脚本环境中运行录制文件path。返回一个ScriptExecution对象。

engines.execAutoFile("/sdcard/脚本/1.auto");

脚本引擎的控制方法

engines.stopAll()

停止所有正在运行的脚本。包括当前脚本自身。

engines.stopAllAndToast()

停止所有正在运行的脚本并显示停止的脚本数量。包括当前脚本自身。


engines.execScript("test_test", "sleep(10000);");
sleep(3000);
engines.stopAllAndToast();

engines.myEngine()

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

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

log(engines.myEngine().execArgv);

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

engines.all()

  • 返回 {Array}

返回当前所有正在运行的脚本的脚本引擎ScriptEngine的数组。

log(engines.all());

脚本执行对象 --- ScriptExecution

执行字符串 js 或者 文件 js 时,返回的对象,就是 ScriptExecution 对象

脚本执行对象:Auto.js

执行脚本时返回的对象,可以通过他获取执行的引擎、配置等,也可以停止这个执行。

要停止这个脚本的执行,使用exectuion.getEngine().forceStop().

ScriptExecution.getEngine()

返回执行该脚本的脚本引擎对象(ScriptEngine)

ScriptExecution.getConfig()

返回该脚本的运行配置(ScriptConfig)

脚本引擎对象 -- ScriptEngine

:Auto.js

脚本执行的过程中,会返回一个 js 引擎,即 js 的执行环境,就是 脚本引擎对象

脚本引擎对象。

ScriptEngine.forceStop()

停止脚本引擎的执行。

ScriptEngine.cwd()

  • 返回 {string}

返回脚本执行的路径。对于一个脚本文件而言为这个脚本所在的文件夹;对于其他脚本,例如字符串脚本,则为null或者执行时的设置值。

ScriptEngine.getSource()

  • 返回 ScriptSource

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

log(engines.myEngine().getSource());

示例代码:

var script_execution_obj = engines.execScriptFile("/sdcard/脚本/demo.js");sleep(1000);var script_engine = script_execution_obj.getEngine()
log("脚本引擎对象 ---> " + script_engine);var script_config = script_execution_obj.getConfig()
log("脚本运行配置 ---> " + script_config);log("执行路径 ---> " + script_engine.cwd());
log("脚本源码 ---> " + script_engine.getSource());
script_engine.forceStop()

基本引擎之间的通信

ScriptEngine.emit(eventName[, ...args])

  • eventName {string} 事件名称
  • ...args {any} 事件参数

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

例如脚本receiver.js的内容如下:

//监听say事件
events.on("say", function(words){toastLog(words);
});
//保持脚本运行
setInterval(()=>{}, 1000);

同一目录另一脚本可以启动他并发送该事件:

//运行脚本
var e = engines.execScriptFile("./receiver.js");
//等待脚本启动
sleep(2000);
//向该脚本发送事件
e.getEngine().emit("say", "你好");

脚本配置

:Auto.js

脚本执行时的配置。

delay

  • {number}

延迟执行的毫秒数

interval

  • {number}

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

loopTimes

  • {number}

循环运行次数

getPath()

  • 返回 {Array}

返回一个字符串数组表示脚本运行时模块寻找的路径。

9、用户界面 --- UI

From:https://www.bilibili.com/video/BV1pQ4y1R7Us?p=61

Auto.js教程(第十四期)-界面UI教程(全网最全最详细):https://www.bilibili.com/video/BV1cy4y117iY

界面设计类似 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 来编写界面,并通过 ui.layout()函数指定界面的布局 xml。举个例子:

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

垂直布局(vertical) 改成 水平布局(horizontal)

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

一个控件可以指定多个属性(甚至可以不指定任何属性),用空格隔开即可;布局同样也可以指定属性,例如:

"ui";
ui.layout(<vertical bg="#ff0000"><button text="第一个按钮" textSize="20sp"/><button text="第二个按钮"/></vertical>
);

第三行bg="#ff0000"指定了垂直布局的背景色(bg)为"#ff0000",这是一个RGB颜色,表示红色(有关RGB的相关知识参见RGB颜色对照表)。第四行的textSize="20sp"则指定了按钮控件的字体大小(textSize)为"20sp",sp是一个字体单位,暂时不用深入理会。

一个界面便由一些布局和控件组成。

  • 子视图, 子控件: 布局里面的控件是这个布局的子控件/子视图。实际上布局里面不仅仅只能有控件,还可以是嵌套的布局。因此用子视图(Child View)更准确一些。在上面的例子中,按钮便是垂直布局的子控件。
  • 父视图,父布局:直接包含一个控件的布局是这个控件的父布局/父视图(Parent View)。在上面的例子中,垂直布局便是按钮的父布局。

更多 view 的属性https://hyb1996.github.io/AutoJs-Docs/#/ui?id=视图-view

Autojs 示例代码

视频教程:Auto.js从入门到精通_哔哩哔哩_bilibili

如图所示: 

  • 文本控件

  • 输入框控件

  • 按钮控件

  • 图片控件

  • 表格控件

  • 单选框控件、复选框控件

  • 进度条控件

  • 卡片布局

  • 列表控件

  • 时间日期控件

  • 下拉菜单控件

一般全局函数

全局变量和函数在所有模块中均可使用。 但以下变量的作用域只在模块内,详见 module:

  • exports
  • module
  • require() 以下的对象是特定于 Auto.js 的。 有些内置对象是 JavaScript 语言本身的一部分,它们也是全局的。

一些模块中的函数为了使用方便也可以直接全局使用,这些函数在此不再赘述。例如timers模块的setInterval, setTimeout等函数。

  • sleep(n)
  • currentPackage()
  • currentActivity()
  • setClip(text)
  • getClip()
  • toast(message)
  • toastLog(message)
  • waitForActivity(activity[, period = 200])
  • waitForPackage(package[, period = 200])
  • exit()
  • random(min, max)
  • random()
  • requiresApi(api)
  • requiresAutojsVersion(version)
  • runtime.requestPermissions(permissions)
  • runtime.loadJar(path)
  • runtime.loadDex(path)
  • context

示例代码:

var _toast = toast;toast = function(msg){_toast(msg);sleep(2000);
}toast("123");
toast("456");
toast("789");

// text("微信").waitFor();
// sleep(1000);// 没有出现等待的页面时,则一直等待
// waitForActivity("com.tencent.mm.plugin.sns.ui.SnsTimeLineUI");
// toast("已经到达微信界面");waitForPackage("com.tencent.mm");
toast("已经到了某个应用");var 控件集合 = id("com.miui.home:id/icon_icon").findOne();
var 控件数量 = 控件数量.size();
var r = random(0, 控件数量-1);
var 控件坐标 = 控件集合.get(r).bounds();
click(控件坐标.centerX(), 控件坐标.centerY())

控制台

控制台出现的悬浮窗,进行模拟点击等操作是无法进行穿透操作后面的内容的。。。

控制台模块提供了一个和 Web 浏览器中相似的用于调试的控制台。用于输出一些调试信息、中间结果等。 console 模块中的一些函数也可以直接作为全局函数使用,例如 log, print 等。

显示、隐藏 控制台

  • console.show():显示控制台。这会显示一个控制台的悬浮窗(需要悬浮窗权限)。
  • console.hide():隐藏控制台悬浮窗。

控制台信息 清理、打印

console.clear()

清空控制台。

console.log([data][, ...args])

  • data {any}
  • ...args {any}

打印到控制台,并带上换行符。 可以传入多个参数,第一个参数作为主要信息,其他参数作为类似于 printf(3) 中的代替值(参数都会传给 util.format())。

const count = 5;
console.log('count: %d', count);
// 打印: count: 5 到 stdout
console.log('count:', count);
// 打印: count: 5 到 stdout

详见 util.format()。该函数也可以作为全局函数使用。

print(text)

  • text {string} | {Object} 要打印到控制台的信息

相当于log(text)

console.trace([data][, ...args])

[v4.1.0新增]

  • data {any}
  • ...args {any}

与 console.log 类似,同时会打印出调用这个函数所在的调用栈信息(即当前运行的文件、行数等信息)。

console.trace('Show me');
// 打印: (堆栈跟踪会根据被调用的跟踪的位置而变化)
// Show me
//  at <test>:7

控制台信息输出样式

console.verbose([data][, ...args])

  • data {any}
  • ...args {any}

与 console.log 类似,但输出结果以灰色字体显示。输出优先级低于log,用于输出观察性质的信息。

console.info([data][, ...args])

  • data {any}
  • ...args {any}

与console.log类似,但输出结果以绿色字体显示。输出优先级高于log, 用于输出重要信息。

console.warn([data][, ...args])

  • data {any}
  • ...args {any}

与console.log类似,但输出结果以蓝色字体显示。输出优先级高于info, 用于输出警告信息。

console.error([data][, ...args])

  • data {any}
  • ...args {any}

与console.log类似,但输出结果以红色字体显示。输出优先级高于warn, 用于输出错误信息。

console.assert(value, message)

  • value {any} 要断言的布尔值
  • message {string} value为false时要输出的信息

断言。如果value为false则输出错误信息message并停止脚本运行。

var a = 1 + 1;
console.assert(a == 2, "加法出错啦");

控制台计时

console.time([label])

[v4.1.0新增]

  • label {String} 计时器标签,可省略

启动一个定时器,用以计算一个操作的持续时间。 定时器由一个唯一的 label 标识。 当调用 console.timeEnd() 时,可以使用相同的 label 来停止定时器,并以毫秒为单位将持续时间输出到控制台。 重复启动同一个标签的定时器会覆盖之前启动同一标签的定时器。

console.timeEnd(label)

[v4.1.0新增]

  • label {String} 计时器标签

停止之前通过调用 console.time() 启动的定时器,并打印结果到控制台。 调用 console.timeEnd() 后定时器会被删除。如果不存在标签指定的定时器则会打印 NaNms

console.time('求和');
var sum = 0;
for(let i = 0; i < 100000; i++){sum += i;
}
console.timeEnd('求和');
// 打印 求和: xxx ms

控制台输入

console.input(data[, ...args])

  • data {any}
  • ...args {any}

与console.log一样输出信息,并在控制台显示输入框等待输入。按控制台的确认按钮后会将输入的字符串用eval计算后返回。

部分机型可能会有控制台不显示输入框的情况,属于bug。

例如:

var n = console.input("请输入一个数字:");
//输入123之后:
toast(n + 1);
//显示124

console.rawInput(data[, ...args])

  • data {any}
  • ...args {any}

与console.log一样输出信息,并在控制台显示输入框等待输入。按控制台的确认按钮后会将输入的字符串直接返回。

部分机型可能会有控制台不显示输入框的情况,属于bug。

例如:

var n = console.rawInput("请输入一个数字:");
//输入123之后:
toast(n + 1);
//显示1231

控制台大小、位置、配置的设置

console.setSize(w, h)

  • w {number} 宽度
  • h {number} 高度

设置控制台的大小,单位像素。

console.show();
sleep(2000);
console.setSize(device.width/2, device.height/2)

console.setPosition(x, y)

  • x {number} 横坐标
  • y {number} 纵坐标

设置控制台的位置,单位像素。

console.show();
console.setPosition(100, 100);

console.setGlobalLogConfig(config)

[v4.1.0新增]

  • config {Object} 日志配置,可选的项有:

    • file {string} 日志文件路径,将会把日志写入该文件中
    • maxFileSize {number} 最大文件大小,单位字节,默认为512 * 1024 (512KB)
    • rootLevel {string} 写入的日志级别,默认为"ALL"(所有日志),可以为"OFF"(关闭), "DEBUG", "INFO", "WARN", "ERROR", "FATAL"等。
    • maxBackupSize {number} 日志备份文件最大数量,默认为5
    • filePattern {string} 日志写入格式,参见PatternLayout

设置日志保存的路径和配置。例如把日志保存到"/sdcard/1.txt":

console.setGlobalLogConfig({"file": "/sdcard/1.txt"
});

注意该函数会影响所有脚本的日志记录。

安卓7.0 以上的 触摸 和 手势模拟

:https://pro.autojs.org/docs/#/zh-cn/coordinatesBasedAutomation?id=安卓70以上的触摸和手势模拟

免 root 手机 "模拟点击" 的三种方式

1. click(x, y)

  • x {number} 要点击的坐标的x值
  • y {number} 要点击的坐标的y值

模拟点击坐标(x, y),并返回是否点击成功。只有在点击执行完成后脚本才继续执行。

一般而言,只有点击过程 ( 大约 150ms ) 中被其他事件中断 ( 例如 用户自行点击 ) 才会点击失败。

使用该函数模拟连续点击时,可能有点击速度过慢的问题,这时可以用 press() 函数代替

2. longClick(x, y)

  • x {number} 要长按的坐标的x值
  • y {number} 要长按的坐标的y值

模拟长按坐标(x, y), 并返回是否成功。只有在长按执行完成(大约600毫秒)时脚本才会继续执行。一般而言,只有长按过程中被其他事件中断(例如用户自行点击)才会长按失败。

3. press(x, y, duration)

  • x {number} 要按住的坐标的x值
  • y {number} 要按住的坐标的y值
  • duration {number} 按住时长,单位毫秒

模拟按住坐标(x, y), 并返回是否成功。只有按住操作执行完成时脚本才会继续执行。

如果按住时间过短,那么会被系统认为是点击;如果时长超过500毫秒,则认为是长按。

一般而言,只有按住过程中被其他事件中断才会操作失败。

一个连点器的例子如下:

//循环100次
for(var i = 0; i < 100; i++){//点击位置(500, 1000), 每次用时1毫秒press(500, 1000, 1);
}

免 root 手机 "模拟滑动"  的三种方式

swipe(x1, y1, x2, y2, duration)

  • x1 {number} 滑动的起始坐标的x值
  • y1 {number} 滑动的起始坐标的y值
  • x2 {number} 滑动的结束坐标的x值
  • y2 {number} 滑动的结束坐标的y值
  • duration {number} 滑动时长,单位毫秒

模拟从坐标(x1, y1)滑动到坐标(x2, y2),并返回是否成功。只有滑动操作执行完成时脚本才会继续执行。一般而言,只有滑动过程中被其他事件中断才会滑动失败。

gesture(duration, [x1, y1], [x2, y2], ...)

  • duration {number} 手势的时长
  • [x, y] ... 手势滑动路径的一系列坐标

模拟手势操作。例如gesture(1000, [0, 0], [500, 500], [500, 1000])为模拟一个从(0, 0)到(500, 500)到(500, 100)的手势操作,时长为2秒。

gestures([delay1, duration1, [x1, y1], [x2, y2], ...], [delay2, duration2, [x3, y3], [x4, y4], ...], ...)

同时模拟多个手势。每个手势的参数为[delay, duration, 坐标], delay为延迟多久(毫秒)才执行该手势;duration为手势执行时长;坐标为手势经过的点的坐标。其中delay参数可以省略,默认为0。

例如手指捏合:

gestures([0, 500, [100, 500], [100, 1000]],[0, 500, [300, 500], [300, 1000]],[0, 500, [500, 500], [500, 1000]]
);

使用 root 权限 点击 和 滑动

RootAutomator 是一个使用 root 权限来模拟触摸的对象,用它可以完成触摸与多点触摸,并且这些动作的执行没有延迟。一个脚本中最好只存在一个RootAutomator,并且保证脚本结束退出他。可以在exit事件中退出RootAutomator,例如:

var ra = new RootAutomator();
events.on('exit', function(){ra.exit();
});
//执行一些点击操作
...

注意:以下命令需要root权限

RootAutomator

RootAutomator是一个使用root权限来模拟触摸的对象,用它可以完成触摸与多点触摸,并且这些动作的执行没有延迟。

一个脚本中最好只存在一个RootAutomator,并且保证脚本结束退出他。可以在exit事件中退出RootAutomator,例如:

var ra = new RootAutomator();
events.on('exit', function(){ra.exit();
});
//执行一些点击操作
...

注意以下命令需要root权限

RootAutomator.tap(x, y[, id])

  • x {number} 横坐标
  • y {number} 纵坐标
  • id {number} 多点触摸id,可选,默认为1,可以通过setDefaultId指定。

点击位置(x, y)。其中id是一个整数值,用于区分多点触摸,不同的id表示不同的"手指",例如:

var ra = new RootAutomator();
//让"手指1"点击位置(100, 100)
ra.tap(100, 100, 1);
//让"手指2"点击位置(200, 200);
ra.tap(200, 200, 2);
ra.exit();

如果不需要多点触摸,则不需要id这个参数。 多点触摸通常用于手势或游戏操作,例如模拟双指捏合、双指上滑等。

某些情况下可能存在tap点击无反应的情况,这时可以用RootAutomator.press()函数代替。

RootAutomator.swipe(x1, x2, y1, y2[, duration, id])

  • x1 {number} 滑动起点横坐标
  • y1 {number} 滑动起点纵坐标
  • x2 {number} 滑动终点横坐标
  • y2 {number} 滑动终点纵坐标
  • duration {number} 滑动时长,单位毫秒,默认值为300
  • id {number} 多点触摸id,可选,默认为1

模拟一次从(x1, y1)到(x2, y2)的时间为duration毫秒的滑动。

RootAutomator.press(x, y, duration[, id])

  • x {number} 横坐标
  • y {number} 纵坐标
  • duration {number} 按下时长
  • id {number} 多点触摸id,可选,默认为1

模拟按下位置(x, y),时长为duration毫秒。

RootAutomator.longPress(x, y[, id])

  • x {number} 横坐标
  • y {number} 纵坐标
  • duration {number} 按下时长
  • id {number} 多点触摸id,可选,默认为1

模拟长按位置(x, y)。

以上为简单模拟触摸操作的函数。如果要模拟一些复杂的手势,需要更底层的函数。

RootAutomator.touchDown(x, y[, id])

  • x {number} 横坐标
  • y {number} 纵坐标
  • id {number} 多点触摸id,可选,默认为1

模拟手指按下位置(x, y)。

RootAutomator.touchMove(x, y[, id])

  • x {number} 横坐标
  • y {number} 纵坐标
  • id {number} 多点触摸id,可选,默认为1

模拟移动手指到位置(x, y)。

RootAutomator.touchUp([id])

  • id {number} 多点触摸id,可选,默认为1

模拟手指弹起。

下面的函数在后续版本很可能有改动!请勿过分依赖。推荐使用 RootAutomator 代替本章节的触摸函数。

以下函数均需要root权限,可以实现任意位置的点击、滑动等。

  • 这些函数通常首字母大写以表示其特殊的权限。
  • 这些函数均不返回任何值。
  • 并且,这些函数的执行是异步的、非阻塞的,在不同机型上所用的时间不同。脚本不会等待动作执行完成才继续执行。因此最好在每个函数之后加上适当的sleep来达到期望的效果。

例如:

Tap(100, 100);
sleep(500);

注意,动作的执行可能无法被停止,例如:

for(var i = 0; i < 100; i++){Tap(100, 100);
}

这段代码执行后可能会出现在任务管理中停止脚本后点击仍然继续的情况。 因此,强烈建议在每个动作后加上延时:

for(var i = 0; i < 100; i++){Tap(100, 100);sleep(500);
}

Tap(x, y)

  • x, y {number} 要点击的坐标。

点击位置(x, y), 您可以通过"开发者选项"开启指针位置来确定点击坐标。

Swipe(x1, y1, x2, y2, [duration])

  • x1, y1 {number} 滑动起点的坐标
  • x2, y2 {number} 滑动终点的坐标
  • duration {number} 滑动动作所用的时间

滑动。从(x1, y1)位置滑动到(x2, y2)位置。

AutoJs 4.1.1 实战教程、Hamibot相关推荐

  1. AutoJs4.1.0实战教程---js文件打包发布成APK文件

    AutoJs4.1.0实战教程---js文件打包发布 首先需要在手机上安装AutojsApp,下载地址:https://wwa.lanzoui.com/imX3Vpchkdc 需要将Js文件打包发布成 ...

  2. PyTorch 高级实战教程:基于 BI-LSTM CRF 实现命名实体识别和中文分词

    20210607 https://blog.csdn.net/u011828281/article/details/81171066 前言:译者实测 PyTorch 代码非常简洁易懂,只需要将中文分词 ...

  3. ArcGIS水文分析实战教程(9)雨量计算与流量统计

    ArcGIS水文分析实战教程(9)雨量计算与流量统计 本章导读:降水是水文循环中重要的一环,降水包括雨.雪.雾.露.雹等,本章介绍的是降雨的环节.通过雨量站与插值的方式,实现雨量的空间分布就算,为水文 ...

  4. 宏基因组分析实战教程1. 背景知识

    上次我写的学习经验和推荐的教程--<微生物组入门必读+宏基因组实操课程=新老司机赶快上车>,小伙伴们当天阅读破2700+人次,3.5天破3000+,达到了宏基因组快车满三千人发车的要求.我 ...

  5. js模板字符串自定义类名_【Vue.js 入门到实战教程】07Vue 组件注册 | 基本使用和组件嵌套...

    来源 | https://xueyuanjun.com/post/21929除了前面介绍的基本语法之外,Vue.js 还支持通过组件构建复杂的功能模块,组件可以称得上是 Vue.js 的灵魂,是 Vu ...

  6. python商业爬虫教程_廖雪峰老师的Python商业爬虫课程 Python网络爬虫实战教程 体会不一样的Python爬虫课程...

    廖雪峰老师的Python商业爬虫课程 Python网络爬虫实战教程 体会不一样的Python爬虫课程 1.JPG (53.51 KB, 下载次数: 1) 2019-8-9 08:15 上传 2.JPG ...

  7. Swift游戏开发实战教程(大学霸内部资料)

    Swift游戏开发实战教程(大学霸内部资料) 试读下载地址:http://pan.baidu.com/s/1sj7DvQH 介绍:本教程是国内第一本Swift游戏开发专向资料. 本教程详细讲解记忆配对 ...

  8. python教程下载地址-最新python实战教程网盘下载地址

    原标题:最新python实战教程网盘下载地址 Python在程序员中始终流行:40%的受访者都会学习,44%的受访者每周都会学习.目前技术领域最热点的技术排名,排在前一位的是:Python.Pytho ...

  9. python3项目-终于找到python3项目实战教程

    列表的元素是可以变动的,比如增加.删除.修改,不过需要注意的是,列表的元素不是基本数据类型,都是一个个的标识符引用对象.以下是小编为你整理的python3项目实战教程 先定义一个列表 a = [123 ...

最新文章

  1. 云计算读书笔记(五)
  2. js实现下拉框三级级联
  3. Dexposed:Android平台免Root无侵入AOP框架
  4. goland 远程调试 golang
  5. MySQL- SHOW TABLE STATUS命令
  6. less background url相对路径取不到编译报错问题
  7. gitlab新增ssh
  8. OSPF协议工作原理
  9. 排序算法二:归并排序(Merge sort)
  10. Rxjs takeWhile 和 filter 操作符的区别
  11. CortexM0开发 —— LPC11C14的UART使用方法
  12. 为了让开发者写MaxCompute SQL更爽,DataWorks 增强SQL 编辑器功能
  13. 如何构建JavaScript警报框或弹出窗口
  14. [C++程序设计]字符数组的赋值与引用
  15. 京东物流研发岗位会背景调查吗_【秋招资讯】京东健康于港交所主板上市 | 京东健康2021校园招聘火热进行中!...
  16. IsPostBack结论
  17. 怎么用js代码画一棵树,附带下载链接
  18. 在电脑上构建自我意识
  19. socket 读、写字节流数据
  20. 爬取网易云音乐评论2

热门文章

  1. 电脑个性化和显示设置打不开解决方法
  2. 阿里云人脸对比API使用
  3. 一般将来时语法课教案_英语时态
  4. SQlserver基础学习
  5. SCNN--车道线检测
  6. 【华为提前批】笔试 测评 面试 全流程(结构与材料工程师)
  7. 真的来了,浏览器端可以直接运行Python了
  8. 若依框架修改器(包名修改器) 修改不全问题
  9. Linux常用指令/知识点
  10. RMAN duplicate 方式 做个备库