2021 年,发布了 Gradle 托管设备 (DMG) 和 Android 测试设备 (ATD) 映像。使用带有这些图像的模拟器往往会更快,并且使用更少的资源进行仪器测试。
缺点是关于它们的文档似乎很少。
我几乎在任何地方都找不到任何有关处理 ATD 权限和仪器测试的内容。
这是一个问题,因为我试图让我们的应用程序的仪器测试在这些设备上运行,以便更轻松地在 CICD 中运行它们。
Android 10 之后,权限处理发生了变化。现在有安装权限、运行时权限和特殊权限。
在 GMD 上运行测试时,它们可以轻松成为没有预设配置的新映像。这意味着您必须授予权限。
特殊权限的工作非常具有挑战性。
通常在请求这些权限时,你必须发出一个特殊的意图让用户双重确认权限,例如
Settings.ACTION_MANAGE_WRITE_SETTINGS
。
这是一个问题,因为 ATD 没有安装设置。这意味着应用程序崩溃,并显示以下堆栈跟踪:
android.content.ActivityNotFoundException: No Activity found to handle Intent
{ act=android.settings.action.MANAGE_WRITE_SETTINGS
cat=[android.intent.category.DEFAULT] dat=package:sequoia.gui.demo flg=0x50800000 }
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2087)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1747)
at
androidx.test.runner.MonitoringInstrumentation.execStartActivity(MonitoringInstrumentation.java:605)
我已经尝试过
GrantPermissionsRule
:
Permission: android.permission.WRITE_SETTINGS cannot be granted!
failed: existence(sequoia.gui.test.app.MainActivityTest)
----- begin exception -----
junit.framework.AssertionFailedError: Failed to grant permissions, see logcat for details
at junit.framework.Assert.fail(Assert.java:50)
at
androidx.test.runner.permission.PermissionRequester.requestPermissions(PermissionRequester.java:111)
at
androidx.test.rule.GrantPermissionRule$RequestPermissionStatement.evaluate(GrantPermissionRule.java:135)
还有
UiAutomation.grantRuntimePermission
:
java.lang.SecurityException: Error granting runtime permission
at android.app.UiAutomation.grantRuntimePermissionAsUser(UiAutomation.java:1271)
at android.app.UiAutomation.grantRuntimePermission(UiAutomation.java:1238)
如何实现这一目标?
我最终开始工作的解决方案是使用内置命令
appops
:
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
UiDevice device = UiDevice.getInstance(instrumentation);
String targetPackageName = instrumentation.getTargetContext().getPackageName();
String permissionCommand = String.format("appops set %s WRITE_EXTERNAL_STORAGE allow", targetPackageName);
device.executeShellCommand(permissionCommand);