对于Marshmallow或更高版本,权限不会在安装时授予,必须在运行时(如果之前未授予)请求所需的权限。
为此,您需要在用户执行需要额外系统权限的操作时,在Activity中运行ActivityCompat.requestPermissions()
以弹出系统权限对话框。
例如,对于WRITE_EXTERNAL_STORAGE
权限:
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_EXTERNAL_STORAGE_REQUEST_CODE
);
注意:
WRITE_EXTERNAL_STORAGE_REQUEST_CODE
是一个任意的整数常量,你应该在其他地方定义它。
你请求的权限也应该在你的
AndroidManifest.xml
中声明。在这个例子中,声明应该是:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
为了处理系统权限对话框的响应,您还需要在Activity中实现
onRequestPermissionsResult()
。对于此示例,代码类似于:
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
if (grantResults.length == 0 || grantResults[0] == PackageManager.PERMISSION_DENIED) {
return;
}
if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
}
}
如果您正在通过
Espresso,
UIAutomator或其他UI测试框架自动化您的应用程序,那么您需要在测试期间预测并单击系统对话框,这可以通过以下测试代码实现:
private void allowPermissionsIfNeeded() {
if (Build.VERSION.SDK_INT >= 23) {
UiObject allowPermissions = mDevice.findObject(new UiSelector().text("Allow"));
if (allowPermissions.exists()) {
try {
allowPermissions.click();
} catch (UiObjectNotFoundException e) {
Timber.e(e, "There is no permissions dialog to interact with ");
}
}
}
}
关于测试系统UI权限的更全面解释可以在这里找到。