我想要的只是在我的外部下载目录中打开一个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));
}
现在在android N(API 24)中,它崩溃说android.os.FileUriExposedException
我按照链接 – https://stackoverflow.com/a/38858040/4788557和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));
}
并添加提供者xml为 –
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
并表现为 –
<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>
所以,现在应用程序不会在N上崩溃,但pdf应用程序无法打开该文件.这个方向有什么帮助吗?
最佳答案
I used this code to open the file, and it used to work fine.
该代码中至少有两个错误:
>“application /”getExtension(filename)不是用于查找文件的MIME类型的合适算法,因为并非所有MIME类型都以application /开头(例如,image / jpeg,text / plain).使用MimeTypeMap.
> setType()
clears the data previously set on the Intent
,所以你的意图没有Uri.
另外,不要使用串联来构建文件路径,因为你的代码不能处理有人决定让DIRECTORY_DOWNLOADS以/结尾的情况.更换:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
+ File.separator + filename);
有:
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fiename);
but the pdf applications are unable to open the file
您的Intent中没有Uri,因为您的第二个代码段包含与第一个代码段相同的错误.使用setDataAndType()一次设置Uri和MIME类型.或者,只需使用setData()并删除setType(),因为FileProvider将使用MimeTypeMap来确定MIME类型.
FWIW,this sample app演示了如何使用FileProvider将PDF文件提供给PDF查看器.