我有一个下载完成后打开文件的功能:
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()
有什么帮助吗?
您应该使用 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);