小米手机运行时(xiaomi_runtime)

Oct 10, 2021, 3:00:15 PM
本文专门针对小米手机实现了通用的运行时代码(红米9A,8A测试通过),代码如下:
function waitAppLaunched(tag, options) {
    options.maxStep /= 2;
    var ret = smartFindView(tag, options);
    if (ret.length <= 0) {
        refresh();
        ret = smartFindView(tag, options);
    }
    return ret;
}

function smartLaunchApp(packageName, autoInstall=true, checkUpdate=true, afterWait=6000) {
    console.log('启动:' + packageName);
    var result = false;

    var version = getAppVersion(packageName);
    var appName = getAppName(packageName);
    sendMessage('run_msg', '正在启动:' + appName);
    console.log('packageName:' + packageName + '  version:' + version);
    if (version == '') {
        console.log('没有安装app');
        if (autoInstall) {
            sendMessage('run_msg', '正在安装:' + appName);
            if (__installApp(packageName)) {
                console.log('安装成功');

                sleep(2000);
                console.log('hh appName:' + appName);
                sendMessage('run_msg', '正在设置:' + appName);
                if (__appSetting(appName)) {
                    result = 1 == launchApp(packageName);
                }
            } else {
                console.log('安装失败');
            }
        }
    } else {
        if (checkUpdate) {
            var latestVersion = getLatestAppVersion(packageName);
            console.log('latestVersion:' + latestVersion);
            if (latestVersion != '') {
                var version = getAppVersion(packageName);
                if (__compareVersion(latestVersion, version)) {
                    // update
                    if (__installApp(packageName)) {
                        console.log('安装成功');
                    }
                }
            }
        }

        result = 1 == launchApp(packageName);
    }

    if (result) {
        clickByTag('txt:允许', {click: true, maxStep: 8});

        sleep(afterWait);
    }

    return result;
}

function exitAppDeal() {
    home();

    sleep(1000);

    recentApps();

    sleep(1000);

    clickByTag('id:com.android.systemui:id/clearAnimView', {click: true});

    sleep(1000);

    recentApps();

    sleep(1000);

    clickByTag('txt:' + getAppName(), {click: true});
}

function __compareVersion(newVersion, oldVersion) {
    if (newVersion && oldVersion) {
        newVersion = newVersion.trim();
        oldVersion = newVersion.trim();
        var newArr = newVersion.split('.'), oldArr = oldVersion.split('.');
        var size = Math.min(newArr.length, oldArr.length);
        for (var i = 0; i < size; ++i) {
            var newV = parseInt(newArr[i]);
            var oldV = parseInt(oldArr[i]);
            if (newV > oldV) {
                return true;
            } else if (newV < oldV) {
                break;
            }
        }
    }

    return false;
}

function __installApp(packageName) {
    var savedPath = downloadApp(packageName);
    console.log('savedPath:' + savedPath);
    if (savedPath != '') {
        if (install(savedPath)) {
            // 开始点击界面
            console.log('开始点击安装界面');
            sleep(2000);
            var findInstall = false, clickInstall = false, startTime = new Date().getTime();
            while (!clickInstall && (new Date().getTime() - startTime) < 100000) {
                var ret = findView('txt*:解析软件包时出现问题|id:com.miui.packageinstaller:id/install_btn|txt:继续安装|txt*:无视风险安装|txt:退出登录');
                if (ret.length > 0) {
                    console.log('find:' + ret.tag);
                    if (ret.tag == 'com.miui.packageinstaller:id/install_btn' || ret.tag == '继续安装') {
                        click(ret.views[0], {click: true});
                    } else if (ret.tag == '退出登录') {
                        break;
                    } else if (ret.tag == '无视风险安装') {
                        var view = ret.views[0];
                        gestureClick(view.right - 100, (view.top + view.bottom) / 2, {afterWait:1000});
                    } else {
                        console.log('解析软件包失败');
                        clickByTag('txt:确定', {click: true});
                        break;
                    }
                    findInstall = true;
                }

                if (findInstall) {
                    ret = findView('txt:确定|id:com.miui.packageinstaller:id/done_button');
                    if (ret.length > 0) {
                        click(ret.views[0], {click: true});
                        clickInstall = true;
                    }
                }
            }

            console.log('完成安装:' + clickInstall);
            return clickInstall;
        } else {
            console.log('install failed:');
        }
    }

    return false;
}

function __appSetting(appName) {
    if (!launchApp('com.android.settings')) {
        return false;
    }

    var ret = smartFindView('txt:设置', {failed: __exitPopup, maxStep: 30});
    if (ret.length <= 0) {
        console.error('启动设置程序失败');
        return false;
    }

    scroll('up', {distance: 0.99, afterWait: 1000});

    var result = false, scrollCount = 0, target = 'txt:应用设置|txt:授权管理|';
    while(scrollCount <= 3 && target!= '') {
        ret = smartFindView(target, {failed: __exitPopup});
        if (ret.length <= 0) {
            console.log('没找到tag,滚动后继续找');
            scrollCount++;
            scroll('up', {distance: 0.99, afterWait: 1000});
        } else {
            result = true;
            if (ret.tag == '应用设置') {
                result = switchPage('txt:应用设置', 'txt:授权管理', {failed: __exitPopup, click: true}).length > 0;
            }

            if (result) {
                result = false;
                ret = switchPage('txt:授权管理', 'txt:应用权限管理', {failed: __exitPopup, click: true});
                if (ret.length > 0) {
                    ret = switchPage('txt:应用权限管理', 'txt:应用管理', {failed: __exitPopup, click: true});
                    if (ret.length > 0) {
                        if (clickByTag('txt$:个应用程序', {click: true})) {
                            ret = findView('cn:miui.widget.ClearableEditText');
                            if (ret.length > 0) {
                                paste(ret.views[0], appName, {type: 'paste', afterWait: 3000});

                                var container = findView('cn:androidx.recyclerview.widget.RecyclerView');
                                if (container.length > 0 && container.views[0].size > 0) {
                                    click(container.views[0][0], {click: true, afterWait: 1000});
                                    ret = findView('txt:读取应用列表', {maxStep: 6});
                                    if (ret.length > 0) {
                                        if (ret.views[0].parent.parent[1].text != '拒绝') {
                                            ret = switchPage('txt:获取手机中已安装的应用信息', 'txt:取消', {click: true, failed: __exitPopup});
                                            if (ret.length > 0) {
                                                result = clickByTag('txt:拒绝', {click: true, afterWait: 2000});
                                            } else {
                                                console.error('失败');
                                            }
                                        } else {
                                            console.error('已经是拒绝了');
                                            result = true;
                                        }
                                    }
                                } else {
                                    console.error('can not find recyclerView');
                                }
                            } else {
                                console.error('can not find edit');
                            }
                        }
                    } else {
                        console.error('没进入应用管理');
                    }
                }
            }
            break;
        }
    }

    return result;
}

function __exitPopup() {
    var ret = findView('txt:暂不开启', {maxStep: 1});
    if (ret.length > 0) {
        click(ret.views[0], {click: true});
    }
}

function cbWindowChange(textList, className, packageName, rawEvent) {
    if (className == 'com.miui.cleanmaster.LowMemoryIntentDispatchActivity' || className == 'com.miui.hybrid.p') {
        clickByTag('txt:取消', {click: true, afterWait: 500});
    } else if (className=='com.xiaomi.market.ui.MarketTabActivity' || className=='com.miui.hybrid.VendorLauncherActivity$Launcher0' || className=='com.ali.user.mobile.login.ui.AliuserGuideActivity' || className=='com.android.settings.Settings$AppNotificationSettingsActivity' || className=='com.xiaomi.market.ui.detail.AppDetailActivityInner') {
        back({beforeWait: 1000});
    } else if (className == 'com.android.server.am.AppNotRespondingDialog') {
        clickByTag('txt:确定', {click: true, beforeWait:500});
    } else if (className == 'miuix.appcompat.app.AlertDialog') {
        clickByTag('txt:拒绝', {click: true, beforeWait:500});
    } else if (className=='com.android.packageinstaller.PackageInstallerActivity') {
        var curAppName = getCurAppName();
        console.log('curAppName:' + curAppName + ' appName:' + getAppName());
        if (curAppName && curAppName != getAppName()) {
            back({beforeWait: 1000});
        }
    } else if (className=='com.ali.user.mobile.login.logindialog.LoginDialog') {
        clickByTag('id:com.eg.android.AlipayGphone:id/img_dialog_close', {click: true, beforeWait:1000});
    } else if (className == 'com.android.packageinstaller.permission.ui.GrantPermissionsActivity') {
        clickByTag('txt:仅在使用中允许|始终允许|拒绝', {click: true});
    } else if (className == 'com.miui.wakepath.ui.ConfirmStartActivity') {
        console.log('getCurAppName():' + getCurAppName());
        clickByTag('txt:拒绝', {click: true, beforeWait: 5000});
    } else {
        console.log('default window change failed:' + className);
        return false;
    }
    console.log('default window change success:' + className);

    return true;
}

function globalExitPopup() {
    var ret = findView('txt:存储空间严重不足|txt:存储空间不足|txt:不感兴趣|txt:坚持退出|txt:权限设置|txt*:正在尝试创建桌面图标|id:moInterstitialImageHorizontal|id:moInterstitialImageVertical|id:moInterstitialVidoe', {maxStep:1});
    if (ret.length > 0) {
        console.log('text:' + ret.tag);
        if (ret.tag == '存储空间严重不足') {
            clickByTag('txt:取消', {click: true});
        } else if (ret.tag == '存储空间不足') {
            clickByTag('txt:忽略', {click: true});
        } else if (ret.tag == '权限设置') {
            clickByTag('txt:取消', {click: true});
        } else if (ret.tag == '正在尝试创建桌面图标') {
            clickByTag('txt:天之内不再提醒', {click: true, afterWait: 1000});
            clickByTag('txt:取消', {click: true});
        } else if (ret.tag=='moInterstitialImageHorizontal' || ret.tag=='moInterstitialImageVertical' || ret.tag=='moInterstitialVidoe') {
            console.log('弹出的无名广告');
            var bound = ret.views[0].bound;
            gestureClick(bound.right - 10*rsDensity, bound.top + 10*rsDensity);
        } else {
            click(ret.views[0], {click: true});
        }
        return true;
    }

    return false;
}

function globalDealAD() {
    var ret = findView('txt*:安装应用|txt*:正在尝试开|txt^:复制成功|txt^:网址为|txt:不感兴趣|txt:放弃下载|txt:放弃奖励', {maxStep: 1});
    if (ret.length > 0) {
        var text = ret.views[0].text;
        if (text.charCodeAt(0) <= 57 && text.charCodeAt(0) >= 48) {
            text = text.substring(0, text.indexOf('|'));
        }

        if (text.includes('复制成功')) {
            clickByTag('txt:确定', {click: true});
        } else if (text.includes('安装应用')) {
            clickByTag('txt:禁止', {click: true});
        } else if (text.includes('正在尝试开')) {
            clickByTag('txt:拒绝', {click: true});
        } else if (text.includes('网址为')) {
            clickByTag('txt:确定', {click: true});
        } else {
            click(ret.views[0], {click: true});
        }

        return true;
    }

    return false;
}
smartLaunchApp函数,按包名来启动某个app。autoInstall表示是否自动安装,checkUpdate表示启动前是否检查更新。
waitAppLaunched函数,等待app启动完成。tag和options和smartFindView的参数一致。
exitAppDeal函数,退出app时的统一处理。当退出app时调用。
下面的demo演示了如何使用这些函数:
import xiaomi_runtime;

function main() {
    var hours = new Date().getHours();
    if (hours < 10 || hours > 23) {
        return;
    }

    if (!smartLaunchApp('com.daimajia.gold', false, false, 0)) {
        console.error('启动app失败');
        return;
    }

    var ret = waitAppLaunched('txt:首页', {failed: exitPopup, maxStep: 30, beforeWait: 3000});
    if (ret && ret.length > 0) {
        console.log('进入程序');
       ......
        console.log('finish');
    }

    exitAppDeal();
    console.log('end');
}

发表评论
最新评论
商务合作QQ:2231485359
Copyright © 2021-2024 杭州汇骋科技有限公司. All rights reserved. 浙ICP备15043866号-4 《冰狐智能辅助服务协议》