命令参考
Droidline 全部命令的参数、返回值、错误,以及在 Python、Node.js、CLI 和 HTTP 中的同一调用。
本页为译文。如与英文版不一致,以英文版为准。 English
每条命令都列出它的作用、参数、返回值和可能的错误,然后给出各个接口中的同一调用。在任意示例中选择一种语言,整页都会跟着切换。Python 示例假定已经执行了 d = connect()(服务器命令为 dl = Droidline()),Node.js 示例假定已经执行了 const d = await connect()(const dl = new Droidline())。
界面
dump
返回当前界面的节点树
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
path | string | 保存为本地 JSON 文件 | |
all_windows | bool | false | 包含状态栏、键盘等系统窗口 |
返回: 包含以下字段的对象: package, activity, width, height, tree
d.dump("screen.json") # saved on your PCawait d.dump("screen.json"); // saved on your PCdroidline dump screen.jsoncurl -s -X POST localhost:8780/devices/_/dump \
-H 'content-type: application/json' > screen.json{"id":1,"cmd":"dump"}screenshot
截取屏幕
Android 11 及以上使用无障碍截图,9-10 首次需要允许屏幕录制
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
path | string | 保存到本地文件,扩展名决定 png 或 jpeg | |
format | string png | jpeg | "jpeg" | 图片格式 |
quality | int | 80 | JPEG 质量 1-100 |
scale | number | 1 | 缩放比例 0.1-1.0,移动网络下有用 |
返回: 包含以下字段的对象: format, width, height, data
d.screenshot("shot.png") # saved on your PCawait d.screenshot("shot.png"); // saved on your PCdroidline screenshot shot.pngcurl -s localhost:8780/devices/_/screenshot.png -o shot.png{"id":1,"cmd":"screenshot"}current
前台包名和 Activity
返回: 包含以下字段的对象: package, activity
d.current()await d.current();droidline currentcurl -s -X POST localhost:8780/devices/_/current \
-H 'content-type: application/json'{"id":1,"cmd":"current"}坐标
tap
点击坐标
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
x | int | 必填 | 屏幕像素 X |
y | int | 必填 | 屏幕像素 Y |
返回: 包含以下字段的对象: ms
d.tap(540, 1200)await d.tap(540, 1200);droidline tap 540 1200curl -s -X POST localhost:8780/devices/_/tap \
-H 'content-type: application/json' \
-d '{"x":540,"y":1200}'{"id":1,"cmd":"tap","x":540,"y":1200}long_tap
长按坐标
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
x | int | 必填 | 屏幕像素 X |
y | int | 必填 | 屏幕像素 Y |
ms | int | 800 | 按住时长(毫秒) |
返回: 包含以下字段的对象: ms
d.long_tap(540, 1200, 800)await d.longTap(540, 1200, 800);droidline long_tap 540 1200 800curl -s -X POST localhost:8780/devices/_/long_tap \
-H 'content-type: application/json' \
-d '{"x":540,"y":1200,"ms":800}'{"id":1,"cmd":"long_tap","x":540,"y":1200,"ms":800}swipe
在两点之间或按方向滑动
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
x1 | int|string | 必填 | 起点 X,或方向:up、down、left、right |
y1 | int | 起点 Y | |
x2 | int | 终点 X | |
y2 | int | 终点 Y | |
ms | int | 300 | 时长(毫秒) |
返回: 包含以下字段的对象: ms
d.swipe(540, 1600, 540, 400, 300)await d.swipe(540, 1600, 540, 400, 300);droidline swipe 540 1600 540 400 300curl -s -X POST localhost:8780/devices/_/swipe \
-H 'content-type: application/json' \
-d '{"x1":540,"y1":1600,"x2":540,"y2":400,"ms":300}'{"id":1,"cmd":"swipe","x1":540,"y1":1600,"x2":540,"y2":400,"ms":300}元素
touch
等待元素出现并点击
节点拒绝点击时改为点击 bounds 中心。via 表示成功方式:node、parent 或 gesture
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
timeout | number | 10 s | 等待目标出现的秒数 |
返回: 包含以下字段的对象: via, ms
简写: touchById(value), touchByText(value), touchByDesc(value)
错误: NOT_FOUND, NOT_CLICKABLE, NO_ACCESSIBILITY
d.touch("text", "登录")await d.touch("text", "登录");droidline touch text "登录"curl -s -X POST localhost:8780/devices/_/touch \
-H 'content-type: application/json' \
-d '{"by":"text","value":"登录"}'{"id":1,"cmd":"touch","by":"text","value":"登录"}long_touch
等待元素出现并长按
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
ms | int | 800 | 按住时长(毫秒) |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
timeout | number | 10 s | 等待目标出现的秒数 |
返回: 包含以下字段的对象: via, ms
d.long_touch("text", "消息")await d.longTouch("text", "消息");droidline long_touch text "消息"curl -s -X POST localhost:8780/devices/_/long_touch \
-H 'content-type: application/json' \
-d '{"by":"text","value":"消息"}'{"id":1,"cmd":"long_touch","by":"text","value":"消息"}scroll_to
滚动直到元素可见
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
direction | string down | up | left | right | "down" | 滚动方向 |
max_swipes | int | 20 | 滑动这么多次后放弃 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
返回: 包含以下字段的对象: swipes
d.scroll_to("text", "设置")await d.scrollTo("text", "设置");droidline scroll_to text "设置"curl -s -X POST localhost:8780/devices/_/scroll_to \
-H 'content-type: application/json' \
-d '{"by":"text","value":"设置"}'{"id":1,"cmd":"scroll_to","by":"text","value":"设置"}输入
input
等待输入框并填入文字
使用无障碍设置文本操作;忽略该操作的输入框在选择了 Droidline 键盘时改用键盘输入
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
text | string | 必填 | 要输入的文字 |
append | bool | false | 保留原有文字并追加 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
timeout | number | 10 s | 等待目标出现的秒数 |
返回: 包含以下字段的对象: via, ms
d.input("id", "email", "me@example.com")await d.input("id", "email", "me@example.com");droidline input id email me@example.comcurl -s -X POST localhost:8780/devices/_/input \
-H 'content-type: application/json' \
-d '{"by":"id","value":"email","text":"me@example.com"}'{"id":1,"cmd":"input","by":"id","value":"email","text":"me@example.com"}clear
清空输入框
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
timeout | number | 10 s | 等待目标出现的秒数 |
返回: 包含以下字段的对象: ms
d.clear("id", "email")await d.clear("id", "email");droidline clear id emailcurl -s -X POST localhost:8780/devices/_/clear \
-H 'content-type: application/json' \
-d '{"by":"id","value":"email"}'{"id":1,"cmd":"clear","by":"id","value":"email"}sendkey
发送按键名、键码或文字
back、home、recents、notifications、quick_settings、lock 使用无障碍全局操作;其他按键和文字通过 Droidline 键盘发送到焦点输入框
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
key | string|int | 按键名(enter、tab、del、space、escape、up、down、left、right、back、home 等)、Android 键码或要输入的文字 | |
text | string | 按字面输入,即使与按键名相同 |
返回: 包含以下字段的对象: via
d.sendkey("enter")await d.sendkey("enter");droidline sendkey entercurl -s -X POST localhost:8780/devices/_/sendkey \
-H 'content-type: application/json' \
-d '{"key":"enter"}'{"id":1,"cmd":"sendkey","key":"enter"}检查
exists
元素当前是否在屏幕上,不等待
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
返回: 以下类型的值: bool
d.exists("text", "关闭广告")await d.exists("text", "关闭广告");droidline exists text "关闭广告"curl -s -X POST localhost:8780/devices/_/exists \
-H 'content-type: application/json' \
-d '{"by":"text","value":"关闭广告"}'{"id":1,"cmd":"exists","by":"text","value":"关闭广告"}wait
等待元素出现
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
timeout | number | 10 s | 等待目标出现的秒数 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
返回: 包含以下字段的对象: ms
错误: NOT_FOUND
d.wait("text", "完成", timeout=30)await d.wait("text", "完成", { timeout: 30 });droidline wait text "完成" --timeout 30curl -s -X POST localhost:8780/devices/_/wait \
-H 'content-type: application/json' \
-d '{"by":"text","value":"完成","timeout":30}'{"id":1,"cmd":"wait","by":"text","value":"完成","timeout":30}wait_gone
等待元素消失
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
timeout | number | 10 s | 等待目标出现的秒数 |
返回: 包含以下字段的对象: ms
错误: TIMEOUT
d.wait_gone("text", "加载中")await d.waitGone("text", "加载中");droidline wait_gone text "加载中"curl -s -X POST localhost:8780/devices/_/wait_gone \
-H 'content-type: application/json' \
-d '{"by":"text","value":"加载中"}'{"id":1,"cmd":"wait_gone","by":"text","value":"加载中"}get_text
元素的文字,不存在时为空字符串
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
返回: 以下类型的值: string
d.get_text("id", "balance")await d.getText("id", "balance");droidline get_text id balancecurl -s -X POST localhost:8780/devices/_/get_text \
-H 'content-type: application/json' \
-d '{"by":"id","value":"balance"}'{"id":1,"cmd":"get_text","by":"id","value":"balance"}条件
checkedenabledselectedcountwhichin_appkeyboard_shownlast_toastcolor
checked
开关或复选框为开启时返回 true
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
返回: 以下类型的值: bool
d.checked("id", "auto_login")await d.checked("id", "auto_login");droidline checked id auto_logincurl -s -X POST localhost:8780/devices/_/checked \
-H 'content-type: application/json' \
-d '{"by":"id","value":"auto_login"}'{"id":1,"cmd":"checked","by":"id","value":"auto_login"}enabled
元素可点击时返回 true
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
返回: 以下类型的值: bool
d.enabled("text", "下一步")await d.enabled("text", "下一步");droidline enabled text "下一步"curl -s -X POST localhost:8780/devices/_/enabled \
-H 'content-type: application/json' \
-d '{"by":"text","value":"下一步"}'{"id":1,"cmd":"enabled","by":"text","value":"下一步"}selected
标签或项目被选中时返回 true
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
nth | int | 0 | 多个元素匹配时的序号,从 0 开始 |
返回: 以下类型的值: bool
d.selected("text", "首页")await d.selected("text", "首页");droidline selected text "首页"curl -s -X POST localhost:8780/devices/_/selected \
-H 'content-type: application/json' \
-d '{"by":"text","value":"首页"}'{"id":1,"cmd":"selected","by":"text","value":"首页"}count
匹配元素的数量
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | selector | 必填 | 按哪个 dump 字段查找:text、textContains、id、desc、descContains、class |
value | string | 必填 | 要匹配的值 |
返回: 以下类型的值: int
d.count("class", "android.widget.CheckBox")await d.count("class", "android.widget.CheckBox");droidline count class android.widget.CheckBoxcurl -s -X POST localhost:8780/devices/_/count \
-H 'content-type: application/json' \
-d '{"by":"class","value":"android.widget.CheckBox"}'{"id":1,"cmd":"count","by":"class","value":"android.widget.CheckBox"}which
最先出现的候选项序号,没有则为 -1
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
candidates | list<selector_pair> | 必填 | [条件, 值] 对的列表 |
timeout | number | 10 s | 等待任一候选出现的秒数 |
返回: 以下类型的值: int
d.which([("text", "登录"), ("id", "main_tab")], timeout=15)await d.which([["text", "登录"], ["id", "main_tab"]], { timeout: 15 });droidline which text="登录" id=main_tab --timeout 15curl -s -X POST localhost:8780/devices/_/which \
-H 'content-type: application/json' \
-d '{"candidates":[["text","登录"],["id","main_tab"]],"timeout":15}'{"id":1,"cmd":"which","candidates":[["text","登录"],["id","main_tab"]],"timeout":15}in_app
该应用在前台时返回 true
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
package | string | 必填 | 包名,例如 com.android.chrome |
返回: 以下类型的值: bool
d.in_app("com.android.chrome")await d.inApp("com.android.chrome");droidline in_app com.android.chromecurl -s -X POST localhost:8780/devices/_/in_app \
-H 'content-type: application/json' \
-d '{"package":"com.android.chrome"}'{"id":1,"cmd":"in_app","package":"com.android.chrome"}keyboard_shown
软键盘显示时返回 true
返回: 以下类型的值: bool
d.keyboard_shown()await d.keyboardShown();droidline keyboard_showncurl -s -X POST localhost:8780/devices/_/keyboard_shown \
-H 'content-type: application/json'{"id":1,"cmd":"keyboard_shown"}last_toast
最近一条 Toast 的文字,没有则为空字符串
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
max_age | number | 30 s | 忽略早于此秒数的 Toast |
返回: 以下类型的值: string
d.last_toast()await d.lastToast();droidline last_toastcurl -s -X POST localhost:8780/devices/_/last_toast \
-H 'content-type: application/json'{"id":1,"cmd":"last_toast"}color
坐标处的像素颜色(#RRGGBB)
用于没有无障碍节点的界面(如游戏)
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
x | int | 必填 | 屏幕像素 X |
y | int | 必填 | 屏幕像素 Y |
返回: 以下类型的值: string
d.color(540, 1200)await d.color(540, 1200);droidline color 540 1200curl -s -X POST localhost:8780/devices/_/color \
-H 'content-type: application/json' \
-d '{"x":540,"y":1200}'{"id":1,"cmd":"color","x":540,"y":1200}设备
screen_onlockedwakelockbatteryorientationinfo
screen_on
屏幕亮着时返回 true
返回: 以下类型的值: bool
d.screen_on()await d.screenOn();droidline screen_oncurl -s -X POST localhost:8780/devices/_/screen_on \
-H 'content-type: application/json'{"id":1,"cmd":"screen_on"}locked
处于锁屏时返回 true
返回: 以下类型的值: bool
d.locked()await d.locked();droidline lockedcurl -s -X POST localhost:8780/devices/_/locked \
-H 'content-type: application/json'{"id":1,"cmd":"locked"}wake
点亮屏幕并解除无密码的锁屏
屏幕关闭时手势会失败。PIN、图案或密码锁需要用户解锁
返回: 包含以下字段的对象: screen_on, locked
d.wake()await d.wake();droidline wakecurl -s -X POST localhost:8780/devices/_/wake \
-H 'content-type: application/json'{"id":1,"cmd":"wake"}lock
关闭屏幕并锁定
返回: 无
d.lock()await d.lock();droidline lockcurl -s -X POST localhost:8780/devices/_/lock \
-H 'content-type: application/json'{"id":1,"cmd":"lock"}battery
电量和充电状态
返回: 包含以下字段的对象: level, charging, temperature
d.battery()await d.battery();droidline batterycurl -s -X POST localhost:8780/devices/_/battery \
-H 'content-type: application/json'{"id":1,"cmd":"battery"}orientation
屏幕方向:portrait 或 landscape
返回: 以下类型的值: string
d.orientation()await d.orientation();droidline orientationcurl -s -X POST localhost:8780/devices/_/orientation \
-H 'content-type: application/json'{"id":1,"cmd":"orientation"}info
型号、Android 版本、屏幕尺寸和权限状态
返回: 包含以下字段的对象: model, manufacturer, sdk, release, agent, width, height, ready
d.info()await d.info();droidline infocurl -s -X POST localhost:8780/devices/_/info \
-H 'content-type: application/json'{"id":1,"cmd":"info"}网络
network
连接类型(wifi、mobile、none)和飞行模式
返回: 包含以下字段的对象: type, airplane, metered
d.network()await d.network();droidline networkcurl -s -X POST localhost:8780/devices/_/network \
-H 'content-type: application/json'{"id":1,"cmd":"network"}proxy
通过按应用 VPN 让指定应用走上游代理
支持 http://(CONNECT)和 socks5://,可带 user:pass。传 null 或 "off" 关闭。同一时间仅一个上游。忽略代理设置的应用会断网而不是泄漏
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
url | string|null | 必填 | socks5://user:pass@host:port、http://host:port、@kr1 这样的已保存配置,或 off |
app | string|list<string> | 要走代理的包(可多个) |
返回: 包含以下字段的对象: active, apps
错误: NO_PERMISSION, PROXY_FAILED, UNSUPPORTED
d.proxy("@kr1", app="com.android.chrome")await d.proxy("@kr1", { app: "com.android.chrome" });droidline proxy @kr1 --app com.android.chromecurl -s -X POST localhost:8780/devices/_/proxy \
-H 'content-type: application/json' \
-d '{"url":"@kr1","app":"com.android.chrome"}'{"id":1,"cmd":"proxy","url":"@kr1","app":"com.android.chrome"}proxy_check
按应用代理状态和外部看到的 IP
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
app | string | 要检查的包 |
返回: 包含以下字段的对象: active, ip, upstream, error
d.proxy_check("com.android.chrome")await d.proxyCheck("com.android.chrome");droidline proxy_check com.android.chromecurl -s -X POST localhost:8780/devices/_/proxy_check \
-H 'content-type: application/json' \
-d '{"app":"com.android.chrome"}'{"id":1,"cmd":"proxy_check","app":"com.android.chrome"}应用
launchopen_urlkillclear_dataappsinstalled
launch
启动应用,可指定 Activity
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
package | string | 必填 | 包名,例如 com.android.chrome |
activity | string | Activity 名称,完整名称或以点开头 |
返回: 包含以下字段的对象: ms
错误: APP_NOT_FOUND, ACTIVITY_BLOCKED
d.launch("com.android.settings")await d.launch("com.android.settings");droidline launch com.android.settingscurl -s -X POST localhost:8780/devices/_/launch \
-H 'content-type: application/json' \
-d '{"package":"com.android.settings"}'{"id":1,"cmd":"launch","package":"com.android.settings"}open_url
打开 URL 或深层链接
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
url | string | 必填 | http(s) 地址或应用深层链接 |
package | string | 仅用此应用打开 |
返回: 无
d.open_url("https://droidline.dev")await d.openUrl("https://droidline.dev");droidline open_url https://droidline.devcurl -s -X POST localhost:8780/devices/_/open_url \
-H 'content-type: application/json' \
-d '{"url":"https://droidline.dev"}'{"id":1,"cmd":"open_url","url":"https://droidline.dev"}kill
强制停止应用
设置宏:应用信息 → 强行停止 → 确定,需要几秒
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
package | string | 必填 | 包名,例如 com.android.chrome |
返回: 包含以下字段的对象: via, ms
错误: APP_NOT_FOUND, MACRO_FAILED
d.kill("com.android.chrome")await d.kill("com.android.chrome");droidline kill com.android.chromecurl -s -X POST localhost:8780/devices/_/kill \
-H 'content-type: application/json' \
-d '{"package":"com.android.chrome"}'{"id":1,"cmd":"kill","package":"com.android.chrome"}clear_data
清除应用数据
设置宏:应用信息 → 存储 → 清除数据 → 确定
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
package | string | 必填 | 包名,例如 com.android.chrome |
返回: 包含以下字段的对象: via, ms
错误: APP_NOT_FOUND, MACRO_FAILED
d.clear_data("com.android.chrome")await d.clearData("com.android.chrome");droidline clear_data com.android.chromecurl -s -X POST localhost:8780/devices/_/clear_data \
-H 'content-type: application/json' \
-d '{"package":"com.android.chrome"}'{"id":1,"cmd":"clear_data","package":"com.android.chrome"}apps
已安装的包列表
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
system | bool | false | 包含系统包 |
返回: 以下类型的值: list<app>
d.apps()await d.apps();droidline appscurl -s -X POST localhost:8780/devices/_/apps \
-H 'content-type: application/json'{"id":1,"cmd":"apps"}installed
已安装时返回版本名,否则为空字符串
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
package | string | 必填 | 包名,例如 com.android.chrome |
返回: 以下类型的值: string
d.installed("com.android.chrome")await d.installed("com.android.chrome");droidline installed com.android.chromecurl -s -X POST localhost:8780/devices/_/installed \
-H 'content-type: application/json' \
-d '{"package":"com.android.chrome"}'{"id":1,"cmd":"installed","package":"com.android.chrome"}系统
backhomerecentsopen_notificationsquick_settingsdatawifiairplaneclipboardbatch
back
返回
返回: 无
d.back()await d.back();droidline backcurl -s -X POST localhost:8780/devices/_/back \
-H 'content-type: application/json'{"id":1,"cmd":"back"}home
主屏幕
返回: 无
d.home()await d.home();droidline homecurl -s -X POST localhost:8780/devices/_/home \
-H 'content-type: application/json'{"id":1,"cmd":"home"}recents
最近任务
返回: 无
d.recents()await d.recents();droidline recentscurl -s -X POST localhost:8780/devices/_/recents \
-H 'content-type: application/json'{"id":1,"cmd":"recents"}open_notifications
下拉通知栏
返回: 无
d.open_notifications()await d.openNotifications();droidline open_notificationscurl -s -X POST localhost:8780/devices/_/open_notifications \
-H 'content-type: application/json'{"id":1,"cmd":"open_notifications"}quick_settings
打开快捷设置
返回: 无
d.quick_settings()await d.quickSettings();droidline quick_settingscurl -s -X POST localhost:8780/devices/_/quick_settings \
-H 'content-type: application/json'{"id":1,"cmd":"quick_settings"}data
开关移动数据
会断开手机自身的连接。调用先返回 accepted;传入 wait 可直接得到最终结果。
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
on | bool | 必填 | true 为开启,false 为关闭 |
返回: 包含以下字段的对象: via, ms
错误: MACRO_FAILED
d.data(False, wait=True)await d.data(false, { wait: true });droidline data false --waitcurl -s -X POST localhost:8780/devices/_/data \
-H 'content-type: application/json' \
-d '{"wait":true,"on":false}'{"id":1,"cmd":"data","on":false,"wait":true}wifi
开关 Wi-Fi
会断开手机自身的连接。调用先返回 accepted;传入 wait 可直接得到最终结果。
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
on | bool | 必填 | true 为开启,false 为关闭 |
返回: 包含以下字段的对象: via, ms
错误: MACRO_FAILED
d.wifi(False, wait=True)await d.wifi(false, { wait: true });droidline wifi false --waitcurl -s -X POST localhost:8780/devices/_/wifi \
-H 'content-type: application/json' \
-d '{"wait":true,"on":false}'{"id":1,"cmd":"wifi","on":false,"wait":true}airplane
开关飞行模式
更换 IP 时,请把开和关放进同一个 batch,手机离线时也会执行
会断开手机自身的连接。调用先返回 accepted;传入 wait 可直接得到最终结果。
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
on | bool | 必填 | true 为开启,false 为关闭 |
返回: 包含以下字段的对象: via, ms
错误: MACRO_FAILED
d.airplane(True, wait=True)await d.airplane(true, { wait: true });droidline airplane true --waitcurl -s -X POST localhost:8780/devices/_/airplane \
-H 'content-type: application/json' \
-d '{"wait":true,"on":true}'{"id":1,"cmd":"airplane","on":true,"wait":true}clipboard
写入剪贴板;不带文字调用时读取
Android 10 及以上读取需要 Droidline 键盘为当前输入法
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
text | string | 要复制的文字,省略则读取 |
返回: 以下类型的值: string
错误: NO_IME
d.clipboard("你好")await d.clipboard("你好");droidline clipboard "你好"curl -s -X POST localhost:8780/devices/_/clipboard \
-H 'content-type: application/json' \
-d '{"text":"你好"}'{"id":1,"cmd":"clipboard","text":"你好"}batch
在手机上一次执行多条命令,离线时也会继续
步骤为 [命令, 参数...] 列表或 {cmd, ...} 对象。sleep(ms) 只能在 batch 中使用。若某步骤会断网,先返回 accepted,重连后再返回结果
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
steps | list<step> | 必填 | 按顺序执行的命令 |
stop_on_error | bool | true | 遇到失败步骤即停止 |
返回: 包含以下字段的对象: results
d.batch([("airplane", True), ("sleep", 3000), ("airplane", False)], wait=True)await d.batch([["airplane", true], ["sleep", 3000], ["airplane", false]], { wait: true });droidline batch '[["airplane",true],["sleep",3000],["airplane",false]]' --waitcurl -s -X POST localhost:8780/devices/_/batch \
-H 'content-type: application/json' \
-d '{"wait":true,"steps":[["airplane",true],["sleep",3000],["airplane",false]]}'{"id":1,"cmd":"batch","steps":[["airplane",true],["sleep",3000],["airplane",false]],"wait":true}Chrome
chrome.go
在 Chrome 中打开网址
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
url | string | 必填 | 网址,缺少 https:// 时自动补全 |
new_tab | bool | false | 在新标签页打开 |
返回: 包含以下字段的对象: ms
错误: APP_NOT_FOUND
d.chrome.go("droidline.dev")await d.chrome.go("droidline.dev");droidline chrome.go droidline.devcurl -s -X POST localhost:8780/devices/_/chrome.go \
-H 'content-type: application/json' \
-d '{"url":"droidline.dev"}'{"id":1,"cmd":"chrome.go","url":"droidline.dev"}通知
notificationshas_notificationwait_notificationnotification_replynotification_clicknotification_dismissnotify_filteron_notification
notifications
当前显示的通知列表
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
package | string | 仅此应用 |
返回: 以下类型的值: list<notification>
d.notifications()await d.notifications();droidline notificationscurl -s -X POST localhost:8780/devices/_/notifications \
-H 'content-type: application/json'{"id":1,"cmd":"notifications"}has_notification
当前通知中有匹配项时返回 true
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | string text | textContains | title | package | 必填 | text 和 textContains 同时匹配标题和正文 |
value | string | 必填 | 要匹配的值 |
返回: 以下类型的值: bool
d.has_notification("textContains", "发货")await d.hasNotification("textContains", "发货");droidline has_notification textContains "发货"curl -s -X POST localhost:8780/devices/_/has_notification \
-H 'content-type: application/json' \
-d '{"by":"textContains","value":"发货"}'{"id":1,"cmd":"has_notification","by":"textContains","value":"发货"}wait_notification
等待匹配的通知并返回其内容
由 PC 服务器处理,不会阻塞发往手机的其他命令。Android 15 及以上系统会对应用隐藏验证码,只能得知通知到达
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
by | string text | textContains | title | package | 必填 | text 和 textContains 同时匹配标题和正文 |
value | string | 必填 | 要匹配的值 |
timeout | number | 60 s | 等待秒数 |
package | string | 仅来自此应用 |
返回: 以下类型的值: notification
错误: TIMEOUT
dl.wait_notification("textContains", "验证码", 60)await dl.waitNotification("textContains", "验证码", 60);droidline wait_notification textContains "验证码" 60curl -s -X POST localhost:8780/server/wait_notification \
-H 'content-type: application/json' \
-d '{"by":"textContains","value":"验证码","timeout":60}'{"id":1,"cmd":"wait_notification","by":"textContains","value":"验证码","timeout":60}notification_reply
直接回复带回复按钮的通知
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
key | string | 必填 | 来自 notifications() 或通知事件的 key |
text | string | 必填 | 回复内容 |
返回: 无
n = d.notifications()[0]
d.notification_reply(n["key"], "我在路上")const [n] = await d.notifications();
await d.notificationReply(n.key, "我在路上");KEY=$(droidline --json notifications | jq -r '.value[0].key')
droidline notification_reply "$KEY" "我在路上"curl -s -X POST localhost:8780/devices/_/notification_reply \
-H 'content-type: application/json' \
-d '{"key":"KEY","text":"我在路上"}'{"id":1,"cmd":"notification_reply","key":"KEY","text":"我在路上"}notification_click
点击通知打开对应界面
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
key | string | 必填 | 来自 notifications() 或通知事件的 key |
返回: 无
n = d.notifications()[0]
d.notification_click(n["key"])const [n] = await d.notifications();
await d.notificationClick(n.key);KEY=$(droidline --json notifications | jq -r '.value[0].key')
droidline notification_click "$KEY"curl -s -X POST localhost:8780/devices/_/notification_click \
-H 'content-type: application/json' \
-d '{"key":"KEY"}'{"id":1,"cmd":"notification_click","key":"KEY"}notification_dismiss
清除通知
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
key | string | 必填 | 来自 notifications() 或通知事件的 key |
返回: 无
n = d.notifications()[0]
d.notification_dismiss(n["key"])const [n] = await d.notifications();
await d.notificationDismiss(n.key);KEY=$(droidline --json notifications | jq -r '.value[0].key')
droidline notification_dismiss "$KEY"curl -s -X POST localhost:8780/devices/_/notification_dismiss \
-H 'content-type: application/json' \
-d '{"key":"KEY"}'{"id":1,"cmd":"notification_dismiss","key":"KEY"}notify_filter
选择哪些应用的通知发送到 PC,默认不发送任何应用
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
packages | list<string> | 允许的包,省略则读取当前列表 |
返回: 以下类型的值: list<string>
d.notify_filter(["com.android.chrome", "com.google.android.gm"])await d.notifyFilter(["com.android.chrome", "com.google.android.gm"]);droidline notify_filter com.android.chrome,com.google.android.gmcurl -s -X POST localhost:8780/devices/_/notify_filter \
-H 'content-type: application/json' \
-d '{"packages":["com.android.chrome","com.google.android.gm"]}'{"id":1,"cmd":"notify_filter","packages":["com.android.chrome","com.google.android.gm"]}on_notification
每当有匹配的通知时调用函数
仅 SDK,基于 subscribe 实现。CLI 会以 JSON 行输出匹配的通知
在 SDK 内运行,服务器收到的是一行 subscribe。
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
package | string | 仅来自此应用 | |
textContains | string | 仅当标题或正文包含此文字 |
返回: 无
stop = d.on_notification(package="com.google.android.gm", callback=print)
# ... later
stop()const stop = await d.onNotification({ package: "com.google.android.gm" }, (n) => console.log(n.title, n.text));
// ... later
stop();droidline on_notification --package com.google.android.gm{"id":1,"cmd":"subscribe","events":["notification"]}服务器
devicespairpair_qrrenamerevokesubscribeserver_infoauth
devices
已配对设备及其在线状态和连接方式
返回: 以下类型的值: list<device>
dl.devices()await dl.devices();droidline devicescurl -s localhost:8780/devices{"id":1,"cmd":"devices"}pair
批准显示此 6 位代码的手机
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
code | string | 必填 | 手机上显示的代码 |
name | string | 设备名称 |
返回: 以下类型的值: device
错误: PAIRING_FAILED
dl.pair("482913", name="shelf-01")await dl.pair("482913", { name: "shelf-01" });droidline pair 482913 --name shelf-01curl -s -X POST localhost:8780/server/pair \
-H 'content-type: application/json' \
-d '{"code":"482913","name":"shelf-01"}'{"id":1,"cmd":"pair","code":"482913","name":"shelf-01"}pair_qr
生成 10 分钟内有效的一次性配对二维码
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
name | string | 设备名称 |
返回: 包含以下字段的对象: uri, expires
dl.pair_qr()await dl.pairQr();droidline pair # shows the QR code in the terminalcurl -s -X POST localhost:8780/server/pair_qr \
-H 'content-type: application/json'{"id":1,"cmd":"pair_qr"}rename
重命名设备
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
device | string | 必填 | 设备 ID 或名称 |
name | string | 必填 | 新名称 |
返回: 以下类型的值: device
dl.rename("k7d2q9xa", "shelf-01")await dl.rename("k7d2q9xa", "shelf-01");droidline rename k7d2q9xa shelf-01curl -s -X POST localhost:8780/server/rename \
-H 'content-type: application/json' \
-d '{"device":"k7d2q9xa","name":"shelf-01"}'{"id":1,"cmd":"rename","device":"k7d2q9xa","name":"shelf-01"}revoke
取消配对设备,需要重新配对才能连接
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
device | string | 必填 | 设备 ID 或名称 |
返回: 无
dl.revoke("shelf-01")await dl.revoke("shelf-01");droidline revoke shelf-01curl -s -X POST localhost:8780/server/revoke \
-H 'content-type: application/json' \
-d '{"device":"shelf-01"}'{"id":1,"cmd":"revoke","device":"shelf-01"}subscribe
在此连接上接收事件
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
events | list<string> | 必填 | 可选 notification、screen、toast、device、result |
device | string | 仅此设备,省略则全部 |
返回: 无
dl.subscribe(["notification"])await dl.subscribe(["notification"]);{"id":1,"cmd":"subscribe","events":["notification"]}server_info
服务器版本、端口和监听地址
返回: 包含以下字段的对象: version, server, name, proto, agent_port, client_port
dl.server_info()await dl.serverInfo();droidline server_infocurl -s -X POST localhost:8780/server/server_info \
-H 'content-type: application/json'{"id":1,"cmd":"server_info"}auth
使用令牌认证此客户端连接
| 名称 | 类型 | 默认值 | 含义 |
|---|---|---|---|
token | string | 必填 | 由 droidline token 生成的客户端令牌 |
返回: 无
dl.auth("your-client-token")await dl.auth("your-client-token");{"id":1,"cmd":"auth","token":"your-client-token"}