今天在开发的过程中有这么一个需求,要下载PDF文件,下载完毕然后打开浏览,本以为很简单的事情,结果问题颇多,最终还是解决了,现在记录下来,分享一下,避免更多的人踩坑。
这是打开PDF的代码,Android6.0上测试很正常
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
startActivity(intent);
三星7.0系统直接就报错了,程序崩溃,提示么有权限,ok加上权限将URI获取方式改成:
Uri uri = FileProvider.getUriForFile(this, "xxx.xxx.xxx.fileprovider", file);
以为没有问题以为万事大吉了,现在不崩溃了,但是就是不能拉起这个隐式的Intent,调用没有任何的响应,也没有报错,
不妨在华为8.0上试一下,打不开,但是有提示了,提示无法访问此文件,请检查位置或网络,网上查了一圈,Intent的参数设置不对,正确的姿势应该是这样的
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
完整的解决步骤如下:
1.确保在ApplicationManifest.xml中声明了您的provider
<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>
2.创建 provider_paths 文件
通过这个文件来声明你的文件所存放的位置,不妨设置为path="."表示SD卡上的所有目录都可以存放
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
3. 通过隐式Intent打开PDF文件
关键是要设置FLAG_GRANT_READ_URI_PERMISSION和FLAG_ACTIVITY_CLEAR_TOP在同一时间。intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Uri pdf = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", file);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setDataAndType(pdf, "application/pdf");
try {
startActivity(pdfOpenintent);
} catch (ActivityNotFoundException e) {
// handle no application here....
}