var modules = {}; function Console() { this.timerMap = {} } Console.prototype.log = function (msg) { var s = []; for (var i = 1; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.logd(formatlog(msg), s); } Console.prototype.info = function (msg) { var s = []; for (var i = 1; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.logi(formatlog(msg), s); } Console.prototype.warn = function (msg) { var s = []; for (var i = 1; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.logw(formatlog(msg), s); } Console.prototype.error = function (msg) { var s = []; for (var i = 1; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.loge(formatlog(msg), s); } Console.prototype.logLine = function (line, msg) { if (arguments.length <= 0) { return } var s = []; for (var i = 2; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.logdLine(line, formatlog(msg), s); } Console.prototype.infoLine = function (line, msg) { var s = []; for (var i = 2; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.logiLine(line, formatlog(msg), s); } Console.prototype.warnLine = function (line, msg) { var s = []; for (var i = 2; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.logwLine(line, formatlog(msg), s); } Console.prototype.errorLine = function (line, msg) { var s = []; for (var i = 2; i < arguments.length; i++) { s.push(arguments[i]); } ecImporter.logeLine(line, formatlog(msg), s); } /** * 计时开始 * @param label 标签 * @return {number} 当前时间 */ Console.prototype.time = function (label) { let t = ecImporter.time(); this.timerMap[label] = t; return t; } /** * 计时结束 * @param label 标签 * @return {number} 与计时开始的差值 */ Console.prototype.timeEnd = function (label) { let t1 = ecImporter.time(); let d2 = this.timerMap[label]; if (d2 == null || d2 == undefined) { return 0; } let t2 = t1 - d2; delete this.timerMap[label]; return t2; } var console = new Console(); function HotUpdateWrapper() { } var hotupdater = new HotUpdateWrapper(); /** * 获取热更新得请求结果 * @return {string} 字符串 */ HotUpdateWrapper.prototype.getUpdateResp = function () { return ecImporter.getHotUpdateResp(); } /** * 获取热更新重新的错误 * @return {string} 字符串 */ HotUpdateWrapper.prototype.getErrorMsg = function () { return ecImporter.hotUpdateErrorMsg(); } /** * 请求热更新接口,如果是false,也有可能是无需更新,可以使用getErrorMsg查看具体得信息 * @param updateUrl 更新地址 不写,就使用update.json配置的数据 * @param version 当前版本,使用整形数据,例如 1这样的数字 * @param appendDeviceInfo 是否拼接设备信息数据 true 或者 false * @param timeout 请求超时时间 单位是毫秒 * @return {boolean} true 代表需要更新 false代表无需更新 */ HotUpdateWrapper.prototype.updateReq = function (updateUrl, version, appendDeviceInfo, timeout) { return ecImporter.hotUpdateReq(updateUrl, version, appendDeviceInfo, timeout); } /** * 下载热更新请求到得IEC文件 * @return {string} 下载后热更新文件得路径,如果为空,也有可能是无需更新 */ HotUpdateWrapper.prototype.updateDownload = function () { return ecImporter.hotUpdateDownload(); } /** * 发送钉钉消息 * 适合EC 9.11.0+ * @param url 群组/部门 机器人Webhook地址 * @param secret 群组/部门 机器人Webhook密钥, 可以不写使用关键字过滤方式 * @param msg 要发送的消息 * @param atMobile at手机号,多个用英文逗号隔开 * @param atAll 是否at所有人,写true或者false * @return {string} 调用钉钉返回的json字符串结果,格式 {"errcode":0,"errmsg":"ok"},errcode=0代表成功其他都是错误 */ function sendDingDingMsg(url, secret, msg, atMobile, atAll) { return ecImporter.sendDingDingMsg(url, secret, msg, atMobile, atAll); } /** * 休眠 * @param miSecond 毫秒 */ function sleep(miSecond) { ecImporter.sleep(miSecond); } /** * 脚本是否处于暂停中 * 适配 EC 10.0.0+ * @return {boolean} true 代表脚本处于暂停中 */ function isScriptPause() { return pauseScriptWrapper.isScriptPause(); } /** * 设置脚本暂停或者继续 * 适配 EC 10.0.0+ * @param pause true 代表暂停脚本,false代表继续 * @param timeout 自动恢复时间单位毫秒,0 代表不自动恢复,等待外部交互后恢复,大于0代表到了时间自动恢复运行 * @return {boolean} true 代表脚本处于暂停中,false 代表继续运行中 */ function setScriptPause(pause, timeout) { pauseScriptWrapper.setScriptPause(pause, timeout); return pauseScriptWrapper.isScriptPause(); } function toast(msg, extra) { if (extra) { ecImporter.toastWithSetting(msg, JSON.stringify(extra)); } else { ecImporter.toast(msg); } } function toast1(msg) { ecImporter.toast1(msg); } function toast2(msg) { ecImporter.toast2(msg); } function getHandler() { return ecImporter.getHandler(); } function formatlog(obj) { return obj + ""; } /** * 设置日志等级,可用于关闭或开启日志 * @param level 日志等级,值分别是 debug,info,warn,error,off,排序分别是debug * {
* "node_service":"需要",
* "proxy_service":"不需要",
* "running_mode":"无障碍",
* "auto_start_service":"是",
* "daemon_service":"是",
* "volume_start_tc":"否",
* "log_float_window":"否",
* "ctrl_float_window":"否"
* }
* 参数解释有:
* node_service : 是否需要启动节点获取服务 值有 需要,不需要两种 * proxy_service : 是否需要启动底层代理服务 值有 需要,不需要两种 * running_mode : 手势执行服务 值有 无障碍,代理两种 * auto_start_service : 开机启动服务 值有 是,否 两种 * daemon_service : 守护服务 值有 是,否 两种 * volume_start_tc : 音量键启停 值有 是,否 两种 * log_float_window : 日志悬浮窗展示 值有 是,否 两种 * ctrl_float_window : 启停控制悬浮窗展示 值有 是,否 两种 * * @return {boolean} true 是 false 否 */ function setECSystemConfig(params) { return ecImporter.setECSystemConfig(JSON.stringify(params)); } /** * 载入dex文件 * @param path 路径,加载顺序分别是插件目录(例如 ab.apk)或者是文件路径(例如 /sdcard/ab.apk)加载 * @return {boolean} true 载入成功, false载入失败 */ function loadDex(path) { return ecImporter.loadDex(path); } /** * 设置重复加载dex,apk,防止插件过大导致加载时间过长 * @param r 是否重复加载,true 可以重复加载,false 不可以重复加载 * @return {boolean} true 载入成功, false载入失败 */ function setRepeatLoadDex(r) { return ecImporter.setRepeatLoadDex(r); } /** * 执行JS文件或者内容 * @param type 1=文件,2=直接是JS内容 * @param content 路径例如/sdcard/a.js或者js的内容 * @return {boolean} true代表执行成功, false代表失败 */ function execScript(type, content) { if (type == 1) { content = file.readFile(content); } if (content != undefined && content != null) { if (content.length > 0) { eval(content); return true; } } return false; //return ecImporter.execScript(type, content); } /** * 载入jar文件 * @param path 路径,加载顺序分别是插件目录(例如 ab.jar)或者是文件路径(例如 /sdcard/ab.jar)加载 * @return {boolean} true 载入成功, false载入失败 */ function loadJar(path) { return ecImporter.loadJar(path); } /** * 退出脚本执行 */ function exit() { ecImporter.exit(); } /** * 判断EC运行的当前线程是否处于退出状态,可用判断脚本是否退出,或者子线程是否退出 * @return {boolean} true 已退出 */ function isScriptExit() { return ecImporter.isScriptExit(); } /** * 重启脚本,适合无限循环,或者有异常的情况可以下载最新的iec再次执行,避免进入UI才能热更新, * 注意: 该方法威力巨大,请自行控制好是否自动重启,否则只能强杀进程才能停止 * @param path 新的IEC路径,如果不需要可以填写null * @param stopCurrent 是否停止当前的脚本 * @param delay 延迟多少秒后执行 * @return {boolean} true 代表成功 false 代表失败 */ function restartScript(path, stopCurrent, delay) { return ecImporter.restartScript(path, stopCurrent, delay); } /** * 保存res文件夹中的资源文件到指定的路径 * @param fileName 文件名称,不要加res前缀 * @param path 要保存到的路径地址,例如/sdcard/aa.txt * @return {boolean} true代表保存成功 */ function saveResToFile(fileName, path) { return ecImporter.saveResToFile(fileName, path); } /** * 读取res文件夹中的资源文件,并返回字符串 * @param fileName 文件名称,不要加res前缀 * @return {null|string} 如果是null代表没内容 */ function readResString(fileName) { return javaString2string(ecImporter.readResString(fileName)); } /** * 查找IEC的文件 * 适合版本 EC 8.0.0+ * @param dir 文件夹名称,null代表只读res/文件夹,没有默认是res文件夹,可以是类似 res/aaa/这样的文件夹 * @param names 文件名称前缀,null代表不匹配, 例如aaa,多个前缀用|分割,例如 aaa|bb|cc * @param ext 文件扩展名 ,null代表不匹配,例如.png,多个扩展用|分割,例如 .png|.jpg|.bmp * @param recursion 是否递归子目录,true代表递归 * @return {null|JSON} 文件名称JSON数组 */ function findIECFile(dir, names, ext, recursion) { let s = ecImporter.findIECFile(dir, names, ext, recursion); if (s == null) { return null; } s = javaString2string(s); try { return JSON.parse(s); } catch (e) { return null; } return null; } /** * 读取IEC文件中的资源文件,并返回字符串 * @param fileName 文件名称,如果放在某个文件夹下 需要加上文件名称 * @return {null|string} 如果是null代表没内容 */ function readIECFileAsString(fileName) { return javaString2string(ecImporter.getPkgContent(fileName)); } /** * 读取IEC文件中的资源文件,并返回java的直接数组 * @param fileName 文件名称,如果放在某个文件夹下 需要加上文件名称 * @return {null|字节数组|*} 如果是null代表没内容 */ function readIECFileAsByte(fileName) { return ecImporter.getPkgContentAsByte(fileName); } /** * 读取res文件夹中的资源文件,并返Bitmap图片对象 * @param fileName 文件名称,不要加res前缀 * @return {null|Bitmap} 如果是null代表没内容 */ function readResBitmap(fileName) { return ecImporter.readResBitmap(fileName); } /** * 启动自动化环境 * @return {boolean} true代表启动成功,false代表启动失败 */ function startEnv() { return ecImporter.startEnv(); } /** * 守护自动化环境, * 如果是激活或者无障碍保活的情况下,尽量保证自动服务不掉线 * @param daemon 是否守护自动化环境 true 是,false 否 * @return {boolean} true代表启动成功,false代表启动失败 */ function daemonEnv(daemon) { return ecImporter.setDaemonAutoService(daemon); } /** * 设置代理模式下获取节点方式 * 该方法仅对代理模式生效 * EC 安卓 11.2.0+ * 该方法在启动代理服务之前调用,使用2和3 可以减少检测的特征 * 1的方式会出现 ruru检测出 AccessibilityManager.isEnabled,2和其他的方式不会出现 * 1的方式节点能力交强,2节点功能较弱,0和3 就没有节点功能 * @param support 1 类似无障碍一样的方式, 2 shell dump的的方式,3或者0 不开启节点服务 * @return {boolean} true */ function setAgentSupportNode(support) { return ecImporter.setAgentSupportNode(support + ""); } /** * 获取打包混淆后的真实组件名称 * @param name 原始名称 * @return {string} 真实的类名 */ function getComponentRealName(name) { return ecImporter.getComponentRealName(name); } /** * 关闭自动化环境 * @param skinAccPage 无障碍模式停止失败 是否跳转到开启无障碍页面 * @return {boolean} true代表启动成功,false代表启动失败 */ function closeEnv(skinAccPage) { return ecImporter.closeEnv(skinAccPage); } /** * 设置壁纸服务函数 * @return {boolean} true代表启动成功,false代表启动失败 */ function setWallpaperService() { return ecImporter.setWallpaperService(); } /** * 是否设置壁纸成功 * @return {boolean} true代表成功,false代表失败 */ function isWallpaperServiceSet() { return ecImporter.isWallpaperServiceSet(); } /** * 自动化服务是否正常 * @return {boolean} true代表正常,false代表不正常 */ function isServiceOk() { return ecImporter.isServiceOk(); } /** * 设置要执行的IEC文件路径 * @param path 文件路径 * @return {boolean} true代表成功 false代表失败 */ function setIECPath(path) { return ecImporter.setIECPath(path); } /** * 获取要执行的IEC文件路径 * @return {null|string} null代表无。ts.iec 代表是包内iec文件,其他代代表存储路径中的文件 */ function getIECPath() { return ecImporter.getIECPath(); } function javaString2string(x) { if (x == null) { return null; } return "" + x; } function setStopCallback(callback) { ecImporter.onScriptStopCallback(callback); } function setExceptionCallback(callback) { ecImporter.onScriptExCallback(callback); } /** * 对事件进行监听 * @param event 事件类型 类型有: * activity-change 页面切换,OK * notification-show:状态栏通知展示, OK * toast-show:Toast消息展示, OK * key-down:按键按下, OK * key-up:按键弹起 OK * acc-service-interrupt:无障碍服务被中断 OK * acc-service-destroy: 无障碍服务被销毁 OK * acc-event:无障碍节点事件 OK * acc-service-connected: 无障碍服务连接成功 OK * auto-service-status: 自动化服务可用状态 * * @param callback 事件回调 * @return {boolean} | true 成功,false失败 */ function observeEvent(event, callback) { return observeEvents.on(event, callback); } /** * 取消事件监听 * @param event 事件类型 * @return {boolean} | true 成功,false失败 */ function cancelObserveEvent(event) { return observeEvents.cancelEvent(event); } /** * 时间函数 * @return {number} 毫秒级别的long时间 */ function time() { return ecImporter.time(); } /** * 申请动态权限 * 适合版本 EC 7.9.0+ * @param permissionArray 动态权限数组,可以是多个 * @timeout 申请超时时间 单位是毫秒 * @return {boolean} true 代表有权限 false代表无权限或申请失败 */ function requestRuntimePermission(permissionArray, timeout) { if (permissionArray == null || permissionArray == undefined) { return false; } let d = JSON.stringify(permissionArray) return ecImporter.requestRuntimePermission(d, timeout); } /** * 格式化时间函数例如:yyyy-MM-dd HH:mm:ss * @return {string} 格式话之后的当前时间 */ function timeFormat(format) { return ecImporter.timeFormat(format); } function object2JsonString(o) { if (o == null) { return "{}"; } if ((typeof o) === 'string') { return o; } return JSON.stringify(o); } /** * 激活自己 * @param activeType 激活类型,0 自动,1 模式1 2 模式2 * @param timeout 超时时间 * @return {string} 激活成功:代表成功,其他都是错误消息 */ function activeSelf(activeType, timeout) { return ecImporter.activeSelf(activeType, timeout); } /** * 通过IP激活其他设备 * @param ip 设备的IP * @param activeType 激活类型,0 自动,1 模式1 2 模式2 * @param timeout 超时时间 * @return {string} 激活成功:代表成功,其他都是错误消息 */ function activeDevice(ip, activeType, timeout) { return ecImporter.activeDevice(ip, activeType, timeout); } // ///** // * 获取当前代码执行行号 // * 适配EC 安卓 9.16.0+ // * @param data 这个必须写null否则获取不到正确行号 // * @return {int} -1 代表没获取到 // */ //function getCodeLine(data){ // return ecImporter.getCodeLine(data); //} /** * 是否同步日志到中控 * 适合版本 EC 安卓 9.27.0+ * @param logSyncToCenter true代表同步 false代表不同步 */ function commonLogToCenter(logSyncToCenter) { ecImporter.commonLogToCenter(logSyncToCenter); } /** * 取得中控发过来的任务参数信息 * 中控启动脚本,可以配置参数,在这里使用本函数获取参数,给脚本使用 * 适合版本 EC 安卓 9.27.0+ * 注意:这个需要使用参数配置,读取顺序是 优先读取单个设备配置 ,如果单个设备配置无任何数据,就读取 全局配置, * 返回参数中 含有 __from_global__ 这样的key,代表是来源于全局参数 * @return {null|JSON} 对象 **/ function getCenterTaskInfo() { let x = ecImporter.getCenterTaskInfo(); if (x != null && x != undefined && x != "") { try { return JSON.parse(x) } catch (e) { } } return null; } /** * 获取截图自允许权限 * 代理模式忽略这函数,这个适合弹窗权限截图模式 * 适配EC 10.25.0+ * 在有shell或者root权限执行,申请完毕可以关闭shell和root * 尝试获取截图自动允许权限,申请截图不会弹窗 * @return {boolean} true 代表成功 false代表失败 */ function tryGetProjectionPermission() { return ecImporter.tryGetProjectionPermission() } /** * 获取无障碍自允许权限 * 有权限后 无障碍可以自动启动 * 适配EC 10.25.0+ * 在有shell或者root权限执行,申请完毕可以关闭shell和root * 尝试获取无障碍自动化允许的权限 * @return {boolean} true 代表成功 false代表失败 */ function tryGetAccStartupPermission() { return ecImporter.tryGetAccStartupPermission() }