这是关于请求Manifest.permission.WRITE_EXTERNAL_STORAGE
权限时的新型号的runtime permissions introduced in Android Marshmallow。
简而言之,我遇到的情况是,如果我请求(并且用户允许) Manifest.permission.WRITE_EXTERNAL_STORAGE
权限,应用程序将无法从外部存储目录中读取和写入,直到我销毁并重新启动应用程序。
这就是我正在做的/正在经历的:
我的应用程序从一种状态开始:
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
这就是说,我没有访问外部存储的权限。
然后,我请求Manifest.permission.WRITE_EXTERNAL_STORAGE的许可,就像谷歌解释的那样
private void requestWriteExternalStoragePermission() {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(this)
.setTitle("Inform and request")
.setMessage("You need to enable permissions, bla bla bla")
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
})
.show();
} else {
ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
}
一旦用户允许该权限,就会调用onRequestPermissionsResult
。
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case RC_PERMISSION_WRITE_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && PackageManager.PERMISSION_GRANTED
// allowed
} else {
// denied
}
break;
}
}
}
执行allowed
块,确认用户已被授予权限。
在此之后立即,如果我不销毁并再次打开应用程序,我仍然没有访问外部存储的权限。更确切地说:
hasWriteExternalStoragePermission(); // returns true
Environment.getExternalStorageDirectory().canRead(); // RETURNS FALSE!!
Environment.getExternalStorageDirectory().canWrite(); // RETURNS FALSE!!
所以,看起来Android运行时认为我有权限,但文件系统没有...实际上,尝试访问Environment.getExternalStorageDirectory()
会抛出一个异常:
android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at libcore.io.IoBridge.open(IoBridge.java:438)
at java.io.FileOutputStream.<init>(FileOutputStream.java:87)
at java.io.FileOutputStream.<init>(FileOutputStream.java:72)
如果我现在销毁应用程序,并再次打开它的,行为变得像它应该,能够读取和写入外部存储文件夹。
有没有人遇到过这种情况?
我使用了一个官方的模拟器:
我用以下命令构建应用程序:
android {
compileSdkVersion 23
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
}
...
}
如果有人确认了这一点,我想我们需要打开一个bug,但我希望我做错了什么,因为我认为这样的核心功能在SDK中不太可能有bug。
https://stackoverflow.com/questions/32947638
复制相似问题