【发布时间】:2016-01-02 01:16:02
【问题描述】:
这是关于runtime permissions introduced in Android Marshmallow请求Manifest.permission.WRITE_EXTERNAL_STORAGE权限时的新模型。
简而言之,我遇到的是,如果我请求(并且用户允许)Manifest.permission.WRITE_EXTERNAL_STORAGE 权限,应用程序将无法从外部存储目录读取和写入 ,直到我销毁并重新启动应用程序。
这就是我正在做/正在经历的事情:
我的应用从以下状态开始:
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
也就是说,我没有访问外部存储的权限。
然后,正如 Google 解释的那样,我请求 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 6.0 (API 23) API 23,Rev 1。
- 运行 Intel x86 Atom 系统映像、API 23、Rev 1 的模拟器。
我使用以下方式构建应用程序:
android {
compileSdkVersion 23
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
}
...
}
如果有人证实了这一点,而且我不是唯一一个我想我们需要打开一个错误,但我希望我做错了什么,因为我认为这样的核心功能不太可能在 SDK 中出现错误。
【问题讨论】:
-
"有人遇到这种情况吗?" - 我不是,但我没有在模拟器上尝试过。我一直在使用硬件。
-
@GaRRaPeTa 我现在有同样的问题,症状相同。您是否以其他方式管理过这个?
-
我遇到了同样的问题。你解决了吗?
-
我在模拟器中也遇到了同样的问题,任何人都可以在不重启应用的情况下解决这个问题
标签: android permissions runtime file-permissions android-6.0-marshmallow