我正在使用Spoon 2.0.0快照使用gradle-spoon-plugin为Android UI测试设置Spoon。我的项目是使用Android Gradle插件3.0.1设置的。
通过spoonRule.screenshot(activity, "hello")
截取屏幕截图时,我收到此RuntimeException:
java.lang.RuntimeException: Unable to create output dir: /storage/emulated/0/app_spoon-screenshots
at com.squareup.spoon.SpoonRule.createDir(SpoonRule.java:167)
at com.squareup.spoon.SpoonRule.createDir(SpoonRule.java:164)
at com.squareup.spoon.SpoonRule.createDir(SpoonRule.java:164)
at com.squareup.spoon.SpoonRule.obtainDirectory(SpoonRule.java:108)
at com.squareup.spoon.SpoonRule.screenshot(SpoonRule.java:66)
如果我在Nexus 4 API 19仿真器上运行它,但它在Pixel 2 API 27仿真器上不起作用。权限已从19变为27,所以这并非完全出乎意料。
我已经尝试了当前可用的大部分建议,包括在我的androidTest
目录中添加一个清单,用于授予读写外部存储(使用和不使用maxSdkVersion
):
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="tv.twitch.android.test">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
<uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>
</manifest>
在这两种情况下,我都看到这些权限被合并到我应用的AndroidManifest的最终清单中(不确定如何检查测试应用的清单)。
我尝试通过UIAutomator向应用和测试包授予权限:
val device = UiDevice.getInstance(getInstrumentation())
device.executeShellCommand("pm grant tv.twitch.android.test android.permission.READ_EXTERNAL_STORAGE")
device.executeShellCommand("pm grant tv.twitch.android.debug android.permission.READ_EXTERNAL_STORAGE")
device.executeShellCommand("pm grant tv.twitch.android.test android.permission.WRITE_EXTERNAL_STORAGE")
device.executeShellCommand("pm grant tv.twitch.android.debug android.permission.WRITE_EXTERNAL_STORAGE")
这会向Logcat输出Permission denied
并导致上述相同的异常。
如果我尝试利用GrantPermissionRule
之类的话:
@get:Rule var runtimePermissionRule = GrantPermissionRule.grant(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
我得到了一个不同的例外:
junit.framework.AssertionFailedError: Failed to grant permissions, see logcat for details
at junit.framework.Assert.fail(Assert.java:50)
at android.support.test.runner.permission.PermissionRequester.requestPermissions(PermissionRequester.java:110)
at android.support.test.rule.GrantPermissionRule$RequestPermissionStatement.evaluate(GrantPermissionRule.java:108)
GrantPermissionCallable: Permission: android.permission.WRITE_EXTERNAL_STORAGE cannot be granted!
删除Manifest.permission.WRITE_EXTERNAL_STORAGE
并只留下读取的内容会让我们回到原来的例外:java.lang.RuntimeException: Unable to create output dir: /storage/emulated/0/app_spoon-screenshots
使用gradle-spoon-plugin
在Android Studio内或在命令行上运行不会影响上述任何内容。
查看我的应用和测试应用在“设置”中授予的权限,我看到我的应用具有存储权限,但我的测试应用(tv.twitch.android.test)没有请求任何权限。
我也尝试使用Barista库:
PermissionGranter.allowPermissionsIfNeeded(Manifest.permission.WRITE_EXTERNAL_STORAGE)
他们两个都没有运气。
更新
我尝试将我的测试应用程序定位到SDK版本22,希望它能获得写入权限。
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="tv.twitch.android.test">
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="22"
tools:overrideLibrary="android.support.test.uiautomator.v18"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
通过Gradle(./gradlew spoon
)我尝试配置gradle-spoon-plugin来请求所有权限:
spoon {
// Grant all runtime permissions during installation on Marshmallow and above devices.
grantAll = true
}
没有运气。我甚至尝试使用Spoon库版本1.3.1也无济于事。
答案 0 :(得分:3)
我的问题是由maxSdkVersion中的外部库与WRITE_EXTERNAL_STORAGE权限合并引起的。为了解决这个问题,我删除了该属性并重新添加了WRITE_EXTERNAL_STORAGE权限。这仅适用于我的应用程序清单,而不是测试应用程序清单。
<!-- Strip away maxSdkVersion -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:remove="android:maxSdkVersion"/>
<!-- Add the permission with no maxSdkVersion defined -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
然后,您可以构建,授予权限并运行测试:
# Uninstall existing APKs and install our app APK and test APK
./gradlew uninstallAll installDebug installDebugAndroidTest
# List all APKs installed with adb shell 'pm list packages -f'
# Grant the app APK write and read to external storage permissions
adb shell pm grant gg.mark.debug android.permission.WRITE_EXTERNAL_STORAGE
adb shell pm grant gg.mark.debug android.permission.READ_EXTERNAL_STORAGE
export APK=build/outputs/apk/debug/debug.apk
export TEST_APK=build/outputs/apk/androidTest/debug/debug-androidTest.apk
# TEST_APK and APK are positional arguments so keep them in this order
# Disable GIF generation because it's slow
java -jar spoon-runner-2.0.0.jar --debug --disable-gif "$TEST_APK" "$APK"
如果您的应用的权限未在合并的AndroidManifest.xml中正确设置,则pm grant
命令将失败。确保这些命令成功!
答案 1 :(得分:0)
首先,尝试在Pixel2(API27)上找到SystemSetting->YOUR_APP->Permission
,检查外部存储是否已禁用。
API23(Android 6+)之后的运行时需要EXTERNAL_STORAGE
(WRITE
和READ
)的权限。您应该检查权限并通知用户在系统配置中启用。见Request App Permissions
当然,普通应用程序无法像往常一样使用pm grant ...
授予其权限。
一个未经推荐的解决方案是在API22上使整个应用程序成为目标。但正确的方法还是检查权限并通知用户。