48

I am trying to use FileProvider to play a video from private path.Facing

java.lang.IllegalArgumentException: Failed to find configured root that contains /data/data/XXXXX(Package)/files/Videos/final.mp4

Code:

<paths>
    <files-path path="my_docs" name="Videos/" />
</paths>

Java code:

File imagePath = new File(getFilesDir(), "Videos");
File newFile = new File(imagePath, "final.mp4");
Log.d(TAG, "-------------newFile:"+newFile.exists());//True here
//Exception in below line
Uri contentUri = FileProvider.getUriForFile(this,"com.wow.fileprovider", newFile);

Manifest.xml

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.wow.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">

<meta-data
    android:name="android.support.FILE_PROVIDER_PATHS"
    android:resource="@xml/file_paths" />

Any clues on this?

Thanks Nitz

galath
  • 5,717
  • 10
  • 29
  • 41
NitZRobotKoder
  • 1,046
  • 8
  • 44
  • 74
  • I was getting "Attribute is missing the Android namespace prefix" in @xml/file_paths while implementing Fileprovider..later somehow i ended up misplacing the name and path and ended up with this issue.. – NitZRobotKoder Jul 12 '15 at 17:34

3 Answers3

63

You have your name and your path flipped. name is what goes in the Uri, and path is the relative location within the root on the filesystem.

Go with:

<paths>
    <files-path name="my_docs" path="Videos/" />
</paths>
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Gosh!! Wonder how I misplaced it. You saved my day thanks.. :-) – NitZRobotKoder Jul 10 '15 at 17:22
  • Stuck with"java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{44c35948 3239:com.mxtech.videoplayer.ad/u0a307} (pid=3239, uid=10307) that is not exported from uid 10221" Trying to pass to video player via intent. – NitZRobotKoder Jul 10 '15 at 18:02
  • 2
    @NitZRobotKoder: If by "video player", you mean a separate app, then add `FLAG_GRANT_READ_URI_PERMISSION` to your `Intent` that you use with `startActivity()` to launch the player. If by "video player" you mean `MediaPlayer`, I'd go the `FileDescriptor` route rather than a `ContentProvider`. If by "video player" you mean `VideoView`, I have no suggestions. – CommonsWare Jul 10 '15 at 18:24
  • intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Log.d(TAG, "-------------PAth:"+contentUri.getPath()); intent.setData(contentUri); intent.setType("video/mp4"); Sloved it but getting " Writing exception to parceljava.lang.IllegalArgumentException: the bind value at index 1 is null" – NitZRobotKoder Jul 10 '15 at 18:25
  • Pls see http://stackoverflow.com/questions/31321310/android-unable-to-play-video-from-private-path-subdirectory-using-intent Now taking file provider route.Trying to play using external video players available. – NitZRobotKoder Jul 10 '15 at 18:28
  • Intent intent = new Intent(); intent.setAction(android.content.Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(contentUri, "video/*"); startActivity(intent); ..Worked setting type and data separate was the issue.. – NitZRobotKoder Jul 12 '15 at 17:24
  • I forgot the `getFilesDir()`. Another thing to keep on lookout. – Souradeep Nanda May 26 '18 at 13:36
  • `name` is the parent directory and `path` is the subdirectory. It's confusing how the [documentation](https://developer.android.com/reference/androidx/core/content/FileProvider#SpecifyFiles) explains it. – lasec0203 Aug 21 '21 at 08:54
11

change your provider XML to this.

<?xml version="1.0" encoding="utf-8"?>
<paths>
  <external-path name="external_files" path="." />
  <root-path name="external_files" path="/storage/" />
</paths>
5

I had the very same basic situation. I defined everything correctly (files-path in xml) but there is one more thing which leads to the same exception. I add another answer just as an addition and a comment would not be well readable.

I created/read the directory where i store the files like:

context.getDir("Documents", Context.MODE_PRIVATE) 

This leads to a path like:

/data/user/0/ch.myapp/app_Documents/6c3c70d5-af66-48ef-8dfc-f4341de4e1bd.docx

Then i changed creating the directory to:

File directory = new File(context.getFilesDir(), "Documents");
if (!directory.exists()) {
  directory.mkdir();
}

This leads to a path like:

/data/user/0/ch.myapp/files/Documents/6c3c70d5-af66-48ef-8dfc-f4341de4e1bd.docx

According to the documentation Open a directory the two methods should be equivalent as far as i understand it. But it creates a different path... Maybe the formulation is just not clear for me in the documentation, but for me its wrongly written.

getDir(name, mode)

Creates a new directory (or opens an existing directory) within your app's unique file system directory. This new directory appears inside the directory provided by getFilesDir().

Diego Frehner
  • 2,396
  • 1
  • 28
  • 35