android - 如何在外部缓存目录中为文件设置 FileProvider

标签 android android-intent

对于 Cache 目录中的文件,我可以在 xml 中添加它来设置 FileProvider

    <cache-path
    name="image"
    path="image/"/>

但是如果我将文件存储在外部缓存目录中,我无法获取外部缓存路径标签或类似的东西来设置 FileProvider.And

    <external-path
    name="image_external"
    path="cache/image/"/>

也没有帮助。

这是我的 list 文件:

 <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.tizi.quanzi"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"/>
 </provider>

这是 xml/file_paths 文件:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <cache-path
        name="image"
        path="image/"/>
    <external-path
        name="image_external"
        path="cache/image/"/>
</paths>

这是我的代码:

String RootPath = App.getApplication().getExternalCacheDir().getAbsolutePath();
String filePath = RootPath + "/image/" + fileName;
// done something there to save file
Intent shareIntent = new Intent();

Uri contentUri = FileProvider.getUriForFile(App.getApplication(),
        App.getApplication().getPackageName(), new File(filePath));
App.getApplication().grantUriPermission(App.getApplication().getPackageName(),
        contentUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
shareIntent.setData(contentUri);
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
shareIntent.setType("image/*");

activity.startActivity(Intent.createChooser(shareIntent, "share image"));

这是错误信息:

    /AndroidRuntime: FATAL EXCEPTION: main
Process: com.tizi.quanzi, PID: 27487
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.tizi.quanzi/cache/image/o9xygODHtdP6HXqsuUZghVCsBKTtY4FJgO1MpnmX.jpg
    at android.support.v4.content.FileProvider$SimplePathStrategy.getUriForFile(FileProvider.java:678)
    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:377)
    at com.tizi.quanzi.tool.ShareImage.shareImage(ShareImage.java:67)
    at com.tizi.quanzi.tool.ShareImage.shareImage(ShareImage.java:61)
    at com.tizi.quanzi.adapter.GalleryAdapter$2.onClick(GalleryAdapter.java:119)
    at android.support.v7.app.AlertController$AlertParams$3.onItemClick(AlertController.java:956)
    at android.widget.AdapterView.performItemClick(AdapterView.java:310)
    at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
    at android.widget.AbsListView$PerformClick.run(AbsListView.java:3042)
    at android.widget.AbsListView$3.run(AbsListView.java:3879)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

最佳答案

更新:
使用支持库 24.2.0 及更高版本的方法是 @ashughes 在他的回答中所说的。

在该版本中,他们为 FileProvider.java 的实现添加了两个新标签能够引用外部文件和缓存目录。

private static final String TAG_EXTERNAL_FILES = "external-files-path";
private static final String TAG_EXTERNAL_CACHE = "external-cache-path";

如果您想深入了解它,可以查看所做的更改 on this commit .

原始答案:
我有同样的问题。我看了一下 FileProvider.java 类,正如你所说,外部缓存目录没有标签,只有下面四个标签。

private static final String TAG_ROOT_PATH = "root-path";
private static final String TAG_FILES_PATH = "files-path";
private static final String TAG_CACHE_PATH = "cache-path";
private static final String TAG_EXTERNAL = "external-path";

我所做的是使用 external-path 标签。此标记将指向外部目录的根目录而不是缓存目录。因此,您可以在 path 上指定从那里到缓存目录的其余路径,或者您可以使用点使其指向外部目录的根目录。

   <external-path
    name="external_files"
    path="."/>

当你使用

<external-path
    name="image_external"
    path="cache/image/"/>

getFileForUri 方法正在检查文件路径是否以 /storage/emulated/0/cache/image/ 开头,但事实并非如此,因为路径你的文件是 /storage/emulated/0/Android/data/com.tizi.quanzi/cache/image/。这就是您获得异常(exception)的原因。

关于android - 如何在外部缓存目录中为文件设置 FileProvider,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34248855/

相关文章:

Android - 以不同的布局启动 Intent

java - 调试 Intent

java - Android Activity 生命周期 : Problems with Onstop()

android - 图像未加载到动态创建的 ImageView 中

android - 如何在android布局中添加unityplayer作为 subview ?

android - 使用 ArrayAdapter 创建多列布局

java - 减少应用程序中的数据使用量支持离线模式

android - 使用 Intent 和 ActivityResultContracts 选择并提取联系人详细信息

java - 保存Android文本文件不会在文件中写入文本

android - RECORD_SOUND_ACTION Intent ,直接进入录音列表