如何在外部缓存目录中为文件设置FileProvider [英] how to set FileProvider for file in External Cache dir

查看:243
本文介绍了如何在外部缓存目录中为文件设置FileProvider的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于Cache dir中的文件,我可以将其添加到xml中以设置FileProvider

For file in Cache dir , I can add this in xml to set FileProvider

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

但是,如果我将文件存储在外部缓存目录中,则无法获取external-cache-path标记或用于设置FileProvider的类似标记.

But if I storage file in External Cache Dir,I cannot get external-cache-path tag or something like that to set FileProvider.And

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

也没有帮助.

这是我的清单文件:

 <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文件:

This is the xml/file_paths file:

<?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)

推荐答案

更新:
@ashughes 在回答中说的是支持库24.2.0及更高版本的方式.

Update:
The way to go with the Support Library 24.2.0 and above is how @ashughes says in his answer.

在该版本上,他们为

On that version they added two new tags to the implementation of FileProvider.java to be able to reference the external files and cache directories.

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

如果您想进一步研究它,可以查看所做的更改 对此提交 .

If you want to dig more into it, you can take a look at the changes made on this commit.

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

Original answer:
I had the same problem. I took a look at the class FileProvider.java, and as you said, there is no tag for external cache dir, just the four below.

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上的缓存目录的其余路径,也可以使用点使其指向外部目录的根.

What I do is to use the external-path tag. This tag will point to the root of the external directory not to the cache one. So you can either specify the rest of the path from there to the cache directory on path, or you can use a dot so it points to the root of the external directory.

   <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/.这就是您得到例外的原因.

The method getFileForUri was checking if the path of the file starts with /storage/emulated/0/cache/image/ which it doesn't, because the path of your file is /storage/emulated/0/Android/data/com.tizi.quanzi/cache/image/. And that's the reason you are getting the exception.

这篇关于如何在外部缓存目录中为文件设置FileProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆