写在前面
autojs
是运用accessibility
功用实现的一套免root
主动化模拟点击框架,让开发者能够直接经过运用js脚本实现一系列的主动化操作,包含:触摸屏幕、滑动、输入文字等。autojs
具有很高的灵活性和可扩展性,能够被用于各种场景,例如主动化游戏操作、主动登录、主动化测验等。
autojs
免费版别已经停止保护,官网只要Autojs Pro
付费版别。可是最近(20230214)又由于一些合规问题,被强制下架已经不允许用户注册。市面上可运用替代产品autox
,该项目基于原autojs
4.1版别基础上进行保护开发。本文主要围绕该项目展开。
开发环境搭建
运用vscode,添加插件Auto.js-Autox.js-VSCodeExt
,如下图,注意不要重复安装多个类似插件,会存在冲突问题。


按住cmd+shift+p
,输入> Auto.js
,挑选”敞开服务(Start Server)
“,此刻右下角会提示服务正在运转提示,并显示ip地址信息,如下图,ip为:192.168.1.102
。


手机与电脑衔接同个wifi
,并翻开autox app
,翻开”无障碍服务
“,并翻开”衔接电脑
“按钮,输入ip地址,如下图,点击确认,即可与电脑同步。

衔接成功后出现如下提示,此刻开发环境搭建完成。

测验hello world程序
,创立Autox.js
文件,并输入内容toast("hello world!")
,挑选js文件,右键-从头运转,即可将脚本同步到手机运转,此刻手时机出现hello world!
的一个toast
提示。

js脚本开发指导
关于autojs的API可参阅官方文档,这儿主要是解说一下运用的思路。咱们在开发主动化工具时,最常见的问题就是怎么找到咱们所需求点击的控件节点,每一个节点包含的信息包含:
-
className
类名。类名表明一个控件的类型,例如文本控件为"android.widget.TextView"
,图片控件为"android.widget.ImageView"
等。 -
id
控件节点的仅有id。 -
text
节点姓名,纷歧定有,可能为空。 -
desc
节点的描述信息,纷歧定有,可能为空。 -
packageName
包名。包名表明控件所在的应用包名,例如 QQ 界面的控件的包名为”com.tencent.mobileqq”。 -
bounds
控件在屏幕上的规模。 -
drawingOrder
控件在父控件的制作次序。 -
indexInParent
控件在父控件的位置。 -
clickable
控件是否可点击。 -
longClickable
控件是否可长按。 -
checkable
控件是否可勾选。 -
checked
控件是否能够勾选。 -
scrollable
控件是否可滑动。 -
selected
控件是否已挑选。 -
editable
控件是否可修改。 -
visibleToUser
控件是否可见。 -
enabled
控件是否已启用。 -
depth
控件的布局深度。
控件id
是最为常用的一个仅有性标记,咱们写主动化认为时,常常运用id来对特定控件做点击操作。可是咱们怎么得知具体控件id
信息呢?咱们能够运用以下js脚本,将整个界面的控件信息进行打印输出。
toastLog("start.");
function printNode(node){
if(node){
var text = node.text();
var desc = node.desc();
let bounds = node.bounds();
let left = bounds.left;
let top = bounds.top;
let right = bounds.right;
let bottom = bounds.bottom;
var click = node.clickable();
var id = node.id();
log(id, text, desc, click, left, right, top, bottom);
}
}
function traverse(node) {
printNode(node);
var cnt = node.childCount();
for (var i = 0; i < cnt; i++) {
traverse(node.child(i));
}
}
let windowRoot = auto.rootInActiveWindow;
if(windowRoot){
log("tracerse node.");
traverse(windowRoot);
}else{
log("window root is null.");
}
咱们能够结合node.bounds()
中控件的巨细以及所在位置,来猜测咱们所要点击的目标控件。在获得某个具体控件id
后,即可运用如下js脚本进行点击操作。
target_id=""
id(target_id).findOne().click()
检查viewid脚本开发
这一节咱们将运用canvas绘图将每个控件制作出来,让咱们方便地看出来咱们所要操作的控件viewid。首先咱们需求运用递归方法遍历当前页面上的所有控件,并存放在list
变量中,如下。
function traverse(node) {
if(node != null){
viewNodes.push(node);
}
var cnt = node.childCount();
for (var i = 0; i < cnt; i++) {
traverse(node.child(i));
}
}
//x:946, y:80
let windowRoot = auto.rootInActiveWindow;
if(windowRoot){
log("tracerse node.");
traverse(windowRoot); // 开端遍历控件树并打印控件的text特点
}else{
log("window root is null.");
}
function printNode(i, node){
if(node){
var text = node.text();
var desc = node.desc();
let bounds = node.bounds();
let left = bounds.left;
let top = bounds.top;
let right = bounds.right;
let bottom = bounds.bottom;
var click = node.clickable();
var id = node.id();
log(i, id, text, desc, click, left, right, top, bottom);
}
}
var len = viewNodes.length;
for (var i = 0; i < len; i++) {
let childViewNode = viewNodes[i];
printNode(i, childViewNode);
}
运用浮窗功用,在顶层制作一张通明的画布,如下:
//ui布局为一块画布
var w = floaty.rawWindow(
<frame gravity="center" bg="#ffffff">
<canvas id="canvas" layout_weight="1"/>
</frame>
);
w.setSize(device.width, device.height); // 设置窗口巨细
w.setTouchable(false); // 设置触摸透传
运用canvas
绘图库,用绿色边框将各个控件圈出,并在每个控件上显示在list
中对应的序号。
let paint = new Paint();
paint.setColor(colors.parseColor("#00ff00"));
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.STROKE);
let paintText = new Paint();
paintText.setColor(colors.parseColor("#FF0000"));
paintText.setTextSize(80);
paintText.setStrokeWidth(20);
var isDraw = 1;
w.canvas.on("draw", function (canvas) {
if(isDraw < 20){
isDraw = isDraw + 1;
var len = viewNodes.length;
for (var i = 0; i < len; i++) {
let childViewNode = viewNodes[i];
let bounds = childViewNode.bounds();
let left = bounds.left;
let top = bounds.top;
let right = bounds.right;
let bottom = bounds.bottom;
canvas.drawRect(left, top, right, bottom, paint);
// log(left, bottom, right, top)
canvas.drawText("" + i, left, bottom, paintText);
}
}
});
为了不让脚本退出,咱们需求运用设置等待时间,让脚本继续运转,如下,若没有等待履行,脚本履行后立马退出,咱们将无法看到绘图内容。
setTimeout(()=>{
w.close();
}, 50000);
效果图如下:
