使用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/任何地方。 我不能依赖确切的path,因为有可能来自WhatsApp和类似的应用程序的图片,例如WhatsApp图像得到这个path:

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

我已经设法解决空path:

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

根据文档类似于Environment.getExternalStorageDirectory()

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

Solutions Collecting From Web of "使用FileProvider从图库中选取图像文件"

我想这个问题是基于一个误解。

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

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

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

这似乎是问题所要求的。 如果我不明白你的问题,让我知道,但如果我明白了,你所要做的只是行不通的。

同意@ x-code的答案你没有描述非常清楚的问题,虽然如果你尝试访问另一个应用程序的内部数据,那么你必须有权限这样做。

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

实际上,我发现文档中的SDK版本24现在更新了很多scheme,并在处理文件方面有了巨大的变化,从文档file://的问题被描述为..

在包域之外传递file:// URI可能会使接收器无法访问path。 因此,尝试传递file:// URI会触发FileUriExposedException。 分享私人文件内容的推荐方法是使用FileProvider。

由于安全原因,强烈build议使用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> 

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

该文件的内容如下所示。 它描述了我们想要以名称external_files在根文件夹(path=".")共享对外部存储的访问。

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

我已经从这个博客采取这个,所以请阅读它的全面理解。希望它可以帮助每个人。