无法在Marshmallow上测试需要CHANGE_NETWORK_STATE / WRITE_SETTINGS权限的代码

时间:2018-05-03 14:52:22

标签: android android-permissions android-espresso

我正在尝试将我的应用程序的targetSDK升级到23以上,并且我遇到了一个小问题。我有一个活动将流量绑定到Wifi(以测量到路由器的网络速度,即使路由器没有连接到互联网)。为了实现这一点,我的应用需要CHANGE_NETWORK_STATE权限。如果在清单中声明,则通常直接授予该权限。在Android 6.0上(确切地说,这已在6.0.1 IIRC中修复)CHANGE_NETWORK_STATE已损坏且未获批准,因此您需要WRITE_SETTINGS权限。我已经为Android 6.0用户实现了授予该权限的方式,但是当我想使用espresso测试我的Activity时,我无法这样做。通过添加类似

之类的内容授予测试权限

@Rule public GrantPermissionRule runtimePermissionRule = GrantPermissionRule.grant(Manifest.permission.CHANGE_NETWORK_STATE);

到TestCase。这在应用程序的其他地方工作,但为此我得到 我的测试结果中junit.framework.AssertionFailedError: Failed to grant permissions, see logcat for details。在logcat中,我发现E/GrantPermissionCallable: Permission: android.permission.WRITE_SETTINGS cannot be granted!或与CHANGE_NETWORK_STATE相同,我尝试同时授予它们,但它们都不起作用。我有没有其他方式在测试环境中授予权限?或者我从现在开始无法在6.0设备上测试此活动?

2 个答案:

答案 0 :(得分:1)

由于WRITE_SETTINGS是敏感权限,您将无法使用API​​ 23中的GrantPermissionRule授予它。您可能最终需要在测试中使用UIAutomatorpermissions management screen中选择适当的响应。

答案 1 :(得分:1)

我设法通过使用UiAutomator和shell appops命令授予权限来解决此问题:

Instrumentation instrumentation = getInstrumentation();
UiDevice device = UiDevice.getInstance(instrumentation);
String targetPackageName = instrumentation.getTargetContext().getPackageName();

if (Build.VERSION.SDK_INT >= 23) {
    String shellCommand = String.format("appops set %s WRITE_SETTINGS allow", targetPackageName);
    device.executeShellCommand(shellCommand);
}