Flutter Android Fastlane拉取模拟器截图时遇权限拒绝问题
解决Fastlane Screengrab Android 14模拟器截图拉取权限拒绝问题
核心问题
Fastlane Screengrab能正常完成构建、跑测试并在模拟器生成截图,但Android 14(API 34)的应用私有目录权限限制导致adb无法直接访问/data/user/0/io.outright.my_flutter_app/app_screengrab/路径,加上旧参数use_adb_root已废弃,最终拉取截图失败。
解决方案
方法一:把截图存到公共外部存储
修改测试代码,将截图存储路径切换到系统公共图片目录,避开私有目录权限限制:
1. 测试代码中设置存储路径
Java版本:
import android.os.Environment; import java.io.File; import tools.fastlane.screengrab.Screengrab; import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy; @Before public void setup() { Screengrab.setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy()); // 把截图存到公共图片目录下的screengrab文件夹 File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "screengrab"); Screengrab.setScreenshotStorageDirectory(storageDir); }
Kotlin版本:
import android.os.Environment import java.io.File import tools.fastlane.screengrab.Screengrab import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy @Before fun setup() { Screengrab.setDefaultScreenshotStrategy(UiAutomatorScreenshotStrategy()) val storageDir = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "screengrab") Screengrab.setScreenshotStorageDirectory(storageDir) }
2. 测试APK添加权限
在src/androidTest/AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="33"/> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
方法二:用run-as命令中转截图
如果不想改存储路径,通过run-as命令(仅对debug应用有效)把私有目录的截图复制到sdcard,再拉取到本地,在Screengrabfile里添加自定义拉取逻辑:
app_package_name "io.outright.my_flutter_app" tests_package_name "io.outright.my_flutter_app.test" locale "en_US" clear_previous_screenshots true # 自定义拉取命令:先复制到sdcard,再拉取,最后清理临时文件 pull_cmd = <<~CMD adb shell run-as io.outright.my_flutter_app cp -r /data/user/0/io.outright.my_flutter_app/app_screengrab /sdcard/screengrab_temp adb pull /sdcard/screengrab_temp ./fastlane/screenshots adb shell rm -rf /sdcard/screengrab_temp CMD after_test do |runner| system(pull_cmd) end
然后在Fastfile的screengrab lane里,跳过默认的拉取步骤:
lane :screengrab do gradle(task: "clean assembleDebug assembleAndroidTest") screengrab( device_type: "emulator", exit_on_test_failure: true, skip_pull_screenshots: true # 跳过默认拉取,用自定义命令 ) end
其他辅助检查
- 确认模拟器开发者选项中,USB调试和仅充电模式下允许调试已开启
- 尝试升级Fastlane到最新版本,适配Android 14:
bundle update fastlane
原因说明
Android 14大幅收紧了应用私有目录的访问权限,普通adb用户无法直接读取/data/user/0/<包名>/下的内容;而Fastlane的use_adb_root参数在2.0+版本已废弃,无法通过root绕过权限限制,因此必须通过调整存储路径或中转文件的方式解决。
内容的提问来源于stack exchange,提问作者Nick Charney Kaye
相关产品推荐
相关产品推荐

