You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo保存Base64 PDF至缓存目录打开时Intent报错求助

解决Expo中打开缓存目录PDF文件的Intent错误

问题场景

我有Base64格式的PDF字符串,出于一次性查看需求,想保存到缓存目录后用系统默认PDF阅读器打开。但用Expo开发时,调用Linking.openURL打开文件时出现Android Intent相关错误:

[Error: Could not open URL 'file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf': file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf exposed beyond app through Intent.getData()]

当前使用的实现代码:

async function saveAndOpenFile(fileName: string, content: string) {
    try {
        let directoryUri = FileSystem.cacheDirectory + fileName;
        console.log("D", directoryUri);

        const writed = await FileSystem.writeAsStringAsync(directoryUri, content, { encoding: FileSystem.EncodingType.Base64 });
        console.log("W", writed);

        await Linking.openURL(directoryUri);
    } catch (error) {
        Alert.alert("Ocorreu um erro", "Não foi possível abrir o documento");
        console.log(error);
    }
}

控制台输出:

LOG  D file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf
 LOG  W null
 LOG  [Error: Could not open URL 'file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf': file:///data/user/0/host.exp.exponent/cache/Despacho%20-%2000043651620108260142.pdf exposed beyond app through Intent.getData()]

错误原因

Android系统有安全限制,不允许直接通过file:// URI将应用私有缓存目录内的文件暴露给其他应用,这就是触发上述Intent错误的核心原因。iOS没有这个限制,但为了跨平台统一兼容,建议用同一方案处理。

解决方案

使用Expo提供的FileSystem.getContentUriAsync方法获取文件的安全访问URI:该方法会根据平台自动返回合适的URI格式——Android返回content://开头的内容URI(通过系统内容提供者实现安全共享),iOS返回原file:// URI。

修改后的代码:

import { FileSystem, Linking, Alert } from 'expo';

async function saveAndOpenFile(fileName: string, content: string) {
    try {
        const fileUri = `${FileSystem.cacheDirectory}${fileName}`;
        console.log("文件路径", fileUri);

        // 写入Base64格式的PDF内容到缓存目录
        await FileSystem.writeAsStringAsync(fileUri, content, { 
            encoding: FileSystem.EncodingType.Base64 
        });
        console.log("文件写入完成");

        // 获取可安全分享给其他应用的内容URI
        const contentUri = await FileSystem.getContentUriAsync(fileUri);
        console.log("内容URI", contentUri);

        // 通过安全URI打开文件
        await Linking.openURL(contentUri);
    } catch (error) {
        Alert.alert("发生错误", "无法打开文档");
        console.error("错误详情:", error);
    }
}

注意事项

  • Expo项目默认已包含expo-file-system模块,若为裸React Native项目,需额外安装并配置该模块。
  • 该方案同时兼容Android和iOS平台,无需单独写平台判断逻辑。

内容的提问来源于stack exchange,提问作者Lucas Gardini Dias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 18:45:29