19

为 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=""/>

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

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

4

2 回答 2

5

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

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

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

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

这似乎是问题所要求的。如果我不明白你的问题,请告诉我,但如果我明白了,你试图做的就是行不通。

于 2016-09-12T14:26:21.597 回答
4

同意@x-code的回答,尽管您尝试访问另一个应用程序的内部数据,但您对问题的描述不是很清楚,那么您必须有权这样做。

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

实际上,我在文档中发现 SDK 版本 24 现在更新了许多方案,并且在使用文件方面发生了巨大变化,从文档中file://的问题被描述为..

在包域之外传递 file:// 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文件夹中创建一个provider文件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());

我已经从这个博客中获取了这个,所以请阅读它以获得充分的理解。希望它对每个人都有帮助。

于 2016-09-12T14:46:13.943 回答