写入SD卡“java.io.FileNotFoundException:Permission denied”

时间:2017-04-11 15:48:09

标签: java android android-contentprovider android-permissions storage-access-framework

stackoverflow上有很多类似的问题,但我仍然无法找到解决我的特定问题的方法:

我有一个具有WRITE_EXTERNAL_STORAGE权限的应用和一个未导出的文件提供商

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.cgogolin.library"
      ...
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
      <uses-sdk android:minSdkVersion="11" android:targetSdkVersion="23" />
      ...
      <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.cgogolin.library.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
      </provider>
</application>

provider_paths.xml中进一步指定为

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <external-path name="external_files" path="."/>
  <root-path name="external_files2" path="/storage/"/>
</paths>

我想用它来提供从SD卡到其他应用程序的文件(在这种情况下,我的应用程序或多或少地作为文件浏览器,但不完全......)。

当我使用API​​级别23时,我还通过调用

动态请求权限
requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_PERMISSION_REQUEST);

显示对话框窗口,点击“允许”后(由于Can't write to external storage unless app is restarted after granting permission中描述的错误重新启动应用程序),应用程序正确获取权限,我可以通过测试验证是否

android.support.v4.content.ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED

确实如此。我还可以从sdcard获取UriFile个文件,例如

Uri uri = android.support.v4.content.FileProvider.getUriForFile(context, "com.cgogolin.library.fileprovider", file);

我可以从该文件中读取,例如我可以成功启动Intent.ACTION_VIEW以在外部应用程序中打开该文件。

但是:尽管有写权限,但我无法写入文件。所有尝试使用以下任一方式打开OutputStreamParcelFileDescriptoruri

context.getContentResolver().openOutputStream(uri, "wa");
context.getContentResolver().openFileDescriptor(uri, "wa");

直接从我的应用程序或通过Intent打开的应用程序导致

java.io.FileNotFoundException: Permission denied

我的错误在哪里?我认为在checkSelfPermission()告诉我之后WRITE_EXTERNAL_STORAGE我应该能够这样做。

2 个答案:

答案 0 :(得分:0)

  

我想用它来提供从SD卡到其他应用程序的文件

首先,root-path上没有记录FileProvider

其次,在非常具体的位置之外(例如,getExternalFilesDirs()返回的第二个和后续值),您对可移动存储没有读取或写入权限。外部存储权限与可移动存储无关。

答案 1 :(得分:0)

答案是让用户通过Intent.ACTION_OPEN_DOCUMENT_TREE为整个SD卡(或相关子目录)提供应用程序写入权限,如本文Android SD Card Write Permission using SAF (Storage Access Framework)中所建议的那样。