未Root安卓设备下,Windows平台Java版Appium能否实现文件读写?
我在Windows平台使用Java版Appium,想要对Android设备进行文件读写操作,遇到了以下问题:
ADB权限受限:为确认
/data、/Download等路径,我尝试执行adb命令,但即便以管理员身份运行终端,执行adb shell ls -R仍出现大量权限拒绝提示,甚至无法访问被测应用(AUT)的数据文件。ProcessBuilder执行ADB无输出:我在程序中通过ProcessBuilder执行adb命令,代码如下,但没有任何输出:
String cmd = " adb devices"; ProcessBuilder processBuilder = new ProcessBuilder(); processBuilder.command("sudo C:\\Users\\myUser\\AppData\\Local\\Android\\Sdk\\platform-tools\\adb.exe", cmd); Process process = processBuilder.start();
- pushFile操作失败:执行文件推送操作时失败,代码及报错如下:
driver.pushFile("[can't find the expected filesystem mapping anywhere!!!] \\storage(maybe??)\\Download\\bird.jpg", new File("C:\\Users\\myUser\\Downloads\\bird.jpg"));
报错信息:
adb: error: failed to copy 'C:\Users\myUser\AppData\Local\Temp\2024826-17660-y8us7v.ja5ka\appium.tmp' to '\storage\Download\bird.jpg': remote couldn't create file: Read-only file system
请问:所有Appium测试人员都需要Root设备才能进行文件操作吗?有没有无需Root即可访问、列出、复制或删除文件的方法?
一、ADB权限问题的本质
Android系统有严格的权限隔离机制:
/data属于系统敏感目录,默认仅Root权限可完整访问,普通ADB用户仅能查看部分公开子目录。- 被测应用的私有数据目录
/data/data/[包名]/,在Android 11+版本中,ADB无法直接访问,除非应用开启debuggable模式,此时可通过adb shell run-as [包名] ls命令进入目录查看。 /Download这类公共存储目录的正确路径是/sdcard/Download或/storage/emulated/0/Download,ADB默认有权限访问。
二、修复ProcessBuilder执行ADB无输出的问题
你的代码存在两处错误:
- Windows系统无
sudo命令,需直接移除。 ProcessBuilder.command()需将命令与参数拆分传入,而非将完整命令作为参数。正确写法:
ProcessBuilder processBuilder = new ProcessBuilder( "C:\\Users\\myUser\\AppData\\Local\\Android\\Sdk\\platform-tools\\adb.exe", "devices" ); Process process = processBuilder.start(); // 读取标准输出 BufferedReader outReader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = outReader.readLine()) != null) { System.out.println(line); } // 读取错误输出(排查报错) BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream())); while ((line = errReader.readLine()) != null) { System.err.println(line); }
之前无输出是因为未读取进程的输入/错误流(进程会因缓冲区满阻塞),同时命令参数传递错误。
三、修复pushFile失败的问题
报错原因是路径错误,Android公共存储的正确路径格式为/sdcard/Download/,修改代码如下:
driver.pushFile("/sdcard/Download/bird.jpg", new File("C:\\Users\\myUser\\Downloads\\bird.jpg"));
同时需确保被测应用已申请并授权WRITE_EXTERNAL_STORAGE(Android 10及以下)或MANAGE_EXTERNAL_STORAGE(Android 11+)权限。
四、无需Root的文件操作方法
大部分常用文件操作无需Root,分场景说明:
公共存储目录(/sdcard/Download、/sdcard/Pictures等):
只要应用有对应存储权限,ADB和Appium的pushFile/pullFile可直接操作,ADB命令示例:adb push 本地文件路径 /sdcard/Download/ adb pull /sdcard/Download/目标文件 本地路径被测应用私有数据目录:
若应用开启debuggable模式,可通过run-as命令操作:adb shell run-as [包名] cat /data/data/[包名]/files/xxx.txt adb shell run-as [包名] echo "测试内容" > /data/data/[包名]/files/xxx.txtAppium中可通过脚本执行:
driver.executeScript("mobile: shell", ImmutableMap.of( "command", "run-as com.example.app cat /data/data/com.example.app/files/xxx.txt" ));系统公开目录:
如/system/media等公开系统目录,仅支持只读访问,写入需Root权限。
总结:仅访问系统敏感目录、非debuggable应用私有数据时才需要Root,日常测试的文件操作大部分无需Root。
内容的提问来源于stack exchange,提问作者Ety

