Android 11 (R) file path access

HB. picture HB. · Feb 23, 2020 · Viewed 16k times · Source

According to the docs file path access is granted in Android R:

Starting in Android 11, apps that have the READ_EXTERNAL_STORAGE permission can read a device's media files using direct file paths and native libraries. This new capability allows your app to work more smoothly with third-party media libraries.

The problem is that I can't get the file path from MediaStore, so how are we supposed to read a file path that we can't access/retrieve? Is there a way, I'm not aware of, that we can get the file path from MediaStore?


Furthermore, the docs say the following:

All Files Access

Some apps have a core use case that requires broad file access, such as file management or backup & restore operations. They can get All Files Access by doing the following:

  1. Declare the MANAGE_EXTERNAL_STORAGE permission.
  2. Direct users to a system settings page where they can enable the Allow access to manage all files option for your app.

This permission grants the following:

  • Read access and write access to all files within shared storage.
  • Access to the contents of the MediaStore.Files table.

But I do not need all file access, I only want the user to select a video from MediaStore and pass the file path to FFmpeg(it requires a file path). I know that I can no longer use the _data column to retrieve a file path.


Please note:

  • I know a Uri is returned from MediaStore and does not point to a file.
  • I know that I can copy the file to my application directory and pass that to FFmpeg, but I could do that before Android R.
  • I can not pass FileDescriptor to FFmpeg and I can not use /proc/self/fd/ (I get /proc/7828/fd/70: Permission denied when selecting a file from the SD Card), have a look at this issue.

So what am I supposed to do, am I missing something? What was meant with can read a device's media files using direct file paths and native libraries?

Answer

HB. picture HB. · Mar 29, 2020

After asking a question on issuetracker, I've come to the following conclusions:

  • On Android R, the File restrictions that were added in Android Q is removed. So we can once again access File objects.
  • If you are targeting Android 10 > and you want to access/use file paths, you will have to add/keep the following in your manifest:

    android:requestLegacyExternalStorage="true"
    

    This is to ensure that file paths are working on Android 10(Q). On Android R this attribute will be ignored.

  • Don't use DATA column for inserting or updating into Media Store, use DISPLAY_NAME and RELATIVE_PATH, here is an example:

    ContentValues valuesvideos;
    valuesvideos = new ContentValues();
    valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/" + "YourFolder");
    valuesvideos.put(MediaStore.Video.Media.TITLE, "SomeName");
    valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, "SomeName");
    valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
    valuesvideos.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
    valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
    valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
    ContentResolver resolver = getContentResolver();
    Uri collection = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
    Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
    
  • You can no longer use the ACTION_OPEN_DOCUMENT_TREE or the ACTION_OPEN_DOCUMENT intent action to request that the user select individual files from Android/data/,Android/obb/and all sub-directories.

  • It is recommended to only use File objects when you need to perform "seeking", like when using FFmpeg, for example.
  • You can only use the data column to access files that are on the disk. You should handle I/O Exceptions accordingly.

If you want to access a File or want a file path from a Uri that was returned from MediaStore, I've created a library that handles all the exceptions you might get. This includes all files on the disk, internal and removable disk. When selecting a File from Dropbox, for example, the File will be copied to your applications directory where you have full access, the copied file path will then be returned.