React Native Expo Android端读取图片转Base64报错求助
Android端无法读取ImagePicker缓存文件转Base64的原因及解决方案
问题原因
Android系统的沙箱权限机制限制:Expo ImagePicker生成的编辑后图片会存放在自身的私有缓存目录(file:///data/user/0/host.exp.exponent/cache/ImagePicker/...),而Expo FileSystem模块默认没有权限直接访问其他模块的私有沙箱目录,因此触发"isn't readable"错误。iOS的沙箱权限逻辑不同,所以该流程可以正常执行。
解决方案
方案1:直接通过ImagePicker获取Base64(推荐)
修改launchImageLibraryAsync的配置参数,让ImagePicker直接返回Base64字符串,无需手动读取文件:
const pickImage = async () => { let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (permissionResult.granted === false) { alert("Permission to access camera roll is required!"); return; } let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsEditing: true, aspect: [4, 3], quality: 1, base64: true // 开启Base64返回 }); if (!result.cancelled) { setImage(result.uri); // 直接使用返回的base64字段,如需可拼接data URI前缀 const base64Image = `data:image/jpeg;base64,${result.base64}`; } }
方案2:复制文件到FileSystem可访问目录再读取
如果必须手动读取文件,先将ImagePicker的缓存文件复制到App自身的私有目录(FileSystem.documentDirectory),再读取转Base64:
import * as FileSystem from 'expo-file-system'; const pickImage = async () => { let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (permissionResult.granted === false) { alert("Permission to access camera roll is required!"); return; } let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.All, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.cancelled) { // 复制到App私有目录 const targetPath = `${FileSystem.documentDirectory}selected-image-${Date.now()}.jpeg`; await FileSystem.copyAsync({ from: result.uri, to: targetPath }); // 读取转Base64 const base64_image = await FileSystem.readAsStringAsync(targetPath, { encoding: 'base64' }); setImage(result.uri); } }
内容的提问来源于stack exchange,提问作者HousamKak
相关产品推荐
相关产品推荐

