SVM*_*SVM 5 android uri android-fileprovider android-7.0-nougat
我有一个生成视频文件的应用程序,它可以放在内部存储或 SD 卡中,需要通过 Intent.ACTION_VIEW 由用户首选的视频播放器应用程序打开。该应用程序在面向 API 22 时按预期工作,但是当我尝试将其升级到 27 时遇到了问题。
该应用程序根据存储位置生成不同类型的 URI。对于内部存储,它使用文件 URI,如下所示:
file:///storage/emulated/0/VideoRecorder/2018_06_22_12_25_50.mp4
Run Code Online (Sandbox Code Playgroud)
对于放置在 SD 卡中的视频,它使用内容 URI:
content://com.android.externalstorage.documents/tree/72D1-C625%3Avideostest%2Ftest2/document/72D1-C625%3Avideostest%2Ftest2%2F2018_06_22_12_41_27.mp4
Run Code Online (Sandbox Code Playgroud)
Nougat 不喜欢 file:// URI,所以我使用 FileProvider(下面的代码)来解决这个问题,将文件 URI 转换为其他应用程序可以使用 ACTION_VIEW 打开的内容 URI。我认为 SD 卡 URI 不需要任何更改,因为它已经是内容 URI,但似乎只有默认照片应用程序可以使用 ACTION_VIEW 意图打开该 URI,而用户安装的应用程序(如 VLC Player)则不能,失败,但出现以下异常:
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()
Run Code Online (Sandbox Code Playgroud)
检查了 FileProvider 生成的 URI 后,我想我明白了这个问题。它生成的内容 URI 的格式与我用于 SD 卡视频的内容 URI 的格式完全不同:
content://io.github.androidtests.videorecorder.videosfileprovider/external_files/VideoRecorder/2018_06_22_12_25_50.mp4
Run Code Online (Sandbox Code Playgroud)
我的问题是,SD 卡视频是否也需要通过 FileProvider 共享?我该怎么做,因为我只有内容 URI,没有文件,而且 FileProvider 似乎专门设计用于将文件转换为 URI?
编辑:在测试了更多视频播放器应用程序之后,其中一些似乎能够使用内容 URI,就像照片应用程序一样。这只是一些应用程序不支持内容 URI 的情况吗?
代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
提供者清单定义:
<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>
Run Code Online (Sandbox Code Playgroud)
提供者路径:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
450 次 |
| 最近记录: |