在Kotlin测试中调用UIAutomator的dumpWindowHierarchy遇权限问题求助
解决UiDevice.dumpWindowHierarchy()的权限问题
问题本质
你遇到的EPERM错误,是因为UIAutomator测试进程运行在应用沙箱权限下,无法访问系统级或非应用私有目录——而adb shell uiautomator dump是通过shell用户执行的,拥有更高权限,所以能写入你指定的路径,两者权限环境完全不同。
可行解决方案
方案1:写入应用私有存储目录(最推荐)
直接将dump文件写入测试应用或被测应用的私有存储目录,这类目录不需要额外权限,测试进程默认有权限访问:
// 获取测试应用的Context Context testContext = InstrumentationRegistry.getInstrumentation().getContext(); // 内部私有文件目录路径 String internalPath = testContext.getFilesDir() + "/window_dump.xml"; // 或者外部存储的应用私有目录(Android 10+无需额外权限) String externalPath = testContext.getExternalFilesDir(null) + "/window_dump.xml"; // 调用dump方法 device.dumpWindowHierarchy(internalPath);
之后如果需要将文件导出到电脑,可以通过adb命令拉取:
# 拉取内部目录文件 adb pull /data/data/<测试应用包名>/files/window_dump.xml ./local_path/ # 拉取外部私有目录文件 adb pull /storage/emulated/0/Android/data/<测试应用包名>/files/window_dump.xml ./local_path/
方案2:使用系统临时目录
系统的/data/local/tmp目录是测试进程可访问的临时目录,你可以直接指定这个路径,或者调用无参的dumpWindowHierarchy()方法(默认就会dump到这个路径):
// 直接指定临时目录路径 device.dumpWindowHierarchy("/data/local/tmp/window_dump.xml"); // 或者调用无参方法,自动写入默认路径 device.dumpWindowHierarchy();
之后通过adb拉取文件:
adb pull /data/local/tmp/window_dump.xml ./local_path/
方案3:申请存储权限(仅适用于写入公共目录场景)
如果必须写入外部存储的公共目录(如Downloads),需要提前为测试应用授予存储权限:
- 在测试代码中提前授权(Android 6+):
String testPackageName = InstrumentationRegistry.getInstrumentation().getContext().getPackageName(); // 申请写入外部存储权限 InstrumentationRegistry.getInstrumentation().getUiAutomation() .grantRuntimePermission(testPackageName, Manifest.permission.WRITE_EXTERNAL_STORAGE); // 写入公共Downloads目录(Android 10+需适配分区存储) String publicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/window_dump.xml"; device.dumpWindowHierarchy(publicPath);
- 注意:Android 10+启用了分区存储,即使授予权限,也不能直接写入根目录,只能写入公共目录的特定子文件夹或应用私有外部目录。
内容的提问来源于stack exchange,提问作者AndyReifman
相关产品推荐
相关产品推荐

