我想要的只是在我的外部下载目录中打开一个 pdf 文件。
我使用这段代码打开该文件,并且它曾经工作正常。
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
+ File.separator + filename);
Uri path = Uri.fromFile(file);
Intent pdfOpenintent = new Intent(Intent.ACTION_VIEW);
pdfOpenintent.setDataAndType(path, "application/" + getExtension(filename));
pdfOpenintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
CourseModulesActivity.this.startActivity(pdfOpenintent);
} catch (ActivityNotFoundException e) {
pdfOpenintent.setType("application/*");
startActivity(Intent.createChooser(pdfOpenintent, "No Application found to open File - " + filename));
}
Run Code Online (Sandbox Code Playgroud)
现在在 android N(API 24+) 中,它崩溃了android.os.FileUriExposedException
我按照链接 - /sf/answers/2720062831/和https://developer.android.com/training/secure-file-sharing/share-file.html#ShareFile将我的代码转换为此-
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
+ File.separator + filename);
Uri path = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file);
Intent pdfOpenintent = new Intent(Intent.ACTION_VIEW);
pdfOpenintent.setData(path);
pdfOpenintent.setType("application/" + getExtension(filename));
pdfOpenintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pdfOpenintent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
try {
CourseModulesActivity.this.startActivity(pdfOpenintent);
} catch (ActivityNotFoundException e) {
pdfOpenintent.setType("application/*");
startActivity(Intent.createChooser(pdfOpenintent, "No Application found to open File - " + filename));
}
Run Code Online (Sandbox Code Playgroud)
并将提供者 xml 添加为 -
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Run Code Online (Sandbox Code Playgroud)
并表现为 -
<manifest...>
....
<application...>
....
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
....
</application>
Run Code Online (Sandbox Code Playgroud)
因此,现在应用程序不会在 N 上崩溃,但 pdf 应用程序无法打开该文件。
在这个方向有什么帮助吗?
我使用这段代码打开该文件,并且它曾经工作正常。
该代码中至少有两个错误:
"application/" + getExtension(filename)不是用于查找文件 MIME 类型的适当算法,因为并非所有 MIME 类型都以application/(例如image/jpeg, text/plain)开头。使用MimeTypeMap。
setType()清除之前在 上设置的数据Intent,因此您Intent没有Uri。
另外,不要使用串联来构建文件路径,因为您的代码无法处理有人决定DIRECTORY_DOWNLOADS以/. 代替:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
+ File.separator + filename);
Run Code Online (Sandbox Code Playgroud)
和:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fiename);
Run Code Online (Sandbox Code Playgroud)
但 pdf 应用程序无法打开该文件
Uri您的 中没有Intent,因为您的第二个代码片段包含与第一个代码片段相同的错误。用于同时setDataAndType()设置MIME 类型和 MIME 类型。Uri或者,只需使用setData()并删除setType(),如FileProvider将用于MimeTypeMap确定 MIME 类型一样。
FWIW,此示例应用程序演示了如何FileProvider向 PDF 查看器提供 PDF 文件。
| 归档时间: |
|
| 查看次数: |
4280 次 |
| 最近记录: |