使用FileProvider通过Intent发送不同类型的多个文件

时间:2015-12-10 18:12:30

标签: android android-intent

我想使用Intent通过FileProvider分享图片和音频文件。

当我尝试仅发送两个文件中的一个(它们都工作),但是时,当我传递一个包含我得到的两个文件的URI的数组列表时,它有效以下例外。

Writing exception to parcel      java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/fs_id from pid=27900, uid=10062 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
      at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
      at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
      at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
      at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
      at android.os.Binder.execTransact(Binder.java:453)

这是我在AndroidManifest

中设置提供程序的方法
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.mypackage.mybeautifulprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider_paths" />
</provider>

这就是我创建Intent

的方法
ArrayList<Uri> uris = new ArrayList<>();

// image file
Uri uri = FileProvider.getUriForFile(context, "com.mypackage.mybeautifulprovider", imageFile);
uris.add(uri);

// audio file
uri = FileProvider.getUriForFile(context, "com.mypackage.mybeautifulprovider", audioFile);
uris.add(uri);

Intent intent = new Intent();
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setAction(Intent.ACTION_SEND);
intent.setType("*/*");
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);

// start intent
.... 

1 个答案:

答案 0 :(得分:1)

正如Forget the Storage Permission talk中所述,FLAG_GRANT_READ_URI_PERMISSIONFLAG_GRANT_WRITE_URI_PERMISSION仅适用于setData()中设置的URI。如果您需要多个Uris,则需要将它们添加为ClipData:

ClipData clipData = ClipData.newRawUri(null, imageUri);
clipData.addItem(new ClipData.Item(audioUri));
intent.setClipData(clipData);

请注意,setClipData()仅在API 16中添加。