最近在写脚本的时候,发现定时脚本会发生auto.js在后台运行,导致手机无法自动熄屏的问题(毕竟大家写定时脚本都是为了方便,比如在不需要使用手机的时候完成一些重复性操作...)。但是我们又不能直接停止运行auto.js,那你第一个脚本爽完了,其他的脚本兄弟咋办。
众所周知,“用安卓手机的男人都是好男人,因为每天晚上都要回家充电”(bushi)。安卓手机的电量可是很宝贵的,所以为了解决这个问题。我就去网上查阅了一些资料,发现大部分自动熄屏操作在不对手机进行root的前提下都非常繁琐。可是大家写脚本不就是为了偷懒嘛,这么麻烦的操作有违初衷啊。
机智的我想到了一个以前上课偷摸玩手机时候喜欢用的一个小部件——“一键锁屏”,用最简单的方式实现这一功能。
开始尝试
首先,我在华为手机上进行了测试。发现只要“一键锁屏”这个小部件,位于桌面的第一层,那么Auto.js就可以直接通过text,识别出这个小部件,并且进行点击。
因此,我们只需要在脚本运行结束后,使用home()返回桌面,便可以直接实现 “脚本结束,对手机屏幕进行熄屏” 的操作。
需要注意的是,以下方法的实现,都需要将“一键锁屏”小部件放置在手机桌面的第一层,不能将其摆放至文件夹收纳起来。
有趣的是,在这台华为手机上进行测试的时候。不管屏幕内是否存在“一键锁屏”小部件,auto.js都可以对“一键锁屏”的文本进行识别点击,达到熄屏的效果,可以说是非常方便给力了。下面是多次测试成功的代码:
/**
* 结束脚本后,是否需要一键锁屏
* 请填入"yes"或"no"(默认为"yes")
* 此功能需要在手机桌面第一层放置“一键锁屏”部件或应用
*/
var need_lock = "yes";
// 屏幕是否为锁定状态
function isDeviceLocked() {
importClass(android.app.KeyguardManager);
importClass(android.content.Context);
var km = context.getSystemService(Context.KEYGUARD_SERVICE);
return km.isKeyguardLocked();
}
/**
* 熄灭屏幕
* 自动熄屏功能需要在手机桌面第一层放置“一键锁屏”部件或应用
*/
function lockScreen() {
log("亮度模式:自动");
log("取消设备常亮...");
device.setBrightnessMode(1); // 自动亮度模式
device.cancelKeepingAwake(); // 取消设备常亮
// 震动一秒
toast('脚本运行完毕!');
device.vibrate(1000);
sleep(1000);
if (need_lock == "yes" && !isDeviceLocked()) {
text("一键锁屏").waitFor();
click("一键锁屏");
sleep(1000);
}
}
发现问题,进行优化
而正当我以为大功告成的时候,手贱用了另一台vivo手机进行测试。哦吼,寄!
在这部vivo手机上,出现了一个问题——auto.js虽然可以识别到 “一键锁屏” 的text文本,但却无法对其进行点击。
所以我们改变思路:既然这个控件我们无法正常对其点击,那么我们是否可以利用坐标的形式对其进行操作呢?于是乎,优化版本的锁屏函数便出现了:
在这个版本中,首先尝试是否可以像之前的华为手机一样,直接无视页面识别出“一键锁屏” 的text文本并进行点击;如果识别到第一种锁屏方案失败了,屏幕仍未处于锁屏状态,就切换到第二种方案——
首先,判断桌面上“一键锁屏”的坐标。
之后,根据坐标的大小,判断“一键锁屏”是位于当前页面的左侧还是右侧,并进行滑动操作。
最后,若“一键锁屏”处于当前页面,则直接根据坐标进行点击操作,实现熄屏操作。
需要注意的是, 这里原本我使用的是识别出“一键锁屏”的控件后,通过它的上下左右属性随机出一个点击坐标进行点击(毕竟是脚本操作,习惯性的想偏移坐标了)。但是我发现,如果使用控件内随机坐标,会出现点击失败的情况,并且概率非常大。
又因为这里并不会有被识别脚本的风险,所以最后我没有花精力去找合适的偏移坐标,而是直接使用了它的中心坐标。
我猜测,在vivo手机这里的点击范围仅限于它的图标范围,感兴趣的同学可以用不同的手机去尝试(虽然好像也没什么很大的必要)。
/**
* 熄灭屏幕
* 自动熄屏功能需要在手机桌面第一层放置“一键锁屏”部件或应用
*/
function lockScreen() {
log("亮度模式:自动");
log("取消设备常亮...");
device.setBrightnessMode(1); // 自动亮度模式
device.cancelKeepingAwake(); // 取消设备常亮
// 震动一秒
toast('脚本运行完毕!');
device.vibrate(1000);
sleep(1000);
if (need_lock == "yes" && !isDeviceLocked()) {
text("一键锁屏").waitFor();
click("一键锁屏");
sleep(1000);
if (!isDeviceLocked()) {
log('快捷锁屏失败,切换方案...')
// 获取 “一键锁屏” 小部件的坐标
var lockBtn_X, lockBtn_Y;
function get_btnxy() {
text("一键锁屏").waitFor();
let lockBtn = text("一键锁屏").findOne().bounds();
lockBtn_X = (lockBtn.left + lockBtn.right) / 2;
lockBtn_Y = (lockBtn.top + lockBtn.bottom) / 2;
}
get_btnxy();
// 根据坐标判断 “一键锁屏” 小部件在当前页面的左侧还是右侧
while (lockBtn_X < 0 || lockBtn_X > device.width) {
get_btnxy();
if (lockBtn_X < 0) {
swipe(device.width * 1 / 4, device.height * 5 / 6, device.width * 3 / 4, device.height * 5 / 6, 200);
continue;
}
else if (lockBtn_X > device.width) {
swipe(device.width * 3 / 4, device.height * 5 / 6, device.width * 1 / 4, device.height * 5 / 6, 200);
continue;
}
}
get_btnxy();
click(lockBtn_X, lockBtn_Y);
}
}
}
一些思路
当然,我仅仅只是测试了两部不同品牌的手机,更别说还要同品牌不同型号,或者更多不同品牌的手机。或许也会出现下面这些情况,我也给大家提供一些思路,抛砖引玉:
“一键锁屏”不在当前页面就无法识别 的情况:
可以直接把“一键锁屏”放在主页面,使用home()回到主页面进行识别点击;
亦或者,为函数加上一个page_num参数,代表桌面存在page_num张页面。左滑动page_num次,右滑动page_num次。来回两趟,对全部页面遍历进行识别。
手机没有“一键锁屏”小部件,或是不想在桌面放置“一键锁屏”小部件:
我的解决思路还是一如既往的暴力(嘿嘿),如果是没有“一键锁屏”这个小部件 或者 为了美观不想将其摆放在桌面第一层。我们可以直接从应用商店下载一个“一键锁屏”的应用啊,直接使用别人打包好的功能不香嘛(狗头)。
之后的思路就很清晰啦,脚本运行完毕后直接launchApp就可以了。
(也有可能是我想当然了,毕竟没有实际进行过操作测试,仅仅只是提供一个思路哦)
我也是才接触auto.js不久,希望这篇文章可以给大家提供一些思路或是帮助。
如果觉得这篇文章对你有帮助的话,希望可以点赞关注支持一下,也希望大家在评论区给我留言,互相交流学习(当然也可能是我单方面向大佬学习orz)。