6

I have an app that generates video files, which can be placed in the internal storage or the SD card, and need to be opened by the user's preferred video player app via Intent.ACTION_VIEW. The app works as intended when targeting API 22, but I'm having issues when I attempt to upgrade it to 27.

The app generates different types of URI depending on storage location. For internal storage, it uses a file URI, like so:

file:///storage/emulated/0/VideoRecorder/2018_06_22_12_25_50.mp4

And for videos placed in the SD card, it uses a content URI:

content://com.android.externalstorage.documents/tree/72D1-C625%3Avideostest%2Ftest2/document/72D1-C625%3Avideostest%2Ftest2%2F2018_06_22_12_41_27.mp4

Nougat doesn't like file:// URIs, so I used a FileProvider (code below) to fix that, converting the file URI into a content URI that other apps can open with ACTION_VIEW. I thought the SD card URI wouldn't need any changes, because it's already a content URI, but it seems that only the default Photos app can open that URI with a ACTION_VIEW intent, whereas user-installed apps like VLC Player can't, failing with the following exception:

java.lang.SecurityException: Permission Denial: reading com.android.externalstorage.ExternalStorageProvider uri content://com.android.externalstorage.documents/tree/72D1-C625:videostest/test2/document/72D1-C625:videostest/test2/2018_06_22_12_27_45.mp4 from pid=7809, uid=10022 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()

Having examined the URI that the FileProvider generates, I think I understand the problem. It generates a content URI that's in an entirely different format than the content URI I have for the SD card video:

content://io.github.androidtests.videorecorder.videosfileprovider/external_files/VideoRecorder/2018_06_22_12_25_50.mp4

My question is, do the SD card videos need to be shared via FileProvider as well? How do I do that, seeing as I only have a content URI, not a File, and FileProvider seems specifically designed to convert Files into URIs?

EDIT: After testing some more video player apps, some of them seem to be able to use the content URI, just the same as the Photos app. Is this just a case of some apps not supporting content URIs yet?

Code:

Uri uri = adapter.mDataset.get(position).videoUri;

if (uri.toString().contains("file://")) {
    try {
        ParcelFileDescriptor pFD = ctx.getContentResolver().openFileDescriptor(uri, "r");
        String truePath = Utils.getFdPath(pFD);
        uri = FileProvider.getUriForFile(ctx, "io.github.androidtests.videorecorder.videosfileprovider", new File(truePath));
    } catch (FileNotFoundException e) {
        StaticMethodsAndValues.launchFabricException("RecyclerViewFragment caught FileNotFoundException when opening video.", e);
        return;
    }
}

Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setDataAndType(uri, "video/mp4");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
    ctx.startActivity(intent);
}
catch (ActivityNotFoundException e) {
    Toast.makeText(mContext.get(), mContext.get().getString(R.string.toast_no_video_player_found), Toast.LENGTH_LONG).show();
    StaticMethodsAndValues.launchFabricException("Device does not have app to handle intent action.VIEW for video/mp4.", e);
}

Provider manifest definition:

<provider
    android:name=".VideosFileProvider"
    android:authorities="io.github.androidtests.videorecorder.videosfileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths"/>
</provider>

Provider paths:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>
PM4
  • 624
  • 1
  • 5
  • 18
  • Hi @PM4 I Believe this is a very important question, and it's strange why there is no answer for it. I have also a similar question [here](https://stackoverflow.com/questions/68168717/how-to-open-a-file-uri-that-is-taken-from-action-create-document-via-intent-acti). Did you find the solution? – SoSa Jun 29 '21 at 10:35
  • Afraid not. I had to discard the intent approach, and add a video player so the app can play its own generated videos. – PM4 Jun 29 '21 at 14:14

0 Answers0