自动上滑脚本

自用库

当前为 2024-12-28 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/521999/1511077/%E8%87%AA%E5%8A%A8%E4%B8%8A%E6%BB%91%E8%84%9A%E6%9C%AC.js

importClass(android.content.Context);
importClass(android.provider.Settings);
importClass(android.app.KeyguardManager);
try {
    var km = context.getSystemService(Context.KEYGUARD_SERVICE);//km.isKeyguardLocked(),km.isKeyguardSecure()
    let enabledServices = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
    //log('当前已启用的辅助服务\n', enabledServices);
    if (!enabledServices.match(/.*org\.autojs\.autoxjs\.v6\/com\.stardust\.autojs\.core\.accessibility\.AccessibilityService.*/g)) {
        let Services = (enabledServices ? enabledServices + ":" : "") + "org.autojs.autoxjs.v6/com.stardust.autojs.core.accessibility.AccessibilityService";
        Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, Services);
        Settings.Secure.putString(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, '1');
        sleep(3000);
    }
    toastLog("成功开启AutoJS的辅助服务");
} catch (error) {
    //受权方法:开启usb调试并使用adb工具链接手机,执行 adb shell pm grant org.autojs.autoxjs.v6 android.permission.WRITE_SECURE_SETTING
    toastLog("请受权AutoJS启用辅助服务");
}
auto.waitFor();
//停止其它脚本
engines.all().map((ScriptEngine) => {
    if (engines.myEngine().toString() !== ScriptEngine.toString()) {
        ScriptEngine.forceStop();
    }
});
//============================================================
var AppName = ["抖音极速版","快手极速版"]; 
var runAppName = AppName[0], times = 100; //滑动次数
toastLog('当前分辨率:'+device.width+'X'+device.height);
//toastLog('唯一标识码:'+device.fingerprint);


//息屏状态将屏幕唤醒
global.opentimes=0;
while (!device.isScreenOn() || km.isKeyguardLocked()) {
    opentimes++;
    device.wakeUp();//唤醒设备
    toastLog('屏幕唤醒');
    sleep(1500); //等待屏幕亮起
    back();//如果锁屏后收到新消息,上滑不能解锁屏幕,需要返回一次后上滑
    device.keepScreenOn();//一直保持屏幕常亮
    sleep(1500);
    if (km.isKeyguardSecure()) {
        toastLog('密码解锁');
        //待开发
        break;
    } else {
        toastLog('上滑解锁');
        swipe(device.width / 2, device.height * 0.8, device.width / 2, device.height * 0.3, 400);
    }
    sleep(1500);
    if(opentimes>3){
        toastLog('解锁失败,请尝试重启本软件并开启无障碍服务');
        break;
    }
}
global.oledwin=null;
global.looptimes=times;
function Main() {
    toastLog('进入主程序');
    for (i = 0; i < AppName.length; i++) {
        looptimes=times;
        var packageName = getPackageName(AppName[i]);
        if (packageName) {
            toastLog('启动应用:' + AppName[i]);
            var appstate = launchApp(AppName[i]);
            sleep(5000);
            if (appstate) {
                toastLog("应用正在运行");
            } else {
                toastLog("无法自启动,需模拟点击");
                home();
                sleep(3000);
                var app = id("item_title").text(AppName[i]).visibleToUser(true).findOne(2000);
                if (app) {
                    click(app.bounds().centerX(), app.bounds().top - 50);
                    sleep(10000);
                }
            }
            runAppName=AppName[i];//安全线程中使用
            while (looptimes > 0) {
                //toastLog(currentActivity());
                var tiktokhomepage = className("Button").descStartsWith("侧边栏").clickable(true).boundsInside(0, 0, 500, 500).visibleToUser(true).findOnce();
                var giftshowhomepg = id('com.kuaishou.nebula:id/left_btn').clickable(true).boundsInside(0, 0, 500, 500).visibleToUser(true).findOnce();
                if (tiktokhomepage||giftshowhomepg) {
                    looptimes--;
                    var videoDuration = 0;
                    if(AppName[i]=='抖音极速版'){
                        var seekBar=className('android.widget.SeekBar').desc('进度条').findOne(1000);
                    }else{
                        var seekBar=className('android.widget.HorizontalScrollView').id('com.kuaishou.nebula:id/tab_layout').findOne(1000);
                    }
                    if (seekBar) {
                        isvideo = true;
                        let y1 = seekBar.bounds().top-5;
                        let x1 = random(100, 300);
                        let x2 = random(500, 800);
                        let duration_thread = threads.start(function () {
                            videoDuration = getDouyinVideoDuration();
                            duration_thread.interrupt();
                        });
                        gesture(random(800, 1200), [ [x1, y1],[x2, y1],[x1, y1] ]);  
                        console.log("视频时长:",videoDuration+'s');
                    }
                    var sleepTime=(videoDuration>0&&videoDuration<180)?videoDuration:random(6, 30);//每个视频随机时间 6-30秒
                    console.verbose("浏览:" + (times-looptimes), "停留:" + sleepTime + "s");
                    cutDownBySleep(sleepTime,'观看视频');
                    randomHeart();//拟人化
                } else {
                    var living = id("root").desc("关闭").clickable(true).boundsInside(device.width-300, 0, device.width, 300).visibleToUser(true).findOne(1000);//直播间
                    if (living) {
                        isvideo = true;
                        toastLog("1.退出直播间");
                        click(living.bounds().centerX(), living.bounds().centerY());
                        sleep(2000);
                    }
                    if (currentActivity() == 'com.ss.android.ugc.aweme.live.LivePlayActivity') {
                        toastLog("2.退出直播间");
                        isvideo = true;
                        back();
                    }
                    toast('不在抖音或快手页面');
                    oledwin=null;
                    sleep(3000);
                }
            }
            closeApp(runAppName);
        } else {
            toastLog("未安装:" + AppName[i]);
        }
    }
    toastLog("自动刷屏完成");
    try {
        device.cancelKeepingAwake();
        //熄屏
        runtime.accessibilityBridge.getService().performGlobalAction(android.accessibilityservice.AccessibilityService.GLOBAL_ACTION_LOCK_SCREEN);
    } catch (e) {

    }
    //停止本脚本
    engines.myEngine().forceStop();
}


/**
 * 倒计时
 * @param {倒计时秒} lasterSecend
 * @param {显示提示} message 
 */
function cutDownBySleep(lasterSecend, message) {
    message = message || "";
    floaty.closeAll();
    var fwin = floaty.rawWindow(
        `<vertical id="frame" alpha="0" w="{{device.width-500}}px" h="150px">
            <card w="auto" h="auto" layout_gravity="center" cardCornerRadius="5dp" cardBackgroundColor="#eeeeee" >
                <text id="title" text="" textColor="#333333" textSize="13sp" padding="12 8" />
            </card>
        </vertical>`
    );
    fwin.setTouchable(false);
    sleep(500);
    for (let i = lasterSecend; i > 0; i--) {
        if (oledwin) { break; }
        if (!fwin || !fwin.title) { break; }
        ui.run(() => { 
            fwin.title.setText(message + "剩余" + i + "秒"); 
            fwin.frame.attr("alpha", 0.8); 
            fwin.setTouchable(false);
            let x = parseInt((device.width - fwin.width) / 2);
            let y = device.height-550;
            fwin.setPosition(x, y);
        });
        sleep(1000);
    }
    fwin=null;
    floaty.closeAll();
    sleep(500);
}
//视频时长(秒)获取函数
function getDouyinVideoDuration() {
    var durationText = className('TextView').textMatches(/[0-9]+:[0-9]+/).boundsInside(device.width/2, 2 * device.height / 3, device.width, device.height).findOne(2000);
    //log(durationText);
    if (durationText) {
        var durationStr = durationText.text();
        //log('1',durationStr);
        var durationMatch = durationStr.match(/[0-9]+:[0-9]+/);
        if (durationMatch) {
            //log('2',durationMatch);
            var minutes = 0,seconds = 0;
            var parts = durationMatch[0].split(":");
            if (parts.length === 2) {
                //log('3',parts);
                minutes = parseInt(parts[0], 10);
                seconds = parseInt(parts[1], 10);
                return minutes * 60 + seconds + 3;
            }
        }
    }
    return 0;
}
//=============================================================
/**随机拟人化(防止被判定是机器)**/
function randomHeart(num) {
    if (7!=num&&text('当前无新视频').visibleToUser(true).findOne(1000)) {
        console.log("当前无新视频");
        click(device.right - 100, device.top - 100);
        randomHeart(7);//切换频道
        sleep(1000);
        return;
    }
    let randomIndex = num ? num : random(1, 30);
    //加速播放
    if(randomIndex % 9 == 0){
        var seekBar=className('android.widget.SeekBar').descMatches(/.*进度条.*/).findOne(1000);
        if(seekBar){
            let x1=random(90, 120);
            let y1=device.height/3;
            gestures([0, 1500, [x1,y1], [x1,y1]],[1400, 1500, [x1,y1], [1.1*x1, 2*y1]]);
            return;
        }
    }
    //随机下滑
    if (randomIndex % 8 == 0) {
        console.log('拟人:随机下滑');
        swipe(device.width / 2, device.height * 0.1 + randomIndex, device.width / 2, device.height * 0.9 - randomIndex, random(500, 1500));
        return;
    }
    //随机切换频道
    if (randomIndex == 7) {
        var idList = [];
        className('TextView').clickable(true).descEndsWith(',按钮').boundsInside(0, 0, device.width, 300).find().forEach(function(tv){
            if(!tv.desc().match(/.*已选中.*|.*团购.*|.*商城.*|.*热点.*|.*直播中.*/)){
                //log(tv.desc());
                idList.push(tv);
            }
        });
        if(idList.length>0){
            let index = random(1, idList.length) - 1;
            console.log('拟人:切换频道:' + idList[index].desc());
            idList[index].click();
            sleep(2000);
            if (text('发现通讯录朋友').visibleToUser(true).findOne(1000)) {
                console.log("关注中没有视频");
                randomHeart(7);//再次切换频道
                sleep(2000);
                slidingByCurve();
            }
            return;
        }
    }
    //连续上滑
    if (randomIndex == 6) {
        console.log('拟人:连续上滑');
        var k = random(2, 4);
        for (var i = 0; i < k; i++) {
            var j = random(2, 5);
            if (j == 3) {
                swipe(device.width / j, device.height * 0.1 + j * k, device.width / j, device.height * 0.9 - j * k, j * 50);
            } else {
                swipe(device.width / j, device.height * 0.9 - j * k, device.width / j, device.height * 0.1 + j * k, j * 50);
            }
            sleep(j * 250);
        }
        return;
    }
    //随机恢复到首页
    if(randomIndex % 4 == 0){
        console.log('拟人:随机回首页');
        sleep(3000);back();sleep(3000);back();sleep(3000);
        return;
    }
    //向上滑
    slidingByCurve();
}

/**------------------------------------------------------------
 * 从下往上滑动,随机坐标
 */
function slidingByLine() {
    // top X,Y范围
    tx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
    ty = randomPointLoc(parseInt(device.height / 5), parseInt(device.height / 4));
    // bottom X,Y 范围
    bx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
    by = randomPointLoc(parseInt(3 * device.height / 4), parseInt(4 * device.height / 5));

    slidingTime = randomRangeTime(0.8, 1.3);
    log("上滑:随机直线");
    //log("X: "+ Math.abs(bx-tx) + " Y: "+ Math.abs(by - ty));
    swipe(bx, by, tx, ty, slidingTime);
}

/*从下往上滑动,曲线滑动,随机坐标*/
function slidingByCurve() {
    // top X,Y范围
    tx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
    ty = randomPointLoc(parseInt(device.height / 5), parseInt(device.height / 4));
    // bottom X,Y 范围
    bx = randomPointLoc(parseInt(device.width / 3), parseInt(device.width / 2));
    by = randomPointLoc(parseInt(3 * device.height / 4), parseInt(4 * device.height / 5));

    slidingTime = randomRangeTime(0.2, 0.6);
    log("上滑:仿真曲线");
    //log("X: "+ Math.abs(bx-tx) + " Y: "+ Math.abs(by - ty));
    sml_move(bx, by, tx, ty, slidingTime);
}

/**
 * 上部左右滑动
 */
function left2right(direction) {
    var intX=parseInt(Math.random()*200+400);
    var intY=parseInt(Math.random()*200+200);
    var distance=parseInt(Math.random()*100+device.height/4);
    switch (direction) {
        case 1:
            //向上小距离
            sml_move(intX, intY + distance, intX, intY, 400);
            break;
        case 2:
            //向下小距离
            sml_move(intX, intY, intX, intY + distance, 400);
            break;
        case 3:
            //向左翻屏
            sml_move(
                device.width / 2 + parseInt(Math.random() * 100) + 300,
                device.height / 4 - parseInt(Math.random() * 200) + 100,
                0 + parseInt(Math.random() * 100),
                device.height / 5 + parseInt(Math.random() * 100),
                500
            );
            break;
        case 4:
            //向右翻屏
            sml_move(
                device.width / 2 - parseInt(Math.random() * 100) - 300,
                device.height / 5 - parseInt(Math.random() * 200) + 100,
                device.width - parseInt(Math.random() * 100),
                device.height / 4 + parseInt(Math.random() * 100),
                500
            );
            break;
    }
    sleep(1000);
}

/**
 * 随机位置点
 * @param {起始值} start 
 * @param {结束值} end 
 * @returns 
 */
function randomPointLoc(start,end){
    len = Math.abs(end - start); 
    loc = Math.floor(Math.random() * len) + start;
    return loc;
}

/**
 * 从几秒到几秒
 * @param {开始秒} start 
 * @param {结束秒} end 
 * @returns
 */
function randomRangeTime(start,end){
    len = Math.abs(end -start)*1000; 
    ms = Math.floor(Math.random() * len) + start*1000;
    return ms;
}

/**
 * 仿真随机带曲线滑动 
 * @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 - 150, qx + 150),
        "y": random(qy, qy + 50)
    };
    var dx2 = {
        "x": random(zx - 150, zx + 150),
        "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) {
        let newPoint=bezier_curves(point, i);
        xxyy = [parseInt(newPoint.x), parseInt(newPoint.y)]
        xxy.push(xxyy);
    }
    try {
        gesture.apply(null, xxy);
    } catch (e) {
        log(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; 
}

//关闭软件
function closeApp(appname) {
    let packageName = getPackageName(appname);
    // 使用ADB命令强行结束进程
    //shell("adb shell am force-stop " + packageName);
    console.warn('关闭应用:' + appname);
    app.openAppSetting(packageName);
    text(app.getAppName(packageName)).waitFor();
    let is_sure = textMatches(/.*强行停止.*/).visibleToUser(true).findOnce();
    if (is_sure&&is_sure.enabled()) {
        try {
            var btn = className("Button").text('强行停止').visibleToUser(true).findOnce();
            if (btn) btn.click();
            sleep(1000);
            btn = className("Button").text('强行停止').visibleToUser(true).findOnce();
            if (btn) btn.click();
            sleep(1000);
            btn = className("Button").text('确定').visibleToUser(true).findOnce();
            if (btn) btn.click();
            back(); back(); back();
            home();
        } catch (e) {
            log(app.getAppName(packageName) + "应用已被关闭");
            sleep(1000);
            back(); back(); back();
            home();
        }
    } else {
        log(app.getAppName(packageName) + "应用不能被正常关闭");
        back(); back(); back();
        home();
    }
}

/**
*监控脚本是否卡在某界面不动,发现此情况重启脚本
*/
function Observer() {
    if (oledwin) {return true;}
    function unique(arr) {
        let newArr = [arr[0]];
        for (let i = 1; i < arr.length; i++) {
            let flag = false;
            for (var j = 0; j < newArr.length; j++) {
                if (arr[i] == newArr[j]) {
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                newArr.push(arr[i]);
            }
        }
        return newArr;
    }
    currentActis = new Array();
    for (let c = 0; c < 150; c++) {
        sleep(500);
        currentActis[c] = currentActivity();
    }
    ac = unique(currentActis);
    cc = currentActivity().match(/.*ExcitingVideoActivity|.*main\.MainActivity|.*app\.Dialog/gi);
    if (ac.length == 1 && !cc) {
        return false
    }
    return true
}
//let times = rawInput("请输入要自动刷的视频次数:","50");
// 》》》》》》》》》》》》》》》》》》》 START
work_thread = threads.start(function () {
    Main();
});
 
observer_thread = threads.start(function () {
    setInterval(function () {
        console.verbose('--------多线程安全检测---------');
        if (!Observer()&&looptimes>0) {
            work_thread.interrupt();
            work_thread = threads.start(function () {
                console.warn("Main线程在5秒后重启!",currentActivity());
                toast("Main线程在5秒后重启!");
                oledwin=null;
                closeApp(runAppName);
                sleep(5000);
                Main();
            });
        }
    }, 10000);
});

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址