autojs之四史答题2.0(加ui)


效果

在这里插入图片描述


须知

1.题库,我也是漂的网上大佬的,自己去网上扒吧,扒下来后,按我之前的教程处理成{wenti:daan,wenti:daan}。
2.出现验证码会有振动,个人觉得不是很大声,害怕有上课刷的吓到先说一声,代码里可以改。
3.出现验证码,但是答题时间是不会停的,所以需要尽快输入。
4.需要注意,不同手机的控件信息可能不同,如果不能用,需要改

代码


"ui";
var appName = " SSXX";

ui.statusBarColor("#FF4FB3FF")
ui.layout(
    <drawer id="drawer">
        <vertical>
            <appbar>
             
                    <toolbar id="toolbar" bg="#ff4fb3ff" title="{{appName}}" />
                    <button id="exit" text="退出"  color="#ffffff" bg="#FF4FB3FF" />
                   
            </appbar>
            <vertical gravity="center" layout_weight="1">
                <frame>
                    {/* <View bg="#ff4fb3ff" h="54"/> */}
                    <viewpager h="84" id="pager">
                        <vertical>
                            <card w="*" h="68" margin="10 8" cardCornerRadius="6dp"
                                cardElevation="2dp" gravity="center">
                                <linear>
                                    <vertical margin="10" layout_gravity="center_vertical" layout_weight="1">
                                        <text id="name" size="18" color="#444444" text="请确认答题界面在主界面" />
                                        <text id="name" size="14" color="#444444" text="请开启无障碍服务和悬浮窗" />
                                    </vertical>

                                </linear>
                            </card>
                        </vertical>
                        <vertical>
                            <card w="*" h="68" margin="10 8" cardCornerRadius="6dp"
                                cardElevation="2dp" gravity="center">
                                <linear>
                                    <vertical margin="10" layout_gravity="center_vertical" layout_weight="1">
                                        <text id="imei" textIsSelectable="true" size="14" color="#444444" text="答题过程中进行其他操作会导致脚本停止" />
                                        <text id="Etime" size="12" text="验证码需要手动输入,注意验证码出现时答题时间不会暂停" />
                                    </vertical>

                                </linear>
                            </card>
                        </vertical>
                    </viewpager>
                </frame>
                <tabs w="40" id="tabs" tabIndicatorColor="#777777" bg="#cfcfcf" h="2" />

                <vertical padding="10 6 0 6" bg="#ffffff" w="*" h="auto" margin="0 5" elevation="1dp">
                    <Switch id="autoService" w="*" checked="{{auto.service != null}}" textColor="#666666" text="无障碍服务" />
                    <View h="5" />
                    <Switch id="xuanfuchuang" w="*" textColor="#666666" text="悬浮窗(不确定是否开启的点击->)" />
                </vertical>

                <vertical margin="0 5" bg="#ffffff" elevation="1dp" padding="5 5 10 5" w="*" h="auto">
                    <linear>
                        <checkbox id="ZDcheck" text="振动提醒(验证码出现)" layout_weight="1" />
                        <text text="振动声音大小↓" />
                    </linear>
                    <linear>
                        <seekbar id="DYseekbar" max="50" layout_weight="1" />
                        <text gravity="center" id="ZDlimit" />
                    </linear>
                    <View h="5" />

                </vertical>
                <vertical>
                    <text layout_weight="1" size="19" color="#222222" text="设置" />
                    <horizontal>
                        <radiogroup layout_weight="1" id='pianmu'>
                            <radio w="auto" checked="true" id="yx" text='英雄篇'></radio>

                            <radio w="auto" id="fx" text='复兴篇'></radio>
                            <radio w="auto" id="cx" text='创新篇'></radio>
                            <radio w="auto" id='xn' text="信念篇"></radio>
                        </radiogroup>

                        <radiogroup layout_weight="1" id='xunhuan'>
                            <radio w="auto" checked="true" id='a' text='循环5次'></radio>
                            <radio w="auto" id='b' text='10次'></radio>
                            <radio w="auto" id='c' text='20次'></radio>
                            <radio w="auto" id='d' text='每次提交后询问'></radio>
                        </radiogroup>
                            <input hint = "自定义" id='userin'>    </input>


                    </horizontal>

                </vertical>
                <linear>
                    <text layout_weight="1" size="19" color="#222222" text="日志" />
                    <button id="tolog" h="40" text="查看日志" style="Widget.AppCompat.Button.Borderless.Colored" />
                </linear>
                <text paddingLeft="5" size="16" id="oneLog" />
                <card w="*" h="*" margin="10 8" cardCornerRadius="6dp"
                    cardElevation="2dp" gravity="center">
                    <linear>
                        <vertical margin="10" layout_gravity="center_vertical" layout_weight="1">
                            <text id="n" size="18" color="#444444" text="CSDN:头发浓密的萌新的博客" />
                            <text autoLink="web" text="https://blog.csdn.net/tfnmdmx" />

                            <text id="a" size="12" color="#555555" gravity="right" text="感谢点赞评论收藏关注!" />
                            <text id="m" size="18" color="#444444" text="本程序只供交流学习" />
                            <text id="e" size="12" color="#ff0000" gravity="right" text="请勿用作其他用途       " />
                        </vertical>

                    </linear>
                </card>
                <list bg="#ffffff" elevation="1dp" h="*" id="logList">
                    <linear>
                        <text size="100" textColor="#555555" text="{{time}} " />
                        <text size="44" text="{{message}}" />
                    </linear>
                </list>
            </vertical>
            <button id="start" text="开始运行" tag="ScriptTag" color="#ffffff" bg="#FF4FB3FF" foreground="?selectableItemBackground" />
        </vertical>
    </drawer>
);

//设置滑动模式
ui.logList.setOverScrollMode(2);
//设置滑动页面的标题
ui.pager.setTitles(["", ""]);
//让滑动页面和标签栏联动
ui.tabs.setupWithViewPager(ui.pager);

//无障碍开关监控
ui.autoService.setOnCheckedChangeListener(function (widget, checked) {
    if (checked && !auto.service) {
        app.startActivity({
            action: "android.settings.ACCESSIBILITY_SETTINGS"
        });
    }
    if (!checked && auto.service) auto.service.disableSelf()
    ui.autoService.setChecked(auto.service != null)
});

ui.xuanfuchuang.setOnCheckedChangeListener(function (widget, checked) {
    if (checked) {
        app.startActivity({
            packageName: "com.android.settings",
            className: "com.android.settings.Settings$AppDrawOverlaySettingsActivity",
            data: "package:" + context.getPackageName(),
        });
    }
    // 没有悬浮窗权限,提示用户并跳转请求
    toast("本脚本需要悬浮窗权限来显示悬浮窗");

    //if(!checked&&auto.service)auto.service.disableSelf()
    //ui.xuanfuchuang.setChecked(auto.service!=null) 
});

//存储
ui.DYseekbar.setOnSeekBarChangeListener({
    onProgressChanged: function (v, i, fromUser) {
        ui.run(() => { ui.ZDlimit.setText("" + i * 40) })
        storages.create(appName).put("ZDlimit", i * 10)

          //toast(ui.ZDlimit.getText())
    }
})

//存储器
ui.DYseekbar.setProgress(storages.create(appName).get("ZDlimit", 200) / 10)
//回到本界面时,resume事件会被触发
ui.emitter.on("resume", () => {
    // 此时根据无障碍服务的开启情况,同步开关的状态
    ui.autoService.checked = auto.service != null;

    // ui.xuanfuchuang.checked = auto.service != null;

});
//禁止返回退出脚本
ui.emitter.on("back_pressed", function (event) {
    if (workThread && workThread.isAlive()) {
        backTag = true;
        toast("为防止脚本自动退出,脚本运行时不可返回退出软件");
        event.consumed = true;
    }
})
ui.tolog.click(() => {
    app.startActivity("console")
})

ui.start.click(() => {
    ui.start.setText("停止运行");
    workThread = threads.start(function () {
        try {
            clearLog()
            if (!auto.service) toast("请先打开无障碍服务");
            else workMain()
        } catch (e) {
            if (!e.javaException instanceof java.lang.InterruptedException)
                console.error("运行出错:" + e.toString())
        } finally {
            ui.run(function () {
                ui.start.setText("开始运行")
                threads.start(main)

            });
        }
    });
});

ui.exit.click(() => {
    log("停止运行");
    threads.shutDownAll()
    exit()
});

//var thread = threads.start(function() {

var 多选 = 0  //1是0否
var 选项 = ["初", "始", "化", "用"]
function 设置悬浮窗(悬浮窗位置x, 悬浮窗位置y,10开启控制栏) {


    var 悬浮窗 = floaty.window(
        //floaty.rawWindow
        <frame gravity="center" bg="#CC999999">
            <text id="text" textColor="#ffffffff">开启悬浮窗</text>
        </frame>
    );

    悬浮窗.setPosition(悬浮窗位置x, 悬浮窗位置y)

    if (10开启控制栏 == 1) {
        悬浮窗.setAdjustEnabled(true)
    }

    return 悬浮窗
}
/*
 *好像相当于控制台
 *在悬浮窗和日志里打印信息
 */
function 提示文本(_text) {
    ui.run(function () {
        悬浮窗.text.setText(_text);
    });
    log(_text)
}
function 加载题库(path) {

    //path = "/storage/emulated/0/脚本/cx.js"
    var 题库 = files.read(path)//题库里有一个题目分行,导致错误,需要手动处理
    pattern = /[`~!@#$^&*()=|';'“”\\\.<>\/?~!@#¥……&*()——|【】';:'。,、?\s]/g;
    题库 = 题库.replace(pattern, "")
    //log(题库)

    题库 = eval("(" + 题库 + ")");
    return 题库
}
/*
*读取题目
*处理题目
*/
function 读取题目() {
    多选 = 0
    控件 = className("android.view.View").find();
    题目 = ''
    jj = 0
    for (i = 0; i < 控件.length; i++) {
        控件里的文字 = 控件[i].text();
        if (控件里的文字 != "") {
            题目 += 控件里的文字;
            //log(控件[i].depth()+","+控件[i].indexInParent()+","+控件[i].text())
            //多选题比单选多一行checkbox-group
            if (控件里的文字.indexOf('学】') > -1 || 控件里的文字.indexOf('学]') > -1) {
                break
            }
        }
    }

    if (题目.indexOf("多选题") != -1) { //【单选题】【多选题】
        多选 = 1
    }

    if (题目.indexOf("题】") != -1) { //【单选题】【多选题】
        var index = 题目.indexOf("题】")
        题目 = 题目.substring(index + 2, 题目.length)
    }
    if (题目.indexOf("【出题:武汉大学】") != -1) {
        var index = 题目.indexOf("【出题:武汉大学】")
        题目 = 题目.substring(0, index)
    }
    if (题目.indexOf("[题目来源:") != -1) {    //[题目来源:湘潭大学西安交通大学上海交通大学]
        var index = 题目.indexOf("[题目来源:")
        题目 = 题目.substring(0, index)
    }

    //对获取的题目进行处理,去除所有特殊字符
    pattern = /[`~!@#$^&*()=|{}':;'“”,\\\[\]\.<>\/?~!@#¥……&*()——|{}【】';:""'。,、?\s]/g;
    题目 = 题目.replace(pattern, "")
    log(题目)
    return 题目
}
function 提取选项() {
    if (!多选) {
        for (i = 0; i < 4; i++) {
            选项[i] = ''
            if (className("RadioButton").depth("24").indexInParent(i).findOnce())
                className("RadioButton").depth("24").indexInParent(i).findOne().children()
                    .forEach(function (child) {
                        //log(child.className());
                        if (child.className() == "android.view.View") {
                            if (child.text() != "") {
                                if (选项[i] != child.text())
                                    选项[i] += child.text()
                                //log(child.text());
                            }
                            else {
                                child.children()
                                    .forEach(function (child) {
                                        // log(child.className());
                                        if (child.text() != "") {
                                            if (选项[i] != child.text())
                                                选项[i] += child.text()
                                            //log("!" + child.text());
                                        }
                                    });
                            }
                        }
                    });
            //log("++++" + 选项[i]);
        }
    }
    else {
        for (i = 0; i < 4; i++) {
            选项[i] = ''
            if (className("CheckBox").depth("23").indexInParent(i).findOnce())
                className("CheckBox").depth("23").indexInParent(i).findOne().children()
                    .forEach(function (child) {
                        if (child.className() == "android.view.View") {
                            //  log(child.className());
                            if (child.text() != "") {
                                if (选项[i] != child.text())
                                    选项[i] += child.text()
                                //   log(" " + child.text());
                            }
                            else {
                                child.children()
                                    .forEach(function (child) {
                                        if (child.className() == "android.view.View") {
                                            // log(child.className());
                                            if (child.text() != "") {
                                                if (选项[i] != child.text())
                                                    选项[i] += child.text()
                                                //log("!" + child.text());
                                            }
                                        }
                                    });
                            }
                        }
                    });
        }
    }


    pattern = /[`~!@#$^&*()=|{}':;'“”,\\\[\]\.<>\/?~!@#¥……&*()——|{}【】';:""'。,、?\s]/g;

    for (i = 0; i < 4; i++) {
        提示文本("选项" + i + 选项[i] + " ");
        选项[i] = 选项[i].replace(pattern, "")
    }
}

/* 
*匹配答案
*   题库中[第i个题目].indexof(题目)>-1,表示匹配到问题
*   返回答案
*/
function 匹配答案(题库, 题目) {
    i = 0
    flag = 0
    while (Object.keys(题库)[i]) {
        if (Object.keys(题库)[i].indexOf(题目) > -1) {

            flag = 1
            var 答案 = 题库[Object.keys(题库)[i]]
            return 答案
        }
        i++;

    }
    if (flag == 0) 提示文本("没有匹配到问题,自行作答,百度搜索") //没有写百度搜索
    return -1
}
function 点击答案(答案) {
    if (答案 == -1) {
        if (className("android.widget.RadioButton").depth("24").indexInParent(1).findOnce()) {
            className("android.widget.RadioButton").depth("24").indexInParent(1).findOnce().click()
            toast("无匹配,默认点击第2个")
        }
    /*     else if (className("android.widget.RadioButton").depth("25").indexInParent(1).findOnce()){
            
                className("android.widget.RadioButton").depth("25").indexInParent(1).findOnce().click()
            提示文本("点击出错");
      return 0
        } */
        else {
            toast("默认全选")
            for (j = 0; j < 4; j++) {
                sleep(1000 + random(0, 3000))
                随机位置x = className("android.widget.CheckBox").depth(23).indexInParent(j).findOnce().bounds().centerX() + random(0, 300)
                随机位置y = className("android.widget.CheckBox").depth(23).indexInParent(j).findOnce().bounds().centerY() + random(0, 30)
                click(随机位置x, 随机位置y)
    
            }
        }
        
    }
    else {
        if (!多选) {
            for (j = 0; j < 4; j++) {
                if (答案.indexOf(选项[j]) > -1) {
                    //第一次开始有可能点错//多选匹配
                    //答案相近,即前面的选项含有答案的文字就会被点击,必须提取完整答案
                    sleep(1000 + random(0, 3000))
                    随机位置x = className("android.widget.RadioButton").depth("24").indexInParent(j).findOnce().bounds().centerX() + random(0, 100)
                    随机位置y = className("android.widget.RadioButton").depth("24").indexInParent(j).findOnce().bounds().centerY() + random(0, 30)
                    click(随机位置x, 随机位置y)
                    break
                }
            }
        }
        else if (多选 == 1) {
            for (j = 0; j < 4; j++) {
                if (答案.indexOf(选项[j]) > -1) {
                    toast("点击" + j);

                    随机位置x = className("android.widget.CheckBox").depth(23).indexInParent(j).findOnce().bounds().centerX() + random(0, 100)
                    随机位置y = className("android.widget.CheckBox").depth(23).indexInParent(j).findOnce().bounds().centerY() + random(0, 30)
                    click(随机位置x, 随机位置y)
                    sleep(1000 + random(0, 3000))
                }
            }
        }
    }
    return 1
}
function vibrate(duration, times, delay) {
    if (delay == null) delay = 0
    if (times == null) times = 1
    for (i = 0; i < times; i++) {
        device.vibrate(duration);
        sleep(delay)
    }
}

function 检测验证码(){
    //toast("检测验证码")
    if (text("验证码").exists()) {//会影响下一道题
        if(ui.ZDcheck.isChecked())
            vibrate(ui.ZDlimit.getText(), 3, 200)
        else{
            toast("zahuishia")

        }
        alert("验证码出现啦!救命啊!");
        sleep(10000)
        toast("还有5s")
        sleep(5000)
    }

}
function main() {
  
    pm = -1
    xh = -1
    if (ui.yx.isChecked()) pm = 1;
    if (ui.fx.isChecked()) pm = 2;
    if (ui.cx.isChecked()) pm = 3;
    if (ui.xn.isChecked()) pm = 4;

    if (ui.a.isChecked()) xh = 1;
    if (ui.b.isChecked()) xh = 2;
    if (ui.c.isChecked()) xh = 3;
    if (ui.d.isChecked()) xh = 4;
    /*toast('pm='+pm+'pm=')//322
     toast('xd='+xh+'pm=')
    toast(ui.ZDlimit.getText())*/
    悬浮窗 = 设置悬浮窗(100, 100, 0)
    提示文本("加载悬浮窗");

    launch("com.tencent.mm");
    提示文本("跳转微信");

    提示文本("加载题库中...");
    switch (pm) {
        case 1: path = "/storage/emulated/0/脚本/yx.js"; pmtext = "英雄篇"; pmx = random(80, 500); pmy = random(900, 1100); break;
        case 2: path = "/storage/emulated/0/脚本/fx.js"; pmtext = "复兴篇"; pmx = random(560, 1000); pmy = random(900, 1100); break;
        case 3: path = "/storage/emulated/0/脚本/cx.js"; pmtext = "创新篇"; pmx = random(80, 500); pmy = random(1200, 1400); break;
        case 4: path = "/storage/emulated/0/脚本/xn.js"; pmtext = "信念篇"; pmx = random(560, 1000); pmy = random(1200, 1400); break;
        default: path = "/storage/emulated/0/脚本/yx.js";
    }
    题库 = 加载题库(path)
    提示文本(pmtext + "-题库加载完成");

    sleep(3000)
    提示文本("开始答题");
    if (text("返回").exists())
    {
        click("返回")
        sleep(2000)
    }
    click(pmx, pmy)
    sleep(2000)

    switch (xh) {
        case 1: 循环 = 5; break;
        case 2: 循环 = 10; break;
        case 3: 循环 = 20; break;
        case 4: 循环 = 1; break;
        default: 循环 = 1;
    }

    while (循环--) {
        if (text("返回").exists())
        {
            click("返回")
            sleep(2000)
        }
        click(pmx, pmy)
        sleep(2000)

        while (1) {
            检测验证码()

            题目 = 读取题目()
            检测验证码()
            提取选项()
            检测验证码()
            提示文本("正在匹配答案");
            答案 = 匹配答案(题库, 题目)
            检测验证码()
            sleep(1000)

            提示文本("答案:" + 答案)
            if (点击答案(答案)) {
                检测验证码()
                sleep(2000)
                if(text("下一题").exists())
                   click("下一题")//一直可点,未作答点击无反应
                else{

    if ( text("提交").exists()) {
                    sleep(2000)
                    click("提交")//一直可点,未作答点击无反应
                    提示文本("提交")
                    sleep(2000)
                    break
                }
                检测验证码()
                   }
            }
            sleep(4000)
            
            if (题目.indexOf("答对题目数") > -1) {
                sleep(2000)
                break
            }
        }
        if(循环==0||xh == 4){
            循环 = confirm("要继续刷题吗?");
            if (循环) {

                循环 = 1
                sleep(2000)
                while (!click("返回"))
                toast("返回")
                sleep(2000)
            }
            else {
                toast("脚本已停止")
                threads.shutDownAll()
                exit()
                break
            }
        }
        
        
    }

    }
//});

//目标是写每隔10s检测是否有验证码,有就暂停脚本,之后继续脚本
/* var thread_yanzhengma = threads.start(function(){
    //设置一个空的定时来保持线程的运行状态
    setInterval(function(){
toast("检测验证码")
        if (text("验证码").exists()) {//会影响下一道题
            if(ui.ZDcheck.isChecked())
                vibrate(ui.ZDlimit.getText(), 3, 200)
            alert("验证码出现啦!救命啊!");
            sleep(10000)
            toast("还有5s")
            sleep(5000)
        }

    }, 10000);
}); */
/* 
//检测出错,一分钟页面都没变,视为出错,随机点击可能位置
var thread_tijiao = threads.start(function(){

    if (n >= 20 && text("提交").exists())
    //设置一个空的定时来保持线程的运行状态
    setInterval(function(){}, 1000);
}); */

/* if (上次答案 == 答案) {
    if (!多选) {
        toast("默认点击第2个")
        className("android.widget.RadioButton").depth("24").indexInParent(1).findOnce().click()
    }
    else {
        toast("默认全选")
        for (j = 0; j < 4; j++) {
            sleep(1000 + random(0, 3000))
            随机位置x = className("android.widget.CheckBox").depth(23).indexInParent(j).findOnce().bounds().centerX() + random(0, 300)
            随机位置y = className("android.widget.CheckBox").depth(23).indexInParent(j).findOnce().bounds().centerY() + random(0, 30)
            click(随机位置x, 随机位置y)

        }
    }
} */

问题

希望路过的大佬可以指点一下
一,怎么把退出放到软件名字那一栏的左边(即整个页面的左上角),网上查到的只有菜单栏的配置,就是三个点,是不是不能更改成其他的?

二,对于识别验证码的问题,我试了调用百度识图,识别效果挺差的,现在想试试联众,有知道的朋友可以指点一下吗?

三,对于多线程问题,本来准备写一个子线程间隔时间一直检测的,但是由于初次接触,还不能很好的使用线程,导致在子线程检测到验证码后,主线程(可能是)仍然会继续运行,望大佬指点。

总结

本次更新增加了ui界面,也使用了一点点多线程,在学习更多知识之后会写一些总结。

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tfnmdmx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值