关于 android-device-automation
供 AI Agent 通过截图和自然语言命令自动操作 Android 设备的 Midscene 技能,使用 Android 命令行按顺序观察、执行并验证操作。
主要功能
- 01自然语言执行界面操作
- 02截取并分析屏幕
- 03断言屏幕状态
- 04录制短暂界面状态
- 05运行 ADB 命令并生成报告
适用场景
- 01完成 Android 应用中的多步任务
- 02在 QA 中检查可见界面状态
- 03捕获临时通知或过渡画面
- 04通过 ADB 命令检查设备数据
MCP 相关
Android 命令行中的每条命令都对应 MCP 工具,AI Agent 根据截图调用这些工具控制设备。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ web-infra-dev/ midscene-skills --skill android-device-automation安装后在 Claude Code 中输入/android-device-automation确认已加载。
详细介绍
Android 设备自动化
关键规则——违反规则会破坏工作流:
- 绝不要在后台运行 midscene 命令。 每条命令都必须同步运行,以便你在决定下一步操作前读取其输出(尤其是截图)。后台执行会破坏截图—分析—操作循环。
- 一次只运行一条 midscene 命令。 等待上一条命令完成,读取截图,然后再决定下一步操作。绝不要将多条命令串联执行。
- 为每条命令预留足够的完成时间。 Midscene 命令涉及 AI 推理和屏幕交互,耗时可能比常规 shell 命令更长。一般命令需要约 1 分钟;复杂的
act命令可能需要更久。- 结束前务必汇报任务结果。 完成自动化任务后,你必须主动向用户总结结果,包括发现的关键信息、已完成的操作、截取的截图以及任何相关发现。绝不要在最后一步自动化操作后不作回应就结束;用户希望在一次交互中收到完整答复。
使用 npx -y @midscene/android@1 自动化 Android 设备。每条 CLI 命令都直接对应一个 MCP 工具——你(AI Agent)充当决策核心,根据截图决定要执行哪些操作。
act 可以做什么
在 Android 上的一次 act 调用中,Midscene 可以点击、双击、长按、输入、清除文本、向任意方向滚动或滑动、下拉刷新、拖动项目、用两根手指缩放、按键,以及使用返回、主页或最近使用的应用等系统导航,同时基于当前可见屏幕进行操作。
前提条件
Midscene 需要具备强大视觉定位能力的模型。必须配置以下环境变量——可以将其设为系统环境变量,或放在当前工作目录下的 .env 文件中(Midscene 会自动加载 .env):
MIDSCENE_MODEL_API_KEY="your-api-key"
MIDSCENE_MODEL_NAME="model-name"
MIDSCENE_MODEL_BASE_URL="https://..."
MIDSCENE_MODEL_FAMILY="family-identifier"
示例:Gemini(Gemini-3-Flash)
MIDSCENE_MODEL_API_KEY="your-google-api-key"
MIDSCENE_MODEL_NAME="gemini-3-flash"
MIDSCENE_MODEL_BASE_URL="https://generativelanguage.googleapis.com/v1beta/openai/"
MIDSCENE_MODEL_FAMILY="gemini"
示例:Qwen 3.5
MIDSCENE_MODEL_API_KEY="your-aliyun-api-key"
MIDSCENE_MODEL_NAME="qwen3.5-plus"
MIDSCENE_MODEL_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
MIDSCENE_MODEL_FAMILY="qwen3.5"
MIDSCENE_MODEL_REASONING_ENABLED="false"
# If using OpenRouter, set:
# MIDSCENE_MODEL_API_KEY="your-openrouter-api-key"
# MIDSCENE_MODEL_NAME="qwen/qwen3.5-plus"
# MIDSCENE_MODEL_BASE_URL="https://openrouter.ai/api/v1"
示例:Doubao Seed 2.0 Lite
MIDSCENE_MODEL_API_KEY="your-doubao-api-key"
MIDSCENE_MODEL_NAME="doubao-seed-2-0-lite"
MIDSCENE_MODEL_BASE_URL="https://ark.cn-beijing.volces.com/api/v3"
MIDSCENE_MODEL_FAMILY="doubao-seed"
常用模型:Doubao Seed 2.0 Lite、Qwen 3.5、Zhipu GLM-4.6V、Gemini-3-Pro、Gemini-3-Flash。
如果尚未配置模型,请让用户进行设置。支持的提供商请参见模型配置。
命令
常用 Android CLI 标志
在创建或使用 Android Agent 的命令中使用这些标志,例如 connect、take_screenshot、act、assert 和 tap:
--device-id <id>:指定要操作的 Android 设备,该设备须来自adb devices。--use-scrcpy:启用 scrcpy 加速截图。当常规截图较慢或不稳定时使用此标志。由于 CLI 调用无状态,每次需要基于 scrcpy 截图的 Android Midscene 命令都必须传入此标志。
连接到设备
npx -y @midscene/android@1 connect
npx -y @midscene/android@1 connect --device-id emulator-5554
npx -y @midscene/android@1 connect --device-id emulator-5554 --use-scrcpy
启动应用或 URL
如果需要在执行其余任务前确定起始状态,请使用专用的启动步骤:
npx -y @midscene/android@1 launch --uri https://www.ebay.com
npx -y @midscene/android@1 launch --uri com.android.settings
npx -y @midscene/android@1 launch --uri com.android.settings/.Settings
运行原始 Android Shell 命令
当任务需要更底层的设备控制,且不适合通过可见的 UI 交互实现时,请使用此命令:
npx -y @midscene/android@1 runadbshell --command "dumpsys battery"
此命令会转发到已连接设备上的 adb shell。实际上,底层命令是 adb -s <deviceId> shell dumpsys battery;某些环境还可能包含默认 ADB 服务端口,例如 adb -P 5037 -s <deviceId> shell dumpsys battery。
截取屏幕截图
npx -y @midscene/android@1 take_screenshot
npx -y @midscene/android@1 take_screenshot --device-id emulator-5554 --use-scrcpy
截取屏幕截图后,请读取保存的图像文件,了解当前屏幕状态,再决定下一步操作。
执行操作
使用 act 与设备交互并获取结果。它会在内部自主处理所有 UI 交互——点击、输入、滚动、滑动、等待和导航。因此,应将复杂的高级任务整体交给它,而不是拆分成小步骤。请用自然语言描述你想做什么以及期望达到的效果:
# specific instructions
npx -y @midscene/android@1 act --prompt "type hello world in the search field and press Enter"
npx -y @midscene/android@1 act --prompt "long press the message bubble and tap Delete in the popup menu"
npx -y @midscene/android@1 act --device-id emulator-5554 --use-scrcpy --prompt "type hello world in the search field and press Enter"
# or target-driven instructions
npx -y @midscene/android@1 act --prompt "open Settings and navigate to Wi-Fi settings, tell me the connected network name"
断言当前屏幕状态
使用 assert 验证当前屏幕是否满足自然语言条件。它不会执行 UI 操作;它会检查可见的屏幕状态,并且只有断言为真时才会通过。可将其用于验证、QA 检查,以及在 act 后验证最终状态。
npx -y @midscene/android@1 assert --prompt "there is a login button visible"
npx -y @midscene/android@1 assert --prompt "the settings screen shows Wi-Fi and Bluetooth options"
npx -y @midscene/android@1 assert --device-id emulator-5554 --prompt "the app shows a successful login message"
npx -y @midscene/android@1 assert --device-id emulator-5554 --use-scrcpy --prompt "the app shows a successful login message"
默认情况下,断言失败会抛出 AI 生成的原因。传入 --message 可改为抛出自定义错误消息,这对于在 QA 和 CI 日志中显示预期结果很有用。
npx -y @midscene/android@1 assert \
--prompt "the order confirmation screen is visible" \
--message "the order should be confirmed after tapping Pay"
当断言需要与参考图像(图标、徽标、屏幕截图)进行比对时,传入 --image 指定 URL/路径,并传入 --image-name 指定其显示名称。每个 --image 都可以是 http(s) 链接、data: URI 或本地文件路径。需要附加多张图像时,按对应顺序重复这两个标志。当模型无法直接访问 URL 时,添加 --convertHttpImage2Base64 true。需要 @midscene/[email protected]+。
npx -y @midscene/android@1 assert \
--prompt "the visible app icon matches the supplied reference image" \
--image "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png" \
--image-name "icon" \
--convertHttpImage2Base64 true
# or with a local file
npx -y @midscene/android@1 assert \
--prompt "the header on screen matches the local screenshot" \
--image "./fixtures/header.png" \
--image-name "header"
# multiple reference images — pair --image and --image-name by order
npx -y @midscene/android@1 assert \
--prompt "the screen shows both the app icon and the header" \
--image "./fixtures/icon.png" --image-name "icon" \
--image "./fixtures/header.png" --image-name "header"
录制并断言瞬态 UI
如果要验证的状态可能在当前屏幕断言运行前消失(例如 Toast、加载横幅、动画或过渡),请使用录制:
# Terminal 1: keep this foreground command running
npx -y @midscene/android@1 record start \
--device-id emulator-5554 --use-scrcpy \
--output ./submission-observation.json
# Terminal 2, while Terminal 1 records
npx -y @midscene/android@1 act --device-id emulator-5554 \
--prompt "tap the Submit button"
# Send Ctrl+C to Terminal 1 and wait for the saved-path message, then assert
npx -y @midscene/android@1 assert --device-id emulator-5554 \
--record ./submission-observation.json \
--prompt "a success toast appeared during submission"
对 record start 传入目标标志、捕获标志和 --output,然后等待 Recording. Press Ctrl+C to stop and save.。让录制器在专用终端中作为前台进程运行;切勿添加 shell &。手动或从第二个终端执行交互,向录制器发送 Ctrl+C,并等待它打印保存路径后再进行断言。--use-scrcpy 可提供更快的连续帧来源;不使用时,录制会回退为定期截取屏幕。可选的捕获标志包括 --interval-ms、--max-frames 和 --watchdog-ms;--max-frames 限制采样帧数,清单中可能还会多出一帧最终代表性画面。默认看门狗会在五分钟后完成并保存录制,而 --watchdog-ms 0 会禁用此安全限制。输出是一份 JSON 清单和一个相邻的 <name>.frames 图像目录,而不是编码后的视频或归档文件。清单包含相对 JPEG/PNG 路径,不包含 base64 图像数据。JSON 文件和图像目录应一并保留或移动,并将 JSON 路径传给 assert --record。如果只关心当前屏幕,请使用普通的 assert,不带 --record。
使用参考图像进行精确定位
当用户提供屏幕截图、图标、徽标或参考图像,并要求精确匹配视觉效果时,优先使用 tap --locate,而非通用的 act --prompt。以 JSON 格式传入 --locate。prompt 描述目标,images 提供带名称的参考图像;如果模型可能无法直接访问图像 URL,使用 convertHttpImage2Base64: true 会很有帮助。
npx -y @midscene/android@1 tap --locate '{
"prompt": "tap the area contains the image",
"images": [
{
"name": "target image",
"url": "https://github.githubassets.com/assets/GitHub-Mark-ea2971cee799.png"
}
],
"convertHttpImage2Base64": true
}'
同样的 locate JSON 格式也适用于其他接受 locate 参数的命令。
断开连接
npx -y @midscene/android@1 disconnect
使用报告文件
建议先使用生成的 HTML 报告供人工阅读。报告包含逐步执行详情以及每项操作的回放视频,因此更容易了解发生了什么并排查问题。
如果其他技能或工具需要使用该报告,请先通过同一平台 CLI 软件包中的 report-tool 进行转换。基于 LLM 的工作流优先使用 Markdown。需要以编程方式处理报告时,请使用 JSON。
npx -y @midscene/android@1 report-tool --action to-markdown --htmlPath ./midscene_run/report/.../index.html --outputDir ./output-markdown
npx -y @midscene/android@1 report-tool --action split --htmlPath ./midscene_run/report/.../index.html --outputDir ./output-data
工作流模式
由于 CLI 命令在不同调用之间是无状态的,请遵循以下模式:
- 连接以建立会话
- 启动目标应用并截取屏幕截图以查看当前状态,确保应用已启动并显示在屏幕上。
- 执行操作,使用
act执行所需操作或基于目标的指令。使用assert验证屏幕状态;或者,在专用终端中运行record start --output ...,使其在瞬时状态工作流期间持续录制,使用 Ctrl+C 停止录制,然后使用assert --record。 - 断开连接,完成后执行
- 报告结果——总结完成的工作,呈现任务期间提取的关键发现和数据,并列出生成的文件(截图、日志等)及其路径
最佳实践
- 使用此技能前,先将目标应用置于前台:为提高效率,请在调用任何 midscene 命令之前使用 ADB 启动应用(例如,
adb shell am start -n <package/activity>)。然后截取屏幕截图,确认应用确实处于前台。只有在通过视觉确认后,才能使用此技能进行 UI 自动化。使用 ADB 命令导航并打开应用,比使用 midscene 快得多。 - 明确描述 UI 元素:不要使用含糊的描述,应提供清晰、具体的细节。例如,说
"右侧的 Wi-Fi 切换开关",而不是"开关"。 - 尽可能描述位置:通过描述元素的位置来帮助定位(例如,
"右上角的搜索图标"、"列表中的第三项")。 - 绝不要在后台运行:每条 midscene 命令都必须同步运行——后台执行会破坏“截图—分析—操作”循环。
- 将相关操作合并到单条
act命令中:在同一个应用中连续执行操作时,请将它们合并到一条act提示词中,而不是拆分成多条命令。例如,"打开设置,点按 Wi-Fi,然后将其开启"应作为一次act调用,而不是三次。这可以减少往返次数,避免不必要的“截图—分析”循环,并显著提升速度。 - 需要加快截图捕获时使用 scrcpy:如果常规 Android 截图速度慢、不稳定或受环境限制,请在每条相关命令中添加
--use-scrcpy。 - 选择合适的验证时机:对当前屏幕使用
assert --prompt "..."。对于 toast、横幅、动画或过渡效果,请在专用终端中运行record start --output ...,执行交互,使用 Ctrl+C 停止录制,等待显示保存路径的消息,然后将生成文件传给assert --record。 - 完成后务必报告结果:完成自动化任务后,必须主动向用户呈现结果,不要等用户询问。这包括:(1) 对用户原始问题的回答或所请求任务的结果;(2) 执行期间提取或观察到的关键数据;(3) 截图和其他生成文件及其路径;(4) 对所采取步骤的简要总结。不要在最后一条自动化命令后就悄然结束——用户希望在一次交互中获得完整结果。
- 提供参考图像时,优先使用
tap --locate:如果用户分享了截图、图标或徽标,并希望定位其中完全相同的视觉目标,请使用带有多模态locateJSON 对象(例如{ "prompt": "...", "images": [...] })的tap --locate,而不要只依赖act --prompt。
示例 — 弹出菜单交互:
npx -y @midscene/android@1 act --prompt "long press the message bubble and tap Delete in the popup menu"
npx -y @midscene/android@1 take_screenshot
示例 — 表单交互:
npx -y @midscene/android@1 act --prompt "fill in the username field with 'testuser' and the password field with 'pass123', then tap the Login button"
npx -y @midscene/android@1 take_screenshot
提高精度(Deep Locate / Deep Think)
当 Midscene 难以完成某项任务时,可以使用两个可选的全局标志。将它们放在命令中的任意位置(子命令之前或之后)即可;设置后,相关操作会默认使用这些标志,因此无需传递单次调用参数。
--deep-locate— 额外进行一轮视觉推理,以精确定位目标元素。当操作点到了错误位置(位置偏移)时使用。它适用于所有定位元素的操作,包括tap --locate,以及act中执行的定位。--deep-think— 通过更深入的推理(更丰富的上下文和子目标分解)来规划act。适用于复杂的多步骤act指令;它只影响规划。
这两个标志都会稍微降低速度以换取更好的结果,也可以同时使用。
# more accurate element location (helps act's internal locating too)
npx -y @midscene/android@1 act --deep-locate --prompt "tap the small overflow (⋮) icon in the top-right corner"
# deeper planning for a complex, multi-step act
npx -y @midscene/android@1 act --deep-think --prompt "open Settings, go to Wi-Fi, and connect to the network named Office"
# combine both
npx -y @midscene/android@1 act --deep-locate --deep-think --prompt "fill in the signup form and tap Submit"
故障排除
| 问题 | 解决方案 |
|---|---|
| 找不到 ADB | 安装 Android SDK Platform Tools:在 macOS 上运行 brew install android-platform-tools,或从 developer.android.com 下载。 |
| 设备未列出 | 检查 USB 连接,确保已在开发者选项中启用 USB 调试,然后运行 adb devices。 |
| 设备显示“unauthorized” | 解锁设备并接受 USB 调试授权提示,然后再次运行 adb devices。 |
| 设备显示“offline” | 断开并重新连接 USB 线缆,然后运行 adb kill-server && adb start-server。 |
| 命令超时 | 设备屏幕可能已关闭或锁定。运行 adb shell input keyevent KEYCODE_WAKEUP 唤醒设备并解锁。 |
| API 密钥错误 | 检查 .env 文件是否包含 MIDSCENE_MODEL_API_KEY=<your-key>。请参阅模型配置。 |
@midscene/* 依赖版本过旧 | 使用 npm ls @midscene/android @midscene/core @midscene/shared(或 pnpm why @midscene/android)检查本地版本。使用 npm view @midscene/android version、npm view @midscene/core version 和 npm view @midscene/shared version 与最新版本进行比较。根据需要升级(npm i @midscene/android@latest @midscene/core@latest @midscene/shared@latest)。 |
| 目标设备错误 | 如果连接了多台设备,请使用 --device-id <id> 标志。 |
| 截图速度慢或不稳定 | 在 Android Midscene 命令中添加 --use-scrcpy,以启用 scrcpy 加速截图。 |