Expo下载PDF后通过Linking打开黑屏问题排查求助
解决方案
问题根源
- 保存的文件名缺少
.pdf后缀,导致系统无法正确识别文件类型,部分PDF查看器无法解析内容引发黑屏 Linking.openURL无法为SAF(Storage Access Framework)的content://URI传递临时读写权限,目标应用无法读取文件内容downloadFile中调用ensureDirAsync未加await,可能导致目录未创建完成就开始下载
修复步骤
1. 安装依赖(处理SAF URI权限传递)
安装Expo的IntentLauncher库,用于正确启动Android Intent并传递权限:
expo install expo-intent-launcher
2. 修正代码中的问题点
导入IntentLauncher
在文件顶部添加导入:
import * as IntentLauncher from 'expo-intent-launcher';
修正下载目录创建逻辑
确保目录创建完成后再开始下载:
const downloadFile = async (fileUrl) => { if (Platform.OS == "android") { await ensureDirAsync(downloadPath); // 添加await等待目录创建完成 } let fileName = "history.pdf"; // 添加.pdf后缀,确保文件类型识别正确 const downloadResumable = FileSystem.createDownloadResumable( fileUrl, downloadPath + fileName, {} ); console.log(downloadPath); try { const { uri } = await downloadResumable.downloadAsync(); saveAndroidFile(uri, fileName); } catch (e) { console.error("download error:", e); } };
替换Linking.openURL为IntentLauncher
在saveAndroidFile中,用IntentLauncher启动PDF查看器并传递权限:
const saveAndroidFile = async (fileUri, fileName = "File") => { try { const fileString = await FileSystem.readAsStringAsync(fileUri, { encoding: FileSystem.EncodingType.Base64 }); if (local === "") { const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync(); if (!permissions.granted) { return; } await AsyncStorage.setItem("local", permissions.directoryUri); } try { await StorageAccessFramework.createFileAsync(local, fileName, "application/pdf") .then(async (uri) => { await FileSystem.writeAsStringAsync(uri, fileString, { encoding: FileSystem.EncodingType.Base64 }); // 替换Linking.openURL为IntentLauncher,传递临时权限 await IntentLauncher.startActivityAsync('android.intent.action.VIEW', { data: uri, flags: (1 << 29) | (1 << 30), // 授予临时读写权限 type: 'application/pdf', }); alert("Success!"); }) .catch((e) => { console.error("File creation error:", e); }); } catch (e) { throw new Error(e); } } catch (err) { console.error("Save file error:", err); } };
原理说明
- 文件名后缀:系统依赖文件扩展名识别类型,缺少
.pdf会导致部分查看器无法正确解析文件内容 - Intent权限传递:SAF的
content://URI属于应用私有权限,需要通过FLAG_GRANT_READ_URI_PERMISSION和FLAG_GRANT_WRITE_URI_PERMISSION将临时权限授予PDF查看器应用,Linking.openURL不会自动添加这些标志 - 异步等待目录创建:确保下载目录存在后再启动下载,避免因目录不存在导致下载失败
内容的提问来源于stack exchange,提问作者Matheus William
相关产品推荐
相关产品推荐

