使用FileProvider

时间:2016-08-23 09:18:24

标签: android android-gallery android-fileprovider

为Android N编译我遇到了FileProvider的问题。我需要让用户从相册中选择图像/用相机拍照然后将其裁剪成方形。

我设法实现FileProvider用相机拍摄图像,但是从图库中选择图像时遇到了严重问题。问题是在图库中有很多来自不同地方的文件,例如我有例外:

  java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/6133-3766/DCIM/100ANDRO/DSC_0035.JPG

所以问题是,我可以将哪些内容添加到 file_paths.xml 以访问/storage/中的任何位置。我不能依赖于确切的路径,因为可能有来自WhatsApp和类似应用程序的图片,例如WhatsApp图像获取此路径:

/storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20160821-WA0000.jpg

我已设法用空路径解决:

<external-path name="external_storage" path=""/>

根据documentation.

类似于Environment.getExternalStorageDirectory()

但仍然无法弄清楚如何处理存储在/storage/SOME_DIR/中的图像。请帮忙。

2 个答案:

答案 0 :(得分:5)

我认为这个问题是基于一种误解。

FileProvider的目的是授予访问权限(对外部应用程序),以及应用程序已经控制的文件。

您永远不会成功使用自己的文件提供程序获取访问外部应用程序拥有的文件。

如果选择使用文件提供程序,则由外部应用程序授予您访问权限。

这似乎是问题所要求的。如果我没有理解你的问题,请告诉我,但如果我理解了,那么你想要做的就是胜利。

答案 1 :(得分:3)

同意@x-code的答案,虽然如果您尝试访问其他应用程序的内部数据,但您必须有权这样做才能解决问题。

合法属于您的应用的文件,应在用户卸载您的应用时删除。虽然这些文件在技术上可由用户和其他应用程序访问,因为它们位于外部存储上,但它们实际上不会为应用程序外的用户提供价值。

实际上我在文档中发现SDK版本24现在已经使用许多方案进行了更新,并且在使用文件时发生了大量更改,从文档中将 file:// 的问题描述为.. < / p>

传递文件://包域外的URI可能会使接收者无法访问路径。因此,尝试传递file:// URI会触发FileUriExposedException。共享私有文件内容的推荐方法是使用FileProvider。

出于安全原因,强烈建议使用Content://而不是使用file://所以基本上使用ContentProvider而不是FileProvider

下面是一个使用它的简单例子,

AndroidMenifest.xml

中的

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest> 

然后在_paths.xml文件夹下的xml文件夹中创建提供程序res文件。如果文件夹不存在,可能需要创建文件夹。

文件内容如下所示。它描述了我们希望在名称为(path=".")的根文件夹external_files上共享对外部存储的访问权限。

<强> RES / XML / 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="."/>
</paths>

现在使用它,

Uri photoURI = FileProvider.getUriForFile(MainActivity.this,
        BuildConfig.APPLICATION_ID + ".provider",
        createImageFile());

我是从this blog获取的,所以请仔细阅读。希望它可以帮助每个人。