【问题标题】:Picking an image file from Gallery using FileProvider使用 FileProvider 从图库中选择图像文件
【发布时间】:2016-12-30 01:07:11
【问题描述】:

为 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/ 中的图像。请帮忙。

【问题讨论】:

标签: android android-gallery android-fileprovider


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 我正在尝试从图库中挑选一张图片并使用裁剪意图对其进行裁剪。有些图片有效,有些图片无效。
  • 我相信,当我触发 PICK 意图时,我看到的所有图像都是那些对我的应用程序具有访问权限的图像,但是当我触发裁剪意图时 - 我应该授予对这些图像的访问权限。还有一些路径我无法授予访问权限。
【解决方案2】:

同意@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> 

然后在res文件夹下的xml文件夹中创建provider_paths.xml文件。如果文件夹不存在,可能需要创建它。

文件内容如下所示。它描述了我们希望共享对根文件夹 (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,请仔细阅读以充分理解。希望对大家有所帮助。

【讨论】:

猜你喜欢
  • 2013-06-22
  • 2021-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 2017-09-06
  • 1970-01-01
相关资源
最近更新 更多