Python 通过 ADB shell 命令实现与 Android 设备的交互,是自动化测试、设备管理、数据获取等场景的核心技术,ADB(Android Debug Bridge)作为 Android 开发调试的桥梁,其 shell 命令可直接在设备或模拟器上执行系统级操作,而 Python 通过 subprocess、os 或第三方库(如 pure-python-adb、ppadb)调用 ADB 命令,能高效整合自动化逻辑,以下从基础操作、进阶应用、代码实现及注意事项等方面展开详细说明。

Python 调用 ADB shell 命令的基础方法
Python 执行 ADB 命令的核心是通过 subprocess 模块启动子进程,将 ADB 命令作为系统命令传递,常见方法包括 subprocess.run()、subprocess.Popen() 和 os.system(),subprocess.run() 因其简洁性和参数控制能力成为主流。
基本语法
import subprocess
# 执行简单 ADB 命令,获取输出结果
result = subprocess.run(["adb", "shell", "ls /sdcard"],
capture_output=True, text=True, check=True)
print(result.stdout) # 输出命令执行结果capture_output=True:捕获标准输出和错误输出。text=True:以文本形式返回输出(默认为字节)。check=True:若命令执行失败(非零退出码)则抛出subprocess.CalledProcessError。
带参数的动态命令
当命令需动态拼接参数时(如指定设备、传递文件路径),需注意参数列表的规范性:
device_id = "emulator-5554" path = "/sdcard/test.txt" command = ["adb", "-s", device_id, "shell", "cat", path] result = subprocess.run(command, capture_output=True, text=True) print(result.stdout)
常见 ADB shell 命令与 Python 实现场景
ADB shell 命令涵盖文件操作、系统信息、应用管理、设备控制等多个维度,以下结合 Python 实现典型用例。
文件与目录操作
通过 adb shell 可对设备文件系统进行读写,Python 用于封装逻辑并处理结果。

| 命令功能 | ADB shell 命令示例 | Python 实现思路 |
|---|---|---|
| 列出目录内容 | adb shell ls /sdcard | 调用命令后解析 stdout,按行分割文件列表 |
| 创建目录 | adb shell mkdir /sdcard/new_dir | 使用 subprocess.run() 执行,检查 returncode 确认是否成功 |
| 复制文件 | adb shell cp /sdcard/a.txt /sdcard/b.txt | 封装为函数,返回操作结果(成功/失败) |
| 删除文件 | adb shell rm /sdcard/test.txt | 结合 try-except 捕获错误输出(如权限不足、文件不存在) |
示例:列出并过滤 SD 卡图片文件
def get_sdcard_images():
command = ["adb", "shell", "ls /sdcard/Pictures"]
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode == 0:
images = [line.strip() for line in result.stdout.split('\n') if line.endswith(('.jpg', '.png'))]
return images
else:
print(f"Error: {result.stderr}")
return []
images = get_sdcard_images()
print("SD卡图片列表:", images)系统信息获取
自动化测试中常需获取设备型号、Android 版本、内存等信息,Python 可用于结构化处理数据。
| 信息类型 | ADB shell 命令示例 | Python 处理方式 |
|---|---|---|
| 设备型号 | adb shell getprop ro.product.model | 提取 stdout 并去除首尾空白字符 |
| Android 版本 | adb shell getprop ro.build.version.release | 同上,可存储为变量用于脚本逻辑分支 |
| 内存使用情况 | adb shell cat /proc/meminfo | 解析输出中的 MemTotal 和 MemFree,计算内存占用率 |
| CPU 信息 | adb shell cat /proc/cpuinfo | 提取 Hardware、Processor 等字段,返回字典格式 |
示例:获取设备基本信息并格式化输出
def get_device_info():
info = {}
commands = {
"model": ["adb", "shell", "getprop", "ro.product.model"],
"android_version": ["adb", "shell", "getprop", "ro.build.version.release"],
"serial": ["adb", "shell", "getprop", "ro.serialno"]
}
for key, cmd in commands.items():
result = subprocess.run(cmd, capture_output=True, text=True)
if result.returncode == 0:
info[key] = result.stdout.strip()
return info
device_info = get_device_info()
print(f"设备型号: {device_info['model']}, Android版本: {device_info['android_version']}")应用管理
自动化测试需控制应用的启动、停止、卸载等操作,Python 可结合 ADB 命令实现流程控制。

| 操作类型 | ADB shell 命令示例 | Python 应用场景 |
|---|---|---|
| 启动应用 | adb shell am start -n com.example/.MainActivity | 测试用例初始化时启动被测应用 |
| 停止应用 | adb shell am force-stop com.example | 测试结束后清理应用进程,避免残留 |
| 卸载应用 | adb shell pm uninstall com.example | CI/CD 流程中自动卸载旧版本应用 |
| 检查应用是否安装 | adb shell pm list packages | grep com.example | 通过 grep 过滤输出,返回 True/False 判断安装状态 |
示例:判断应用是否安装并卸载
def is_app_installed(package_name):
command = ["adb", "shell", "pm", "list", "packages", "|", "grep", package_name]
result = subprocess.run(command, shell=True, capture_output=True, text=True) # 注意:shell=True 用于管道符
return package_name in result.stdout
def uninstall_app(package_name):
if is_app_installed(package_name):
command = ["adb", "shell", "pm", "uninstall", package_name]
result = subprocess.run(command, capture_output=True, text=True)
if result.returncode == 0:
print(f"应用 {package_name} 卸载成功")
else:
print(f"卸载失败: {result.stderr}")
else:
print(f"应用 {package_name} 未安装")
uninstall_app("com.example.test")设备控制与模拟操作
通过 ADB shell 可模拟点击、滑动、输入等操作,结合 Python 实现自动化交互。
| 操作类型 | ADB shell 命令示例 | Python 实现要点 |
|---|---|---|
| 模拟点击 | adb shell input tap 500 300 | 将坐标作为参数传递,封装为点击函数 |
| 模拟滑动 | adb shell input swipe 100 500 500 500 300 | 起始坐标、结束坐标、滑动时长(毫秒)作为参数 |
| 输入文本 | adb shell input text "Hello" | 需对特殊字符转义(如空格用 \\),或通过 shell 参数传递 |
| 截图 | adb shell screencap -p /sdcard/screen.png | 截图后通过 adb pull 传输到本地,结合 PIL 进行图像处理 |
示例:模拟解锁滑动(示例坐标)
def swipe_unlock(start_x, start_y, end_x, end_y, duration=300):
command = ["adb", "shell", "input", "swipe", str(start_x), str(start_y), str(end_x), str(end_y), str(duration)]
subprocess.run(command, check=True)
# 模拟从左向右滑动解锁
swipe_unlock(100, 500, 500, 500, 500)进阶应用与注意事项
多设备管理
当连接多台设备时,需通过 -s 参数指定设备 ID,Python 可动态获取设备列表并分配任务:
def get_connected_devices():
command = ["adb", "devices"]
result = subprocess.run(command, capture_output=True, text=True)
devices = []
for line in result.stdout.split('\n')[1:]: # 跳过第一行 "List of devices attached"
if line.strip():
devices.append(line.split('\t')[0])
return devices
devices = get_connected_devices()
if devices:
print(f"当前设备列表: {devices}")
# 示例:对第一台设备执行操作
subprocess.run(["adb", "-s", devices[0], "shell", "input", "keyevent", "HOME"])
else:
print("未检测到设备")异常处理与日志
ADB 命令可能因设备未授权、命令错误等失败,需通过 try-except 捕获异常并记录日志:
import logging
logging.basicConfig(filename='adb_operations.log', level=logging.ERROR)
def safe_adb_command(command):
try:
result = subprocess.run(command, capture_output=True, text=True, check=True)
return result.stdout
except subprocess.CalledProcessError as e:
logging.error(f"命令执行失败: {' '.join(command)}, 错误: {e.stderr}")
return None
output = safe_adb_command(["adb", "shell", "invalid_command"])
if output is None:
print("命令执行出错,请查看日志")性能优化
- 避免频繁创建子进程:对多次执行的命令(如
adb shell),可保持 ADB 守护进程运行,通过adb shell -进入交互模式。 - 并发执行:使用
concurrent.futures并行操作多设备,提升效率。
相关问答FAQs
Q1: Python 调用 ADB 命令时提示“adb: command not found”,如何解决?
A: 该错误通常表示系统中未安装 ADB 或环境变量未配置,解决步骤如下:
- 下载 ADB 工具(Android SDK Platform Tools),并将其
platform-tools目录路径添加到系统环境变量PATH中。 - 验证安装:在终端执行
adb version,若显示版本信息则配置成功。 - 若 Python 脚本中需指定 ADB 路径(如非标准安装),可通过
subprocess.run(["/path/to/adb", "shell", ...])指定完整路径。
Q2: 如何通过 Python 获取 ADB 命令的错误输出并调试?
A: 使用 subprocess.run() 时,可通过 capture_output=True 捕获标准错误(stderr),结合 try-except 处理异常。
try:
result = subprocess.run(["adb", "shell", "rm /system/allowed"], check=True, capture_output=True, text=True)
except subprocess.CalledProcessError as e:
print(f"命令执行失败,错误码: {e.returncode}")
print(f"错误输出: {e.stderr}") # 通常包含具体错误原因,如 "Permission denied"可通过 adb logcat 查看设备日志,或启用 subprocess 的 universal_newlines=True(等同于 text=True)确保输出编码正确。
文章来源网络,作者:运维,如若转载,请注明出处:https://shuyeidc.com/wp/480292.html<
