【问题标题】:Android M User Permission Error - READ and WRITEAndroid M 用户权限错误 - 读写
【发布时间】:2015-11-17 11:47:15
【问题描述】:

我刚开始使用 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

如何在android M中读写外部存储?

【问题讨论】:

  • 哇,你问了一个问题,并在几毫秒内立即回答了它。你真是个天才。
  • 嗨@SharpEdge 我认为这样做是一个好习惯。 stackoverflow.com/help/self-answer 我花了一个小时寻找解决方案,希望将来能节省其他人的时间。 :)
  • 我不知道..这个声明存在 “如果你有一个你已经知道答案的问题,并且你想公开记录这些知识,以便其他人(包括你自己)以后可以找到它”抱歉讽刺。
  • 没关系,我不介意 :) 祝你有美好的一天!

标签: android user-permissions


【解决方案1】:

documentation 读取。我必须在运行时向用户征求许可。代码示例:

像我们之前做的那样向 android manifest 添加权限:

<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;
        }
    }
}

我无法仅通过询问 WRITE 来读取外部存储 许可,所以我不得不请求 Manifest.permission.READ_EXTERNAL_STORAGE 也是。


此外,如果您想定位低于 api 23 的版本,请检查 Build VERSION 在运行时使用IF 语句并仅在以下情况下请求权限 VERSION 等于或高于Android M

【讨论】:

  • 嗨@ajit 你是对的,它仅在最小 API 23 上有效!但是,在运行时通过if 语句进行简单的版本检查..您也可以支持以前的版本..我一回到我的电脑上就会编辑带有 pre M 支持的 ans..
  • 今天我发布了一个问题,但想找到合适的解决方案,你能帮我吗
  • 有一点很重要,您可以为两者添加代码(最低 23 级或以下),以便对其他开发人员有所帮助。谢谢
  • @Ajit 我已经用你的建议更新了答案!感谢您指出:)
  • Settings.System.canWrite(this)WRITE_EXTERNAL_STORAGE 是两个非常不同的东西!应该是(评论代码是可怕的,贴出更正的答案)。
【解决方案2】:

如果您正在寻找一种在任何 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.
        }
    }

【讨论】:

    【解决方案3】:

    关于选择的答案:

    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()
    

    【讨论】:

      【解决方案4】:

      我正在努力获得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" />
      

      我希望这可能会有所帮助。

      【讨论】:

        【解决方案5】:

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

        https://github.com/kayvannj/PermissionUtil

        【讨论】:

          猜你喜欢
          • 2015-12-23
          • 2014-12-04
          • 1970-01-01
          • 1970-01-01
          • 2017-08-09
          • 1970-01-01
          • 2015-12-19
          • 2016-03-25
          • 2017-04-11
          相关资源
          最近更新 更多