如何在外部caching目录中为文件设置FileProvider

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

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

但是,如果我在外部caching目录存储文件,我不能得到外部cachingpath标记或类似的东西设置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文件:

 <?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 ,以便能够引用外部文件和caching目录。

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

如果你想深入挖掘,你可以看看这个提交的改变。

原始答案:
我有同样的问题。 我看了一下FileProvider.java这个类,正如你所说的那样,外部cachingdir没有标签,下面是四个标签。

 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标记。 这个标签将指向外部目录的根目录而不是caching目录。 因此,您可以指定path的其余部分到path上的caching目录,也可以使用点来指向外部目录的根目录。

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

当你使用

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

getFileForUri方法检查文件path是以/storage/emulated/0/cache/image/开头的,因为文件的path是/storage/emulated/0/Android/data/com.tizi.quanzi/cache/image/ 。 这就是你得到例外的原因。

从支持库24.2.0开始,您可以使用:

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

有关更多详细信息,请参阅FileProvider文档 。

以下configuration适用于我:我使用

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

在我的代码。

和我的提供者看起来像这样

  <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.bqe.core.provider.CameraFilesProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_files_provider_paths" /> 

我的分钟sdk

  minSdkVersion 21