【问题标题】:FileProvider vs MediaStore content URIFileProvider 与 MediaStore 内容 URI
【发布时间】:2019-03-10 13:05:59
【问题描述】:

我正在尝试构建一些基本的文件管理器来浏览我的 Android P 设备上的外部存储文件。我有两种方法来创建使用外部应用程序打开文件的意图。除了 Uri 部分之外,这两种方法都相同

其中一个使用 FileProvider 从文件创建 Uri,如下所示:

content://com.myapp.FILE_PROVIDER/external_files/6537-6630/DCIM/Camera/20180727_221149.jpg

另一个查询 MediaStore 并返回如下所示的 Uri:

content://media/external/images/media/3273

其余代码相同

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setDataAndType(uri, mimeType);
startActivity(intent);

两个 URI 都是有效的,但是当我使用 FileProvider 创建的图像打开图像(来自外部存储的随机图像)时,它们会以 只读访问权限 打开在外部应用程序中。我可以说出来,因为我没有得到编辑选项。使用 MediaStore 的 Uri 中的图像按预期打开,具有写入权限,因此具有编辑选项。

我还从 Play 商店下载了几个文件管理器。例如:File Manager - Local and Cloud File Explorer(我猜是使用 FileProvider)在打开图片时也有同样的只读访问问题。

代码

    <provider
        android:name="com.myapp.files.MyFileProvider"
        android:authorities="${applicationId}.FILE_PROVIDER"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="." />
    <root-path name="external_files" path="/storage/" />
</paths>

我的问题是:

1.使用 FileProvider 时我会错过什么吗?也许它不适用于外部存储文件?

2。是否有其他方法可以获取现有文件的有效 URI?因为 MediaStore 没有所有文件

【问题讨论】:

  • “也许它不适合用于外部存储文件?” -- 你可能想发布你的res/xml/provider_paths.xml 资源。从Uri 看来,您正在尝试将FileProvider 用于removable storage,这不太可能正常工作。
  • @CommonsWare,我在所有可能的存储上都试过了,它总是只读的。 provider_paths 包括在内。

标签: android android-fileprovider


【解决方案1】:

也许它不适用于外部存储文件?

您没有将它用于external storage。您将它用于removable storage

&lt;root-path&gt; 未记录且不受支持。 FileProvider 无法可靠地用于可移动存储,因为您的应用无法访问可移动存储上的任意文件系统位置。我的猜测是,如果您尝试在应用程序中写入该文件——无论是使用File 还是Uri——都会失败并出现错误。

MediaStore 可以访问更多可移动存储,因为它是操作系统的一部分。

是否有其他方法可以获取现有文件的有效 URI?

欢迎您使用ACTION_OPEN_DOCUMENT_TREE 并要求用户选择他们的可移动存储。然后你可以:

  • 使用takePersistableUriPermission() 可以长期访问用户选择的文档树
  • 使用DocumentFile 遍历该文档树并获取其中文档的Uri

请记住,用户不必选择他们的可移动存储 - 欢迎他们选择他们想要的任何文档树。如果操作得当,这可能是您应用中的一项功能,而不是错误。

【讨论】:

  • 感谢您的回答。我发布的这个特殊的 Uri 确实来自 sd 卡,但问题是我在设备上每个文件夹的其他图像上尝试过 - 结果相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多