android.os.FileUriExposeException:file:///storage/emulated/0/Download/FileNmae 通过 Intent.getData() 暴露在应用程序之外

问题描述 投票:0回答:1

我有一个下载完成后打开文件的功能:

fun openDownloadedFile(context: Context?, fileName: String) {
    val storageDirectory =
        Environment.getExternalStorageDirectory().toString() + STORAGE_DIRECTORY + "/${fileName}"
    val file = File(storageDirectory)

    if (file.exists()) {
        val downloadedFileUri = Uri.fromFile(file)
        val fileIntent = Intent(Intent.ACTION_VIEW)
        fileIntent.setDataAndType(downloadedFileUri, "application/vnd.android.package-archive")
        fileIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        
        context?.startActivity(fileIntent)
    }
}

我还在manifest.xml文件中声明了一个文件提供者

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="net.mytvplus.stbstore.file_provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider" />
</provider>

file_provider.xml:

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

下载完成后,应用程序崩溃,我在 logcat 中收到此消息:

android.os.FileUriExposedException: file:///storage/emulated/0/Download/FileNmae 暴露在应用程序之外 通过Intent.getData()

有什么帮助吗?

android kotlin
1个回答
0
投票

您应该使用 FileProvider 来防止此错误。根据android官方文档

https://developer.android.com/about/versions/nougat/android-7.0-changes#sharing-files

对于面向 Android 7.0 的应用程序,Android 框架强制执行 StrictMode API 策略,禁止在应用程序外部公开 file:// URI。如果包含文件 URI 的意图离开您的应用程序,则应用程序将失败并出现 FileUriExposedException 异常。

要在应用程序之间共享文件,您应该发送 content:// URI 并授予对该 URI 的临时访问权限。授予此权限的最简单方法是使用 FileProvider 类。

将提供者添加到您的清单文件中

  <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        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 xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>

最后,这是您如何在 Activity/Fragment 中实现

enter code here
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri Uri = FileProvider.getUriForFile(mcontext, 
BuildConfig.APPLICATION_ID + ".fileprovider", filename);

intent.setDataAndType(Uri,"application/vnd.android.package- 
archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mcontext.startActivity(intent);
© www.soinside.com 2019 - 2024. All rights reserved.