
1. 项目概述adb远程控制与屏幕文本输入自动化在移动应用测试领域adbAndroid Debug Bridge一直是工程师手中的瑞士军刀。最近我在一个跨设备自动化项目中需要实现通过adb获取屏幕文本并自动回填内容的功能这种技术组合特别适合需要绕过UI控件直接操作的特殊测试场景。比如当应用使用自定义渲染控件时传统基于坐标点击的自动化方案往往失效而通过OCR识别屏幕文字再通过adb注入输入流就成了可靠替代方案。这个方案的核心价值在于三点首先它不依赖被测应用的UI层级结构对游戏、地图类应用特别有效其次通过adb命令可以直接模拟物理按键和触摸事件比基于AccessibilityService的方案更接近真实操作最后整套流程可以在没有root权限的设备上运行对测试环境要求较低。我在电商App的搜索框自动化测试中采用这个方法后用例稳定性从72%提升到了98%。2. 核心原理与技术栈拆解2.1 adb输入事件模拟机制Android输入子系统采用分层架构adb通过注入事件到/dev/input/eventX设备节点来模拟真实输入。关键命令是adb shell input它支持以下几种事件类型# 文本注入支持unicode adb shell input text 你好Hello123 # 按键事件KEYCODE_HOME3 adb shell input keyevent 3 # 精确坐标触控x,y 单位像素 adb shell input tap 500 1200 # 滑动手势duration单位为毫秒 adb shell input swipe 300 1000 300 500 200重要提示不同Android版本对input命令的限制不同特别是Android 10以上对后台应用输入有限制需要在开发者选项中开启USB调试安全设置。2.2 屏幕文本获取方案对比获取屏幕文本主要有三种技术路线方案类型优点缺点适用场景UI Automator官方支持稳定性高需要控件可访问标准Android控件OCR识别无视UI层级性能开销大游戏/视频流adb screencap系统级支持需二次处理所有可见内容我最终选择adb exec-out screencap -p结合Tesseract OCR的方案虽然要多一步图像处理但可以应对各种极端情况。以下是获取屏幕文字的核心代码片段import pytesseract from PIL import Image def get_screen_text(): # 获取屏幕截图 os.system(adb exec-out screencap -p screen.png) # 图像预处理 img Image.open(screen.png) gray img.convert(L) threshold gray.point(lambda x: 255 if x 180 else 0) # OCR识别 text pytesseract.image_to_string(threshold, langchi_simeng) return text.strip()3. 完整实现流程与优化技巧3.1 环境准备与adb配置adb环境配置下载最新Platform-tools包建议v34.0添加环境变量export PATH$PATH:/path/to/platform-tools验证连接adb devices -l应显示设备序列号和状态OCR环境安装# Ubuntu sudo apt install tesseract-ocr tesseract-ocr-chi-sim # MacOS brew install tesseract tesseract-lang设备端特殊配置adb shell settings put global hidden_api_policy 1 adb shell pm grant com.example.test android.permission.DUMP3.2 自动化输入控制实现完整的文本替换流程需要处理以下几个关键环节目标定位def find_input_position(text): screenshot get_screen_text() if text in screenshot: # 使用图像匹配算法定位坐标 return (x,y) raise Exception(Target text not found)输入法切换# 切换为ADB键盘需提前安装 adb shell ime set com.android.adbkeyboard/.AdbIME智能输入策略def smart_input(text): if len(text) 50: os.system(fadb shell input text {text}) else: # 长文本分批次输入 for chunk in [text[i:i40] for i in range(0, len(text), 40)]: os.system(fadb shell input text {chunk}) time.sleep(0.3)3.3 性能优化方案通过adb批量执行命令会有明显延迟我通过以下方法将操作耗时从平均1.2s/次降低到0.3s/次命令管道化# 低效方式 os.system(adb shell input tap 100 200) os.system(adb shell input text abc) # 高效方式 os.system(adb shell input tap 100 200; input text abc)截图压缩传输adb exec-out screencap | gzip -d screen.png多线程处理from concurrent.futures import ThreadPoolExecutor def parallel_commands(commands): with ThreadPoolExecutor(max_workers3) as executor: executor.map(os.system, commands)4. 典型问题排查手册4.1 连接类问题现象adb devices显示unauthorized解决方案检查设备是否弹出RSA密钥确认对话框重启adb服务adb kill-server adb start-server删除旧密钥rm ~/.android/adbkey*现象device offline根本原因adb版本不匹配处理步骤adb version # 客户端版本 adb shell getprop ro.build.version.sdk # 设备API级别 # 解决方案升级platform-tools到最新版4.2 输入异常处理现象中文输入变成问号修复方案使用ADB Keyboard输入法或者通过base64编码传输echo 你好 | base64 | adb shell am broadcast -a ADB_INPUT_B64 --es msg base64现象输入内容错乱可能原因特殊字符未转义正确处理import re safe_text re.sub(r[^a-zA-Z0-9\u4e00-\u9fa5], _, text)4.3 OCR识别优化识别率低的常见改进措施图像预处理# 使用OpenCV增强对比度 import cv2 img cv2.imread(screen.png, 0) clahe cv2.createCLAHE(clipLimit3.0, tileGridSize(8,8)) enhanced clahe.apply(img)区域限定识别# 只识别屏幕下半部分 height img.shape[0] roi img[height//2:height, 0:]自定义训练数据tesseract --user-words words.txt --user-patterns patterns.txt5. 高级应用场景扩展5.1 跨设备控制方案通过adb over WiFi实现多设备控制adb tcpip 5555 adb connect 192.168.1.100:5555 # 多设备操作时指定序列号 adb -s 192.168.1.100:5555 shell input text text5.2 自动化测试集成与pytest结合的典型用例import pytest pytest.fixture(scopemodule) def adb(): return AdbWrapper() def test_search_function(adb): adb.tap(500, 200) # 点击搜索框 adb.input(测试商品) assert 搜索结果 in adb.get_screen_text()5.3 异常监控方案实时监控屏幕关键词while True: text get_screen_text() if 停止服务 in text: alert_admin() break time.sleep(5)在实际项目中这套方案帮我解决了三个棘手问题游戏自动化测试中的虚拟按钮识别、金融App动态键盘的安全输入、以及工业平板在恶劣环境下的远程维护。特别是在Android系统碎片化严重的现状下adb方案的兼容性优势尤为明显。