Android M 用户权限错误 - 读写

Android M User Permission Error - READ and WRITE

我刚开始使用 android M,我无法访问外部存储。我收到以下错误

Caused by: java.lang.SecurityException: Permission Denial: reading 
com.android.providers.media.MediaProvider uri 
content://media/external/images/media from pid=15355, uid=10053 requires 
android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() 

我正在清单中添加用户权限,例如

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我的构建文件具有以下设置:

compileSdkVersion 23
buildToolsVersion "22.0.1"

minSdkVersion 16
targetSdkVersion 23

如何读写androidM的外存?

正在阅读 documentation。我必须在运行时请求用户许可。代码示例:

向 android 清单添加权限,就像我们之前做的那样:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

检查用户是否已经授权。如果是,请跳过请求许可并继续您的工作流程,否则请请求用户许可:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (!Settings.System.canWrite(this)) {
        requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE}, 2909);
    } else {
        // continue with your code
    }
} else {
    // continue with your code
}

现在检查用户是否授予权限或拒绝权限@Override OnRequestPermissionResult 以获得回调:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case 2909: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.e("Permission", "Granted");
            } else {
                Log.e("Permission", "Denied");
            }
            return;
        }
    }
}

I was not able to READ external storage only by asking WRITE permission, so i had to request for Manifest.permission.READ_EXTERNAL_STORAGE as well.


Also if you want to target versions below api 23, check the Build VERSION at runtime with IF statement and ask for permissions only if VERSION is equal or above Android M.

如果您正在寻找一种方法来处理任何 android 版本(您正在为 M 编译,但某些设备可以使用其他版本),这里有一个兼容版本。

if (ContextCompat.checkSelfPermission(CreatePlayerActivity.this,
            Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(CreatePlayerActivity.this,
                Manifest.permission.READ_EXTERNAL_STORAGE)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(CreatePlayerActivity.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_READ_CONTACTS);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }

我正在努力获得 WRITE_EXTERNAL_STORAGE 权限:在我请求它之后,对话框没有出现并立即返回 DENIED

问题出在其中一个库中。它在 AndroidManifest.xml 中包含相同的权限声明,但带有 maxSdkVersion="22"。应用程序清单文件中的声明已被库覆盖。

为了覆盖图书馆的权限,我使用了以下内容:

  <uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    tools:node="remove"
    tools:selector="com.example.lib" />

希望对您有所帮助。

关于所选答案:

Settings.System.canWrite(this)WRITE_EXTERNAL_STORAGE 是两个截然不同的东西!应该是:

    boolean needsRead = ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED;

    boolean needsWrite = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED;

    if (needsRead || needsWrite)
        requestStoragePermission()

我在 github 上使用了这个实用程序。它适用于 API 22 和 23。添加运行时权限并不难,但必须分离代码并四处移动方法以捕获回调有点痛苦。这个库提供了一个链式 api 来做所有你需要做的来支持运行时权限。

https://github.com/kayvannj/PermissionUtil