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

react-native-document-picker调用返回uri为undefined如何解决

问题根因

你代码里拿不到uri有三个核心错误:

  • DocumentPicker.pick()是异步Promise接口,你没有加await等待异步返回,直接访问返回值的uri属性,此时拿到的是未完成的Promise对象,自然不存在uri字段。
  • v3及以上版本的react-native-document-picker,pick方法默认返回选中文件的数组结构,哪怕只选单个文件,也需要取下标拿到具体文件对象,直接对返回数组取uri同样会得到undefined。
  • 额外注意:Android平台默认返回的是content://协议的临时共享uri,不是文件系统的绝对路径,直接传给PDF打开库大概率会报路径无权限/找不到文件,需要做路径转换。
修复步骤
  1. 给openFile方法加async声明,调用pick时加await等待结果返回,同时增加try/catch捕获用户取消选择的异常。
  2. 从返回的文件数组中取出第一个文件对象,再读取uri属性。
  3. 针对Android平台的content类型uri,用rn-fetch-blob的stat接口转换为真实的文件系统绝对路径;iOS平台返回的路径按需补全file://前缀适配PDF打开组件的要求。
  4. 补全两端的必要权限配置,避免路径访问被系统拦截。
修复后完整代码
import { StyleSheet, Text, View, Button, Platform } from 'react-native'
import React from 'react'
import DocumentPicker from 'react-native-document-picker'
import RNFetchBlob from 'rn-fetch-blob'
import Pdf from 'react-native-open-pdf';


const openPdfex = () => {

 const openFile = async () => {
    try {
      // 等待文件选择结果返回,copyTo配置可直接生成应用缓存目录下的可访问文件副本,规避权限问题
      const fileList = await DocumentPicker.pick({
        type: [DocumentPicker.types.allFiles],
        copyTo: 'cachesDirectory'
      });
      const selectedFile = fileList[0];
      
      let filePath = selectedFile.uri;
      // 安卓平台转换content协议uri为真实绝对路径
      if (Platform.OS === 'android' && filePath.startsWith('content://')) {
        const fileStat = await RNFetchBlob.fs.stat(filePath);
        filePath = fileStat.path;
      }
      // iOS平台补全file协议前缀
      if (Platform.OS === 'ios' && !filePath.startsWith('file://')) {
        filePath = `file://${filePath}`;
      }

      console.log("absolute path =====> ", filePath);
      // 拿到路径后直接调用PDF打开方法即可
      // Pdf.open(filePath);
    } catch (err) {
      // 用户主动取消选择不属于错误,单独处理
      if (DocumentPicker.isCancel(err)) {
        console.log('用户取消文件选择');
        return;
      }
      console.error('文件选择流程出错:', err);
    }
  }

 return (
    <View>
      <Text>openPdf</Text>
      <Button title='Open PDF' onPress={openFile}></Button>
    </View>
  )
}

export default openPdfex;
必要权限配置

Android端

在android/app/src/main/AndroidManifest.xml的<manifest>标签内添加以下权限,适配不同Android版本的存储访问规则:

<!-- Android12及以下读存储权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android13及以上细分媒体权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

iOS端

在ios/[你的项目名]/Info.plist中添加文档访问权限描述:

<key>NSDocumentsFolderUsageDescription</key>
<string>需要访问文档内容以打开PDF文件</string>

内容的提问来源于stack exchange,提问作者user18749224

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:39:20