EasyClick 入门指南:Shell 命令与 ADB 完全指南

EasyClick 入门指南:Shell 命令与 ADB 完全指南

本文是 EasyClick 入门系列第十五篇,适用于 EasyClick 6.0+ 版本,涵盖代理模式和 Root 模式下的 Shell 命令使用

目录

  1. 前言
  2. 前置准备
  3. [EasyClick Shell API 详解](#EasyClick Shell API 详解)
  4. [常用 ADB Shell 命令大全](#常用 ADB Shell 命令大全)
  5. 实战案例
  6. 常见问题

一、前言

什么是 EasyClick?

EasyClick 是一款强大的安卓自动化测试工具,支持免 Root 执行自动化脚本。通过 Shell 命令,我们可以实现更底层的系统操作,如应用管理、系统设置修改、文件操作等。

为什么要用 Shell 命令?

  • 更强大的功能:可以执行系统级操作
  • 更高的效率:直接调用系统服务
  • 更灵活的控制:可以组合各种系统命令

二、前置准备

2.1 运行模式说明

模式 特点 适用场景
代理模式 免 Root,通过代理服务执行 大多数场景,推荐首选
Root 模式 需要 Root 权限,功能最全 需要修改系统文件等高级操作
Shizuku 模式 通过 Shizuku 服务执行(EC 9.9.0+) 无需 Root 但需要 ADB 授权

2.2 启动代理服务

javascript 复制代码
// 启动代理环境
function main() {
  // 启动代理服务
  startEnv();

  // 检查代理是否正常
  if (agentEvent.isRunning()) {
    logd("代理服务已启动");
  } else {
    loge("代理服务启动失败");
  }
}

main();

2.3 申请 Root 权限

javascript 复制代码
function main() {
  // 申请 Root 权限
  var hasRoot = shell.su();
  if (hasRoot) {
    logd("已获得 Root 权限");
  } else {
    loge("获取 Root 权限失败");
  }
}

main();

三、EasyClick Shell API 详解

3.1 应用管理类

shell.installApp - 安装应用
javascript 复制代码
/**
 * 安装 APK 文件
 * @param path APK 文件路径
 * @return boolean true 成功,false 失败
 */
function installAppExample() {
  var apkPath = "/sdcard/download/app.apk";
  var result = shell.installApp(apkPath);

  if (result) {
    logd("应用安装成功");
  } else {
    loge("应用安装失败");
  }
  return result;
}
shell.uninstallApp - 卸载应用
javascript 复制代码
/**
 * 卸载应用程序
 * @param packageName 应用包名
 * @return boolean true 成功,false 失败
 */
function uninstallAppExample() {
  var packageName = "com.example.app";
  var result = shell.uninstallApp(packageName);

  logd("卸载 " + packageName + ": " + (result ? "成功" : "失败"));
  return result;
}
shell.stopApp - 停止应用
javascript 复制代码
/**
 * 停止正在运行的应用
 * @param packageName 应用包名
 * @return boolean true 成功,false 失败
 */
function stopAppExample() {
  var packageName = "com.example.app";
  var result = shell.stopApp(packageName);

  logd("停止 " + packageName + ": " + (result ? "成功" : "失败"));
  return result;
}

3.2 命令执行类

shell.execCommand - 自动模式执行命令
javascript 复制代码
/**
 * 执行 Shell 命令,自动识别代理或 Root 模式
 * @param command 要执行的命令
 * @return string 命令执行结果
 */
function execCommandExample() {
  // 获取屏幕分辨率
  var result = shell.execCommand("wm size");
  logd("屏幕分辨率: " + result);

  // 获取当前 Activity
  var activity = shell.execCommand("dumpsys activity top | grep ACTIVITY");
  logd("当前 Activity: " + activity);

  return result;
}
shell.execAgentCommand - 代理模式执行命令
javascript 复制代码
/**
 * 在代理模式下执行 Shell 命令
 * @param command 要执行的命令
 * @return string 命令执行结果
 */
function execAgentCommandExample() {
  // 列出 sdcard 文件
  var result = shell.execAgentCommand("ls -la /sdcard/");
  logd("文件列表:\n" + result);

  // 获取电池信息
  var battery = shell.execAgentCommand("dumpsys battery");
  logd("电池信息:\n" + battery);

  return result;
}
shell.execAgentCommandEx - 获取完整执行结果(推荐)
javascript 复制代码
/**
 * 执行 Shell 命令,返回包含正常和错误结果的 JSON 数组
 * 适用版本: EC 7.6.0+
 * @param command 命令字符串
 * @return array JSON 数组,包含所有输出
 */
function execAgentCommandExExample() {
  startEnv();

  var cmd = "ls -la /sdcard/";
  var result = agentEvent.execShellCommandEx(cmd);

  if (result && result.length > 0) {
    logd("命令执行成功,输出内容:");
    for (var i = 0; i < result.length; i++) {
      logd(result[i]);
    }
  } else {
    loge("命令执行失败或无输出");
  }

  return result;
}
shell.sudo - Root 模式执行命令
javascript 复制代码
/**
 * 在 Root 模式下执行命令
 * @param command 要执行的命令
 * @return string 命令执行结果
 */
function sudoExample() {
  // 先申请 Root 权限
  if (!shell.su()) {
    loge("未获得 Root 权限");
    return null;
  }

  // 修改文件权限(需要 Root)
  var result = shell.sudo("chmod 777 /data/local/tmp/test.txt");
  logd("修改权限结果: " + result);

  // 写入系统文件(需要 Root)
  var writeResult = shell.sudo("echo 'test' > /data/local/tmp/test.txt");
  logd("写入文件结果: " + writeResult);

  return result;
}

3.3 Shizuku 支持(EC 9.9.0+)

shell.execShizukuCommand - 执行 Shizuku 命令
javascript 复制代码
/**
 * 通过 Shizuku 执行 Shell 命令
 * 适用版本: EC 9.9.0+
 * @param command 命令字符串
 * @return string 命令执行结果
 */
function shizukuExample() {
  // 检查 Shizuku 服务是否正常
  if (!shell.isShizukuOk()) {
    loge("Shizuku 服务未运行");
    return null;
  }

  var cmd = "pm list packages";
  var result = shell.execShizukuCommand(cmd);
  logd("应用列表:\n" + result);

  return result;
}
shell.isShizukuOk - 检查 Shizuku 状态
javascript 复制代码
/**
 * 检查 Shizuku 服务是否正常
 * @return boolean true 正常,false 异常
 */
function checkShizukuExample() {
  var isOk = shell.isShizukuOk();
  logd("Shizuku 服务状态: " + (isOk ? "正常" : "异常"));
  return isOk;
}

3.4 其他工具函数

shell.addSuBin - 添加 Root 命令
javascript 复制代码
/**
 * 新增 Root 命令
 * @param cmd 新的命令名称
 * @return boolean true 成功
 */
function addSuBinExample() {
  // 添加自定义命令
  shell.addSuBin("mycommand");

  // 申请 Root 权限使命令生效
  var result = shell.su();
  logd("添加命令结果: " + result);

  return result;
}

四、常用 ADB Shell 命令大全

4.1 Activity Manager (am) 命令

启动 Activity
javascript 复制代码
// 启动指定 Activity
shell.execCommand("am start -n com.example.app/.MainActivity");

// 启动 Activity 并传递参数
shell.execCommand(
  "am start -n com.example.app/.MainActivity -d 'https://example.com'",
);

// 启动服务
shell.execCommand("am startservice -n com.example.app/.MyService");

// 发送广播
shell.execCommand("am broadcast -a android.intent.action.BOOT_COMPLETED");
强制停止应用
javascript 复制代码
// 强制停止应用
shell.execCommand("am force-stop com.example.app");

// 杀死应用进程
shell.execCommand("am kill com.example.app");

// 杀死所有后台进程
shell.execCommand("am kill-all");
启动系统设置
javascript 复制代码
// 打开 WiFi 设置
shell.execCommand("am start -a android.settings.WIFI_SETTINGS");

// 打开开发者选项
shell.execCommand(
  "am start -a android.settings.APPLICATION_DEVELOPMENT_SETTINGS",
);

// 打开应用信息页
shell.execCommand(
  "am start -a android.settings.APPLICATION_DETAILS_SETTINGS -d package:com.example.app",
);

// 打开拨号界面
shell.execCommand("am start -a android.intent.action.DIAL");

// 拨打电话
shell.execCommand("am start -a android.intent.action.CALL -d tel:10086");

4.2 Package Manager (pm) 命令

应用列表查询
javascript 复制代码
// 列出所有应用
var allApps = shell.execCommand("pm list packages");

// 列出系统应用
var systemApps = shell.execCommand("pm list packages -s");

// 列出第三方应用
var thirdPartyApps = shell.execCommand("pm list packages -3");

// 查找特定应用
var specificApp = shell.execCommand("pm list packages | grep 'example'");
应用信息查询
javascript 复制代码
// 获取应用路径
var appPath = shell.execCommand("pm path com.example.app");

// 获取应用信息
var appInfo = shell.execCommand("pm dump com.example.app");

// 清除应用数据
shell.execCommand("pm clear com.example.app");

// 禁用应用
shell.execCommand("pm disable com.example.app");

// 启用应用
shell.execCommand("pm enable com.example.app");
安装/卸载应用
javascript 复制代码
// 安装应用
shell.execCommand("pm install /sdcard/app.apk");

// 覆盖安装(保留数据)
shell.execCommand("pm install -r /sdcard/app.apk");

// 卸载应用
shell.execCommand("pm uninstall com.example.app");

// 卸载但保留数据
shell.execCommand("pm uninstall -k com.example.app");

4.3 Input 命令(模拟输入)

点击和滑动
javascript 复制代码
// 点击屏幕坐标 (x, y)
shell.execCommand("input tap 500 800");

// 滑动屏幕 (起点x 起点y 终点x 终点y 持续时间ms)
shell.execCommand("input swipe 500 1500 500 500 300");

// 长按屏幕
shell.execCommand("input swipe 500 800 500 800 1000");
输入文本
javascript 复制代码
// 输入文本
shell.execCommand("input text 'Hello World'");

// 输入中文(需要转义)
shell.execCommand("input text '%E4%BD%A0%E5%A5%BD'");

// 输入按键
shell.execCommand("input keyevent 4"); // 返回键
shell.execCommand("input keyevent 3"); // Home 键
shell.execCommand("input keyevent 26"); // 电源键
shell.execCommand("input keyevent 66"); // 回车键
shell.execCommand("input keyevent 67"); // 删除键
常用按键代码
按键 代码 说明
KEYCODE_HOME 3 Home 键
KEYCODE_BACK 4 返回键
KEYCODE_CALL 5 拨号键
KEYCODE_ENDCALL 6 挂机键
KEYCODE_VOLUME_UP 24 音量加
KEYCODE_VOLUME_DOWN 25 音量减
KEYCODE_POWER 26 电源键
KEYCODE_CAMERA 27 相机键
KEYCODE_MENU 82 菜单键
KEYCODE_NOTIFICATION 83 通知键
KEYCODE_SEARCH 84 搜索键
KEYCODE_ENTER 66 回车键
KEYCODE_DEL 67 删除键
KEYCODE_TAB 61 Tab 键
KEYCODE_ESCAPE 111 ESC 键
KEYCODE_SPACE 62 空格键

4.4 设备信息命令

javascript 复制代码
// 获取设备型号
var model = shell.execCommand("getprop ro.product.model");

// 获取 Android 版本
var version = shell.execCommand("getprop ro.build.version.release");

// 获取 SDK 版本
var sdk = shell.execCommand("getprop ro.build.version.sdk");

// 获取屏幕分辨率
var size = shell.execCommand("wm size");

// 获取屏幕密度
var density = shell.execCommand("wm density");

// 获取电池信息
var battery = shell.execCommand("dumpsys battery");

// 获取内存信息
var memory = shell.execCommand("cat /proc/meminfo");

// 获取 CPU 信息
var cpu = shell.execCommand("cat /proc/cpuinfo");

// 获取存储信息
var storage = shell.execCommand("df -h");

4.5 系统设置命令

网络设置
javascript 复制代码
// 开启/关闭 WiFi
shell.execCommand("svc wifi enable");
shell.execCommand("svc wifi disable");

// 开启/关闭移动数据
shell.execCommand("svc data enable");
shell.execCommand("svc data disable");

// 开启/关闭飞行模式
shell.execCommand("settings put global airplane_mode_on 1");
shell.execCommand("am broadcast -a android.intent.action.AIRPLANE_MODE");
显示设置
javascript 复制代码
// 修改屏幕分辨率
shell.execCommand("wm size 1080x1920");

// 恢复默认分辨率
shell.execCommand("wm size reset");

// 修改屏幕密度
shell.execCommand("wm density 480");

// 恢复默认密度
shell.execCommand("wm density reset");

// 设置屏幕亮度 (0-255)
shell.execCommand("settings put system screen_brightness 200");

// 设置自动亮度
shell.execCommand("settings put system screen_brightness_mode 1");
音量设置
javascript 复制代码
// 设置媒体音量 (0-15)
shell.execCommand("media volume --set 10");

// 设置铃声音量
shell.execCommand("cmd media_session volume --stream 2 --set 10");

// 静音
shell.execCommand("input keyevent 164");

4.6 文件操作命令

javascript 复制代码
// 列出文件
shell.execCommand("ls -la /sdcard/");

// 创建目录
shell.execCommand("mkdir -p /sdcard/test_folder");

// 复制文件
shell.execCommand("cp /sdcard/file1.txt /sdcard/file2.txt");

// 移动文件
shell.execCommand("mv /sdcard/file1.txt /sdcard/folder/");

// 删除文件
shell.execCommand("rm /sdcard/file.txt");

// 删除目录
shell.execCommand("rm -rf /sdcard/folder/");

// 查看文件内容
shell.execCommand("cat /sdcard/file.txt");

// 查看文件行数
shell.execCommand("wc -l /sdcard/file.txt");

// 搜索文件内容
shell.execCommand("grep 'keyword' /sdcard/file.txt");

// 修改文件权限
shell.execCommand("chmod 777 /sdcard/file.txt");

// 修改文件所有者
shell.execCommand("chown root:root /sdcard/file.txt");

4.7 进程管理命令

javascript 复制代码
// 查看所有进程
shell.execCommand("ps");

// 查看特定进程
shell.execCommand("ps | grep 'com.example.app'");

// 查看进程详情
shell.execCommand("cat /proc/[pid]/status");

// 杀死进程
shell.execCommand("kill [pid]");

// 强制杀死进程
shell.execCommand("kill -9 [pid]");

// 查看 CPU 使用情况
shell.execCommand("top -n 1");

// 查看内存使用情况
shell.execCommand("dumpsys meminfo");

// 查看特定应用内存
shell.execCommand("dumpsys meminfo com.example.app");

4.8 日志命令

javascript 复制代码
// 查看日志
shell.execCommand("logcat -d");

// 查看特定标签日志
shell.execCommand("logcat -d -s TAG_NAME");

// 清空日志
shell.execCommand("logcat -c");

// 查看特定应用日志
shell.execCommand("logcat -d --pid=$(pidof com.example.app)");

// 导出日志到文件
shell.execCommand("logcat -d > /sdcard/log.txt");

4.9 截图和录屏

javascript 复制代码
// 截图
shell.execCommand("screencap -p /sdcard/screenshot.png");

// 录屏(默认 180 秒)
shell.execCommand("screenrecord /sdcard/video.mp4");

// 录屏指定时间(秒)
shell.execCommand("screenrecord --time-limit 30 /sdcard/video.mp4");

// 录屏指定分辨率
shell.execCommand("screenrecord --size 720x1280 /sdcard/video.mp4");

// 录屏指定比特率
shell.execCommand("screenrecord --bit-rate 4000000 /sdcard/video.mp4");

4.10 其他实用命令

javascript 复制代码
// 等待设备
shell.execCommand("wait-for-device");

// 重启设备
shell.execCommand("reboot");

// 重启到 Recovery
shell.execCommand("reboot recovery");

// 重启到 Bootloader
shell.execCommand("reboot bootloader");

// 关机
shell.execCommand("reboot -p");

// 查看当前 Activity
shell.execCommand("dumpsys activity top | grep ACTIVITY");

// 查看窗口信息
shell.execCommand("dumpsys window windows");

// 查看通知
shell.execCommand("dumpsys notification");

// 查看闹钟
shell.execCommand("dumpsys alarm");

// 查看定时任务
shell.execCommand("dumpsys jobscheduler");

五、实战案例

案例1:批量安装应用

javascript 复制代码
/**
 * 批量安装指定目录下的所有 APK
 * @param dirPath APK 所在目录
 */
function batchInstallApps(dirPath) {
  startEnv();

  // 获取目录下所有 apk 文件
  var result = shell.execAgentCommand("ls " + dirPath + "/*.apk");
  var apkFiles = result.split("\n");

  var successCount = 0;
  var failCount = 0;

  for (var i = 0; i < apkFiles.length; i++) {
    var apkPath = apkFiles[i].trim();
    if (apkPath === "") continue;

    logd("正在安装: " + apkPath);
    var result = shell.installApp(apkPath);

    if (result) {
      successCount++;
      logd("安装成功: " + apkPath);
    } else {
      failCount++;
      loge("安装失败: " + apkPath);
    }

    // 延时 1 秒,避免安装过快
    sleep(1000);
  }

  logd("批量安装完成 - 成功: " + successCount + ", 失败: " + failCount);
  return { success: successCount, fail: failCount };
}

// 使用示例
batchInstallApps("/sdcard/download/apks");

案例2:清理后台应用

javascript 复制代码
/**
 * 清理所有后台第三方应用
 */
function clearBackgroundApps() {
  startEnv();

  // 获取所有第三方应用
  var result = shell.execAgentCommand("pm list packages -3");
  var packages = result.split("\n");

  var clearedCount = 0;

  for (var i = 0; i < packages.length; i++) {
    var packageName = packages[i].replace("package:", "").trim();
    if (packageName === "") continue;

    // 停止应用
    var result = shell.stopApp(packageName);
    if (result) {
      clearedCount++;
      logd("已停止: " + packageName);
    }
  }

  // 杀死所有后台进程
  shell.execAgentCommand("am kill-all");

  logd("清理完成,共停止 " + clearedCount + " 个应用");
  return clearedCount;
}

// 使用示例
clearBackgroundApps();

案例3:获取设备详细信息

javascript 复制代码
/**
 * 获取设备详细信息
 * @return object 设备信息对象
 */
function getDeviceDetails() {
  startEnv();

  var deviceInfo = {};

  // 基本信息
  deviceInfo.model = shell.execAgentCommand("getprop ro.product.model").trim();
  deviceInfo.brand = shell.execAgentCommand("getprop ro.product.brand").trim();
  deviceInfo.device = shell
    .execAgentCommand("getprop ro.product.device")
    .trim();

  // 系统信息
  deviceInfo.androidVersion = shell
    .execAgentCommand("getprop ro.build.version.release")
    .trim();
  deviceInfo.sdkVersion = shell
    .execAgentCommand("getprop ro.build.version.sdk")
    .trim();
  deviceInfo.buildId = shell.execAgentCommand("getprop ro.build.id").trim();

  // 屏幕信息
  var sizeStr = shell.execAgentCommand("wm size");
  deviceInfo.screenSize = sizeStr.replace("Physical size: ", "").trim();

  var densityStr = shell.execAgentCommand("wm density");
  deviceInfo.screenDensity = densityStr
    .replace("Physical density: ", "")
    .trim();

  // 电池信息
  var batteryInfo = shell.execAgentCommand("dumpsys battery");
  var levelMatch = batteryInfo.match(/level: (\d+)/);
  var statusMatch = batteryInfo.match(/status: (\d+)/);
  deviceInfo.batteryLevel = levelMatch ? levelMatch[1] : "unknown";
  deviceInfo.batteryStatus = statusMatch ? statusMatch[1] : "unknown";

  // 内存信息
  var memInfo = shell.execAgentCommand("cat /proc/meminfo");
  var totalMatch = memInfo.match(/MemTotal:\s+(\d+)/);
  var freeMatch = memInfo.match(/MemFree:\s+(\d+)/);
  deviceInfo.totalMemory = totalMatch
    ? (totalMatch[1] / 1024 / 1024).toFixed(2) + " GB"
    : "unknown";
  deviceInfo.freeMemory = freeMatch
    ? (freeMatch[1] / 1024 / 1024).toFixed(2) + " GB"
    : "unknown";

  // 存储信息
  var storageInfo = shell.execAgentCommand("df -h /sdcard");
  var storageLines = storageInfo.split("\n");
  if (storageLines.length > 1) {
    var storageParts = storageLines[1].split(/\s+/);
    deviceInfo.storageTotal = storageParts[1] || "unknown";
    deviceInfo.storageUsed = storageParts[2] || "unknown";
    deviceInfo.storageAvailable = storageParts[3] || "unknown";
  }

  // 打印信息
  logd("========== 设备信息 ==========");
  for (var key in deviceInfo) {
    logd(key + ": " + deviceInfo[key]);
  }
  logd("==============================");

  return deviceInfo;
}

// 使用示例
getDeviceDetails();

案例4:自动点击脚本

javascript 复制代码
/**
 * 自动点击指定坐标
 * @param x X 坐标
 * @param y Y 坐标
 * @param times 点击次数
 * @param interval 间隔时间(毫秒)
 */
function autoClick(x, y, times, interval) {
  startEnv();

  for (var i = 0; i < times; i++) {
    logd("第 " + (i + 1) + " 次点击: (" + x + ", " + y + ")");

    // 使用 input 命令点击
    shell.execAgentCommand("input tap " + x + " " + y);

    if (i < times - 1) {
      sleep(interval);
    }
  }

  logd("自动点击完成");
}

/**
 * 自动滑动
 * @param startX 起点 X
 * @param startY 起点 Y
 * @param endX 终点 X
 * @param endY 终点 Y
 * @param duration 滑动持续时间(毫秒)
 */
function autoSwipe(startX, startY, endX, endY, duration) {
  startEnv();

  logd(
    "滑动: (" + startX + ", " + startY + ") -> (" + endX + ", " + endY + ")",
  );
  shell.execAgentCommand(
    "input swipe " +
      startX +
      " " +
      startY +
      " " +
      endX +
      " " +
      endY +
      " " +
      duration,
  );
}

// 使用示例
autoClick(500, 800, 5, 1000); // 在 (500, 800) 点击 5 次,间隔 1 秒
autoSwipe(500, 1500, 500, 500, 300); // 向上滑动

案例5:应用状态监控

javascript 复制代码
/**
 * 监控应用运行状态
 * @param packageName 应用包名
 * @param duration 监控时长(毫秒)
 * @param interval 检查间隔(毫秒)
 */
function monitorAppStatus(packageName, duration, interval) {
  startEnv();

  var startTime = new Date().getTime();
  var checkCount = 0;
  var runningCount = 0;

  logd("开始监控应用: " + packageName);
  logd("监控时长: " + duration / 1000 + " 秒");

  while (new Date().getTime() - startTime < duration) {
    checkCount++;

    // 检查进程是否存在
    var psResult = shell.execAgentCommand("ps | grep " + packageName);
    var isRunning = psResult.indexOf(packageName) !== -1;

    if (isRunning) {
      runningCount++;

      // 获取内存信息
      var memResult = shell.execAgentCommand("dumpsys meminfo " + packageName);
      var totalMatch = memResult.match(/TOTAL:\s+(\d+)/);
      var memUsage = totalMatch
        ? (totalMatch[1] / 1024).toFixed(2) + " MB"
        : "unknown";

      logd("[" + checkCount + "] 应用运行中 - 内存使用: " + memUsage);
    } else {
      logd("[" + checkCount + "] 应用未运行");
    }

    sleep(interval);
  }

  logd("监控结束 - 总检查次数: " + checkCount + ", 运行次数: " + runningCount);

  return {
    totalChecks: checkCount,
    runningCount: runningCount,
    runningRate: ((runningCount / checkCount) * 100).toFixed(2) + "%",
  };
}

// 使用示例
monitorAppStatus("com.example.app", 60000, 5000); // 监控 60 秒,每 5 秒检查一次

六、常见问题

Q1: 命令执行返回空或失败?

可能原因和解决方案:

  1. 代理服务未启动

    javascript 复制代码
    // 确保先调用 startEnv()
    startEnv();
    
    // 检查代理状态
    if (!agentEvent.isRunning()) {
      loge("代理服务未启动");
      return;
    }
  2. 命令格式错误

    • 检查命令拼写
    • 确保参数正确
    • 路径中不要包含特殊字符
  3. 权限不足

    • 某些命令需要 Root 权限
    • 使用 shell.sudo() 替代 shell.execAgentCommand()

Q2: 如何执行需要 Root 权限的命令?

javascript 复制代码
function main() {
  // 方法1:使用 sudo
  if (shell.su()) {
    var result = shell.sudo("cat /data/system/users/0/settings_system.xml");
    logd(result);
  }

  // 方法2:使用 execCommand(自动判断)
  var result = shell.execCommand(
    "cat /data/system/users/0/settings_system.xml",
  );
  logd(result);
}

Q3: 中文输入乱码怎么办?

javascript 复制代码
// 中文需要 URL 编码
var chineseText = encodeURIComponent("你好世界");
shell.execCommand("input text '" + chineseText + "'");

// 或者使用 base64 编码
var base64Text = "5L2g5aW9"; // "你好" 的 base64
shell.execCommand("input text $(echo " + base64Text + " | base64 -d)");

Q4: 如何获取命令执行的完整输出?

javascript 复制代码
// 使用 execAgentCommandEx 获取完整输出(包括错误信息)
function getFullOutput() {
  startEnv();

  var result = agentEvent.execShellCommandEx("ls -la /sdcard/");

  if (result && result.length > 0) {
    logd("命令输出:");
    for (var i = 0; i < result.length; i++) {
      logd(result[i]);
    }
  }

  return result;
}

Q5: Shizuku 模式如何使用?

javascript 复制代码
function useShizuku() {
  // 检查 Shizuku 是否可用
  if (!shell.isShizukuOk()) {
    loge("Shizuku 服务未运行,请先启动 Shizuku 并授权");
    return;
  }

  // 使用 Shizuku 执行命令
  var result = shell.execShizukuCommand("pm list packages");
  logd(result);
}

结语

通过本文,你应该已经掌握了 EasyClick 中 Shell 命令的使用方法,以及常用的 ADB Shell 命令。这些命令可以帮助你实现更强大的自动化功能,如应用管理、系统设置修改、文件操作等。

建议:

  • 优先使用代理模式,无需 Root 即可完成大部分操作
  • 使用 execAgentCommandEx 获取完整的命令执行结果
  • 执行命令前检查环境是否准备就绪
  • 注意命令执行的时间,避免阻塞主线程

相关资源:


相关推荐
qq_426003962 天前
启动playwright录制codegen生成自动化测试脚本
python·自动化
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台2 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone2 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc2 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo2 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077002 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼2 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
森叶2 天前
用远程调试端口自动化 Chrome 应用商店发布:做法、三个真坑,以及你必须知道的风险
自动化