auto.js是一个支持无障碍服务的Android平台上的JavaScript IDE,可以编写各种自动化脚本,无需root:基于无障碍服务;基于控件:以坐标为基础的按键精灵、脚本精灵很容易出现分辨率问题,而以控件为基础的Auto.js则没有这个问题;上手简单:使用javascript编写,支持中文变量名;可打包 :可以将JavaScript打包为apk文件,这一点可以简化用户操作,对上了年纪的用户很重要;
importClass(org.jsth.boot.tool.Uuid)
onlyRun()
function onlyRun() {
auto();
if (!requestScreenCapture()) {
toast('请求图片失败');
exit();
}
//console.show()
log("开始QQ")
var res = http.postJson('QQ号存放地址', {
sid: Uuid.getUuid()
})
if (res.statusCode === 200) {
var data = res.body.json().content
var account = data.acct
var password = data.pass
run(account, password)
} else {
log('获取资源失败!退出程序')
exit()
}
}
function run(account, pass) {
let str = launchApp()
if (str === 'login') { //登录不用切换帐号
log("登录页面")
setText([0], account)
sleep(1000);
setText([1], pass)
sleep(1000);
className("android.widget.ImageView").desc("登 录").findOne(5000).click()
sleep(1000);
sleep(1000);
sleep(1000);
toast('开始处理滑块')
if (!className("android.view.View").text("拖动下方滑块完成拼图").findOnce()) {
sleep(1000);
sleep(1000);
sleep(1000);
}
while (className("android.view.View").text("拖动下方滑块完成拼图").findOnce()) {
log("拖动下方滑块完成拼图")
dragSlider()
sleep(1000);
}
} else { //切换帐号
swipe(device.width / 8, device.height / 2, device.width * 4 / 5, device.height / 2, 500);
sleep(500)
if (text("设置").findOnce()) {
var sz = text("设置").findOne()
clickCenter(sz);
sleep(500)
if (text("帐号管理").findOnce()) {
var zhgl = text("帐号管理").findOne()
clickCenter(zhgl);
sleep(500)
if (text(account).findOnce()) {
var acc = text(account).findOne()
clickCenter(acc);
sleep(2000)
goLaunchPage();
}
}
}
}
}
//判断是否为启动页
function ifLaunchPage() {
if (text("联系人").exists() && text("消息").exists() && text("看点").exists() && text("动态").exists()) {
return true;
} else {
return false;
}
}
//跳转启动页
function goLaunchPage() {
while (!ifLaunchPage()) {
back()
sleep(500);
}
}
function launchApp() {
let str = 'login'
let isLauchApp = false
while (!isLauchApp) {
log("尝试启动")
launch("com.tencent.mobileqq");
sleep(1000);
log("尝试启动 1000")
sleep(1000);
sleep(1000);
sleep(1000);
isLauchApp = id("com.tencent.mobileqq:id/egz").findOnce() //登录页面
if (!isLauchApp) {
toastLog(currentPackage())
if ('com.tencent.mobileqq' === currentPackage()) {
goLaunchPage();
goPage(["消息"]);
isLauchApp = true
str = 'index'
}
}
}
log("已启动")
return str
}
function goPage(pagePaths) {
do {
var btn;
if (btn = text(pagePaths[0]).visibleToUser(true).findOne(6000)) {
clickCenter(btn);
pagePaths.shift();
sleep(2000);
} else {
log("进入" + pagePaths[0] + "页面失败");
return false;
}
} while (pagePaths.length > 0);
sleep(200);
return true;
}
function clickCenter(b) {
var rect = b.bounds();
return click(rect.centerX(), rect.centerY());
};
/**
* 拖动滑块
*/
function dragSlider() {
for (var i = 0; i < 0; i++) {
sleep(1000);
log(i);
}
while (true) {
img = images.captureScreen();
if (img) {
log("截图成功。进行识别滑块!");
break;
} else {
log('截图失败,重新截图');
}
}
var x = discernSlidingblock(imgBy720(), 720) + 65 //+ 166
console.info("识别结果滑块X坐标:" + x);
if (x > -1) {
if (className('android.widget.Image').text('tag-bar').findOnce()) {
let b = className('android.widget.Image').text('tag-bar').findOnce().bounds();
randomSwipe(b.centerX(), b.centerY(), x, b.centerY())
} else {
randomSwipe(126, 690, x, 690)
}
return true;
} else {
log("识别有误,请确认是否在滑块界面");
return false;
}
}
function imgBy720() {
var img = captureScreen()
return images.resize(img, [720, device.height * 720 / device.width])
}
/**
* 识别滑块位置
*
* 传入值img,ratio
* img为要识别的图片
* ratio为识别图片的分辨率(暂时只可选择720或1080)
*
* 返回值x
* 识别出方块位置的左端横坐标
*/
function discernSlidingblock(img, ratio) {
//创建识别变量
var temp, temp2, x, y, num, color, p, temp3, arr1;
//分析设备分辨率
if (ratio == 720) {
var tb = [348, 253, 691, 638, 81]
log("您的设备分辨率为:720p");
} else if (ratio == 1080) {
var tb = [463, 387, 912, 831, 125]
log("您的设备分辨率为:1080p");
} else {
log("当前设备分辨率不符合规范")
return -2
}
num = Math.ceil(tb[4] / 3.3 - 4);
//计算滑块位置
for (var k = 29; k <= 40; k++) {
temp2 = "";
color = "#" + k + "" + k + "" + k + "";
for (var i = 1; i <= num; i++) {
temp2 = temp2 + "0|" + i + "|" + color + ",";
temp2 = temp2 + i + "|0|" + color + ",";
temp2 = temp2 + "1|" + i + "|" + color + ",";
temp2 = temp2 + i + "|1|" + color + ",";
temp2 = temp2 + "2|" + i + "|" + color + ",";
temp2 = temp2 + i + "|2|" + color + ",";
}
x = 0;
while (x > -2) {
y = 0;
while (y > -2) {
temp = "";
for (var i = 1; i <= num; i += 2) {
temp = temp + "0|" + (tb[4] + y - i - 1) + "|" + color + ",";
temp = temp + (tb[4] + x) + "|" + i + "|" + color + ",";
temp = temp + (tb[4] + x) + "|" + (tb[4] + y - i - 1) + "|" + color + ",";
temp = temp + (tb[4] + x - i - 1) + "|0|" + color + ",";
temp = temp + i + "|" + (tb[4] + y) + "|" + color + ",";
temp = temp + (tb[4] + x - i - 1) + "|" + (tb[4] + y) + "|" + color + ",";
temp = temp + "1|" + (tb[4] + y - i - 1) + "|" + color + ",";
temp = temp + (tb[4] + x - 1) + "|" + i + "|" + color + ",";
temp = temp + (tb[4] + x - 1) + "|" + (tb[4] + y - i - 1) + "|" + color + ",";
temp = temp + (tb[4] + x - i - 1) + "|1|" + color + ",";
temp = temp + i + "|" + (tb[4] + y - 1) + "|" + color + ",";
temp = temp + (tb[4] + x - i - 1) + "|" + (tb[4] + y - 1) + "|" + color + ",";
}
temp = temp + temp2 + "0|0|" + color;
arr1 = temp.split(",");
var arr2 = new Array();
for (var i = 0; i < arr1.length - 1; i++) {
arr2[i] = new Array();
temp3 = arr1[i].split("|");
arr2[i] = [Number(temp3[0]), Number(temp3[1]), temp3[2]];
}
try {
p = images.findMultiColors(img, color, arr2, {
region: [tb[0], tb[1], tb[2] - tb[0], tb[3] - tb[1]],
threshold: (Math.floor(k / 10) * 16 + k % 10)
});
if (p) {
img.recycle();
return p.x + 65
}
} catch (error) {
//出错
console.log("识别失败,错误原因:" + error);
return -1;
}
y = --y;
}
x = --x;
}
}
try {
img.recycle();
} catch (error) {
console.log("识别失败,错误原因:" + error);
}
return -1;
}
/**
* 真人模拟滑动函数 (滑块滑动)
* @param {起点x} sx
* @param {起点y} sy
* @param {终点x} ex
* @param {终点y} ey
*/
function randomSwipe(sx, sy, ex, ey) {
log(sx)
log(sy)
log(ex)
log(ey)
//设置随机滑动时长范围
var timeMin = 1000
var timeMax = 3000
//设置控制点极限距离
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, y3)
}
//获取运行轨迹,及参数
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))
}
/**
* 计算滑动轨迹
*/
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
};
}
//轨迹转路数组
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
}
/**
* 仿真随机带曲线滑动 (视频滑动)
* @param {起点x} qx
* @param {起点y} qy
* @param {终点x} zx
* @param {终点y} zy
* @param {过程耗时单位毫秒} time
*/
function sml_move(qx, qy, zx, zy, time) {
var xxy = [time];
var point = [];
var dx0 = {
"x": qx,
"y": qy
};
var dx1 = {
"x": random(qx - 100, qx + 100),
"y": random(qy, qy + 50)
};
var dx2 = {
"x": random(zx - 100, zx + 100),
"y": random(zy, zy + 50),
};
var dx3 = {
"x": zx,
"y": zy
};
for (var i = 0; i < 4; i++) {
eval("point.push(dx" + i + ")");
};
log(point[3].x)
for (let i = 0; i < 1; i += 0.08) {
xxyy = [parseInt(bezier_curves(point, i).x), parseInt(bezier_curves(point, i).y)]
xxy.push(xxyy);
}
log(xxy);
gesture.apply(null, xxy);
};
function bezier_curves(cp, t) {
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;
tSquared = t * t;
tCubed = tSquared * t;
result = {
"x": 0,
"y": 0
};
result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
return result;
};