Android Oreo系统中PDF文件无法打开的技术求助
Hey there, I’ve run into this exact issue before with Android Oreo—let’s break down what’s going on and fix it!
核心原因:Android 7.0+ 的文件 URI 限制
Starting from Android 7.0 (API 24, including Oreo 8.0/8.1), Google blocked direct use of file:// URIs to share files between apps. You have to use FileProvider to generate content:// URIs instead. This is why your code works on older versions but fails on Oreo.
Step 1: 注册 FileProvider 到 AndroidManifest.xml
Add this provider block inside your <application> tag:
<application ...> <!-- 注册 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> </application>
Note: If you’re using the old support library instead of androidx, replace androidx.core.content.FileProvider with android.support.v4.content.FileProvider.
Step 2: 创建 FileProvider 路径配置文件
Create a new directory res/xml in your project, then make a file named file_paths.xml with this content (adjust the path based on where your PDFs are stored):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 如果你PDF存在外部存储根目录,用这个 --> <external-path name="external_files" path="." /> <!-- 如果PDF在应用内部存储的files目录,用 <files-path name="internal_files" path="." /> --> <!-- 如果PDF在应用外部私有目录,用 <external-files-path name="app_external_files" path="." /> --> </paths>
Make sure the path points to the actual folder where your PDF files live. For example, if PDFs are in Documents/PDFs, set path="Documents/PDFs".
Step 3: 修改打开 PDF 的代码
Replace your old URI generation logic with FileProvider, and add the necessary permission flag:
doc_list.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // 假设你有一个保存PDF文件的列表,这里获取对应的File对象 File targetPdf = yourPdfFileList.get(position); // 生成content://格式的URI Uri pdfUri = FileProvider.getUriForFile( getApplicationContext(), getPackageName() + ".fileprovider", // 和Manifest里的authorities完全一致 targetPdf ); // 创建打开PDF的Intent Intent openPdfIntent = new Intent(Intent.ACTION_VIEW); openPdfIntent.setDataAndType(pdfUri, "application/pdf"); // 必须添加这个flag,授予外部应用读取文件的权限 openPdfIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 用createChooser启动,同时处理没有PDF阅读器的情况 try { startActivity(Intent.createChooser(openPdfIntent, "选择PDF查看器")); } catch (ActivityNotFoundException e) { Toast.makeText(getApplicationContext(), "请先安装PDF查看器应用", Toast.LENGTH_SHORT).show(); } } });
额外检查点
- Double-check that the
authoritiesvalue in Manifest matches what you use in code (getPackageName() + ".fileprovider"). - Ensure you’ve requested the
READ_EXTERNAL_STORAGEpermission at runtime (even if declared in Manifest—Android 6.0+ requires dynamic permission requests). - Verify that your
file_paths.xmlcorrectly targets the folder where your PDFs are stored.
That should fix the Oreo-specific PDF opening issue!
内容的提问来源于stack exchange,提问作者KKT

