当前最新版本:V1.0.5
《强国助手》为本人Auto.js学习交流的开源非营利项目,仅作为程序员之间相互学习交流之用,使用需严格遵守开源许可协议。严禁用于商业用途,禁止使用《强国助手》进行任何盈利活动。对一切非法使用所产生的后果,本人概不负责。具体声明如下:
1.本项目供程序员日常学习交流使用,不得用于其他任何商业用途。
2.apk软件是本人利用Auto.js打包插件完成的,不包含病毒可放心安装使用。
3.本项目不提倡每天利用脚本软件来刷《学习强国》积分。
4.希望大家正视脚本内容本身,坚持把学习贯彻习近平总书记系列重要讲话精神作为重大政治任务,认真学习党的先进理论与指导思想,请勿利用本软件投机取巧。
5.经过n个账号的两天测试,暂未发现封号风险,理论上Auto.js模仿人的思路对控件进行模拟点击,如果每天一直使用,不保证不会封号。
6.经向专业律师咨询,本声明有效,具有法律效力。
本文档的目的是在经过《学习强国》安卓脚本的实战开发后,梳理个人在学习Auto.js过程中的知识点,并对每一个功能进行思路讲解和代码介绍,希望能通过本项目帮助学习Auto.js的人更进一步理解脚本开发步骤和原理。
如果对您有帮助,欢迎您star⭐一下小星星~
仓库内容:
Images文件夹——存放演示图片和视频
强国助手历史版本文件夹——仅作为备份用
强国助手 vX.X.X .apk —— 当前完善的最新版本,脚本打包后封装好的安卓软件应用安装包
学习强国.apk——学习强国v2.10.0版本(截至2020.3.21官方最新版)
Auto.js官方API文档——字面意思
autojs.apk——autojs手机开发IDE(版本:4.1.1 Alpha2)
AutoLearnChina.js —— 当前最新的核心脚本执行文件
Readme.md —— 《强国助手》说明文档
本项目是一款基于Auto.js工具开发的安卓脚本应用软件,依靠目前的脚本,最多每日能够获得32积分(除答题以外的所有分值)。
目前软件实现的任务功能包括了以下几点:
1.阅读文章
2.视听学习
3.收藏
4.分享
5.订阅
6.评论
7.本地频道
8.文章学习时长(可选)
9.视听学习时长(可选)
在当日未执行所有任务的情况下,脚本完成任务1-7预计花费7分钟。
脚本完成任务8预计花费12分钟。
脚本完成任务9预计花费18分钟。
未实现的任务功能包括:
1.每日答题
2.每周答题
3.专项答题
4.挑战答题
- V1.0.5:新增悬浮窗日志显示功能,解决阅读时长任务的bug,新增选项菜单
- V1.0.4:解决手机主界面UI字符的屏幕适配问题,解决获取任务列表不稳定的问题
- V1.0.3:更新脚本应用的UI效果,增加用户手机息屏检测和屏幕激活,增加看视频时用户是否使用手机流量的检测机制,解决不能首次执行长时阅读任务的BUG
- V1.0.0:正式发布至GitHub平台
版本要求:
1.手机系统:仅支持安卓系统,最好是安卓7.0以上。
2.手机型号:
目前经过测试能正常运行的:
红米K20 Pro(安卓10)、华为nova5pro(安卓10)、华为荣耀20(安卓10)、华为P20 Pro(安卓10)其他机型未知。
其中解决华为手机不能显示脚本执行过程的通知办法:进入手机管家-病毒查杀-风险管控中心-对强国助手解除管控-再打开设置-通知-允许强国助手发送通知
未通过测试的:
oppo A59s(安卓5.1)
3.应用版本:《学习强国》v2.10.0
目前以上版本以通过测试,其他版本机型未知。
使用手册:(建议在Wifi状态下执行脚本软件,因为会涉及到自动观看视频)
1.下载apk软件,安装;
2.关闭《学习强国》软件,打开《强国助手》软件,由强国助手自动启动学习强国;
3.需要打开《强国助手》的无障碍服务和截图功能,到时根据软件提示进行相应操作即可;
4.无需输入任何配置参数,选择是否执行可选任务后,一键运行。
5.在程序运行过程中将手机放到一旁即可,最好不要中途操纵手机,等待程序执行结束,即可查看获得积分或关闭《学习强国》。
附:
如果不小心中途操作手机跳出了学习强国页面,导致脚本执行失败,关闭学习强国软件,重启脚本软件再执行即可。
通常情况下每5秒内会更新脚本执行消息并在屏幕下方显示通知信息(见软件效果静态展示),如果脚本在执行过程中未出现执行过程提示信息但仍在正常执行,请确认手机设置中是否已打开允许强国助手通知(如上华为手机开启通知的解决办法);如果超过20秒学习强国页面未变化,则可能出现了异常,此时关闭学习强国,重启脚本软件再执行即可。
由于脚本并未做学习强国全版本测试,也没有钱做更多的机型适配测试,所以欢迎广大程序员来疯狂测试,程序也存在很多不足,欢迎大家批评指正!望共同进步!
使用效果:
1.软件主页(V1.0.0):
2.使用过程静态展示:
3.使用过程动态展示:(可见Image文件夹中的视频文件)
参与贡献(内附提交方法):https://github.com/Alivon/Panda-Learning/blob/master/CONTRIBUTING.md
Auto.js是一个支持无障碍服务的Android平台上的JavaScript IDE,可以编写各种自动化脚本,它主要有以下优点:
- 无需root:基于无障碍服务;
- 基于控件:以坐标为基础的按键精灵、脚本精灵很容易出现分辨率问题,而以控件为基础的Auto.js则没有这个问题;
- 上手简单:使用javascript编写,支持中文变量名;
- 可打包 :可以将JavaScript打包为apk文件,这一点可以简化用户操作,对上了年纪的用户很重要;
Auto.js下载与详细介绍:https://github.com/hyb1996/Auto.js/
项目开发的准备工作:https://www.bilibili.com/video/av93396608
Auto.js入门教程:https://space.bilibili.com/21486893
学完了以上3个链接,相信你一定对Auto.js开发有了比较全面基础的理解,在我看来,安卓脚本开发中最难的就是控件的寻找,如果找到了控件,接下来对控件的操作只要学会查API文档,就能应付开发中的大部分情况了。
在文件底部,你可看到未完成的方法体,它们就是答题模块,本人比较菜,对该部分模块开发还没有什么思路,也希望能得到高人指点,也可共同开发完成。
复制空方法体到一个新文件,或是新建一个函数体,在该新文件中对该方法要完成的功能进行开发,开发完成后复制到原文件中即可。
教程:
JS入门:https://www.bilibili.com/video/av35958121
控件寻找:https://www.bilibili.com/video/av36724143
控件操作:https://www.bilibili.com/video/av37314451
以下代码均以强国助手V1.0.0脚本应用版本为例,最新版本的代码参见AutoLearnChina.js
套用模板即可,主要是需要对用户的输入进行传值,需要用户提前开启无障碍服务和截图权限。
"ui";
var form = {
isLongRead: false,
isLongWatch: false
}
ui.layout(
<vertical>
<appbar>
<toolbar title="强国助手"/>
</appbar>
<Switch id="autoService" text="无障碍服务" checked="{{auto.service != null}}" padding="8 8 8 8" textSize="15sp"/>
<frame height="50" gravity="center">
<text text="*注意*" gravity="center" textSize="18sp" textColor="red" textStyle="bold"/>
</frame>
<frame height="50" gravity="center">
<text text="使用前请先开启本应用的无障碍服务和截图权限" gravity="center"/>
</frame>
<frame height="50" gravity="center">
<text text="脚本执行过程中请勿操作手机" gravity="center"/>
</frame>
<frame height="50" gravity="center">
<text text="目前强国助手支持的功能包括:(以下任务预计花费7分钟)" gravity="center"/>
</frame>
<frame height="50" gravity="center">
<text text="阅读文章、视听学习、收藏、分享、订阅、评论、本地频道" gravity="center"/>
</frame>
<frame height="80" gravity="center">
<text text="坚持把学习贯彻习近平总书记系列重要讲话精神作为重大政治任务,认真学习党的先进理论与指导思想,请勿利用本软件投机取巧" gravity="center"/>
</frame>
<frame height="50" gravity="center">
<text text="Copyright©2020 by Txy 一岸流年1998" gravity="center"/>
</frame>
<frame height="20" gravity="center">
<text text="---------------------------------------------------------------------------------------------------------------------------------" gravity="center"/>
</frame>
<vertical>
<text text="是否执行文章学习时长任务:(预计最多花费12分钟)"/>
<radiogroup id="long_read">
<radio id="yes_read" text="是"></radio>
<radio id="no_read" text="否" checked = "true"></radio>
</radiogroup>
</vertical>
<vertical>
<text text="是否执行视听学习时长任务:(预计最多花费18分钟)"/>
<radiogroup id="long_watch">
<radio id="yes_watch" text="是"></radio>
<radio id="no_watch" text="否" checked = "true"></radio>
</radiogroup>
</vertical>
<frame height="20" gravity="center">
<text text="---------------------------------------------------------------------------------------------------------------------------------" gravity="center"/>
</frame>
<button id="start" text="开始运行" textColor="blue" textStyle="bold"/>
<button id="stop" text="停止运行" />
</vertical>
);
ui.yes_read.on("check",function(check){
if(check){
form.isLongRead= true;
}
});
ui.no_read.on("check",function(check){
if(check){
form.isLongRead= false;
}
});
ui.yes_watch.on("check",function(check){
if(check){
form.isLongWatch= true;
}
});
ui.no_watch.on("check",function(check){
if(check){
form.isLongWatch= false;
}
});
ui.autoService.on("check", function(checked) {
// 用户勾选无障碍服务的选项时,跳转到页面让用户去开启
if(checked && auto.service == null) {
app.startActivity({
action: "android.settings.ACCESSIBILITY_SETTINGS"
});
}
if(!checked && auto.service != null){
auto.service.disableSelf();
}
});
// 当用户回到本界面时,resume事件会被触发
ui.emitter.on("resume", function() {
// 此时根据无障碍服务的开启情况,同步开关的状态
ui.autoService.checked = auto.service != null;
});
ui.start.on("click", function(){
//程序开始运行之前判断无障碍服务
if(auto.service == null) {
toastLog("请先开启无障碍服务!");
return;
}
main();
});
ui.stop.on("click",function(){
threads.shutDownAll();
engines.stopAll();
exit();
toast("已终止执行脚本");
});function main() {
// 这里写脚本的主逻辑
threads.start(function () {
if(!requestScreenCapture()){
toastLog("请先开启截图权限,以执行收藏任务!");
toastLog("运行结束,脚本自动退出...");
exit();
}
toastLog("主程序开始运行");
try {
//检查无障碍服务是否已经启用,如果没启动,跳转到启动界面,启动后继续执行
// auto.waitFor();
launchApp("学习强国");
waitForPackage("cn.xuexi.android");
sleep(3000);
toast("开始执行脚本!")
getTaskList(); // 获取任务列表
doUnfinishedTask(); //执行当日未完成的任务
doExtraTask();
back();//回到手机主页
sleep(2000);
} catch (error) {
log(error)
toast("出现异常,请关闭应用重新执行脚本!");
exit(); // 有异常退出,结束脚本
}
toastLog("运行结束,脚本自动退出...");
threads.shutDownAll();
engines.stopAll();
exit();
});
}主要得到当日还未达到满分的任务,将其存入taskInfoList数组。
function getTaskList() {
toastLog("执行获取任务列表")
// 从主页到我的主页
className("android.widget.TextView").id('comm_head_xuexi_mine').findOne().click();
sleep(2000);
// 点击事件在我的积分父控件上
id("user_item_name").text("学习积分").findOne().parent().click()
// waitForPackage("cn.xuexi.android")
waitForActivity("com.alibaba.lightapp.runtime.activity.CommonWebViewActivity")
sleep(3000);
toastLog("获取任务列表...")
// 获取任务列表
taskInfoList = []; // 重置
className("android.widget.ListView").findOne().children().forEach(function (child) {
var list = child.find(className('android.view.View'));
log(list)
if (list.length > 5) {
var title = list.get(2).contentDescription;
var content = list.get(4).contentDescription;
if (title && content) {
var integralContent = content.split('/');
var getIntegral = parseInt(integralContent[0].replace(/[^0-9]/ig, ""));
var targetIntegral = parseInt(integralContent[1].replace(/[^0-9]/ig, ""));
taskInfoList.push({
title: title,
getIntegral: getIntegral,
targetIntegral: targetIntegral,
})
}
}
});
if (!taskInfoList.length) {
toastLog('获取任务失败!请关闭应用并重启脚本...');
threads.shutDownAll();
engines.stopAll();
exit(); // 有异常退出,结束脚本
} else {
toastLog("成功获取任务列表,退到首页");
log(taskInfoList);
back();//从“积分”页跳转到“我的”
sleep(2000);
back();//从“我的”跳转到“首页”
sleep(2000);
}
};这部分也相当于一个入口函数,遍历第2步得到的任务列表的数组,通过条件分支,逐个进入各个方法体完成任务。
function doUnfinishedTask(){
var flag = 0;//判断是否完成所有任务满分的标志
var read_article_flag = 2 //判断阅读文章任务是否已完成,作为参数传入视听学习任务的new_vedio_list用于控件寻找
for(i=0;i<taskInfoList.length;i++){
var task = taskInfoList[i];
// log(task);
//如果当日获得积分<当日上限积分
if(task.getIntegral < task.targetIntegral){
flag = 1;
// log('未达成满分的任务有:'+task.title)
if(task.title=='阅读文章'){
rest_num = task.targetIntegral-task.getIntegral;
read_article_flag = 2;
readArticle(rest_num,8,false);//默认阅读8s,执行短时阅读任务
continue;
}
else if(task.title=='视听学习'){
rest_num = task.targetIntegral-task.getIntegral;
learnVideo(rest_num,read_article_flag,8,false);//默认观看8s,执行短时视听任务
continue;
}
else if(task.title=='每日答题'){
sleep(2000)
toastLog('开始执行每日答题任务(暂未开发)')
continue;
}
else if(task.title=='每周答题'){
toastLog('开始执行每周答题任务(暂未开发)')
sleep(2000)
continue;
}
else if(task.title=='专项答题'){
toastLog('开始执行专项答题任务(暂未开发)')
sleep(2000)
continue;
}
else if(task.title=='订阅'){
rest_num = task.targetIntegral-task.getIntegral;
subscribe(rest_num);
continue;
}
else if(task.title=='分享'){
share();
continue;
}
else if(task.title=='收藏'){
collect();
continue;
}
else if(task.title=='发表观点'){
comment();
continue;
}
else if(task.title=='本地频道'){
localChannel();
continue;
}
}
}
if(!flag)
{
toastLog('已完成当日所有脚本任务!d=====( ̄▽ ̄*)b')
}
};之后的部分则是实现各个功能的方法介绍。
这两部分是我一开始开发的功能模块,因为视听学习和阅读文章的操作相似,而Auto.js也是模拟人的思路去点击控件。因为时长就是停留在文章页面的时间更





