从设备/SD卡上传图片至Firebase Storage,统一存储路径问题
统一Firebase Storage中本地与SD卡图片的存储路径
我明白你要解决的问题:从本地设备和SD卡选择图片上传到Firebase Storage时,希望统一以/Photos/namefile.jpg的格式存储,而不是SD卡图片会带上冗余的设备路径(比如/Photos/storage/emulated/0/namefile.jpg)。
初始代码的问题
你的初始代码直接使用uri.getLastPathSegment()来获取文件名,但SD卡返回的Uri路径段会包含完整的设备存储路径,导致最终的Storage路径带上了多余的层级,无法达到统一格式的需求。
可行的解决方案(你更新后的代码解析)
你已经找到可以正常运行的代码,这里帮你拆解下逻辑,确保你理解每一步的作用:
final Uri uri = data.getData(); // 将Uri转为File对象,方便后续提取文件名 File file = new File(uri+""); // 通过分割字符串提取最终的纯文件名,这里的分割规则适配Uri转字符串后的路径分隔符编码 String [] segments = file.getName().split("[\\p{Punct}‘]2F"); // 构建统一的Storage路径:{uid}/Photos/纯文件名 StorageReference path = storeRef.child(uid).child("Photos").child(segments[segments.length-1]);
这段代码的核心是通过分割字符串,从带有冗余路径的文件名中提取出最后的纯文件名,这样不管是本地还是SD卡的图片,最终都会存储在{uid}/Photos/namefile.jpg的路径下,实现了格式统一。
额外优化建议
如果遇到content://开头的Uri(比如某些系统相册返回的非文件路径Uri),上面的分割方式可能会出问题,推荐使用DocumentFile来更稳妥地获取文件名:
final Uri uri = data.getData(); DocumentFile documentFile = DocumentFile.fromSingleUri(context, uri); if (documentFile != null && documentFile.exists()) { String fileName = documentFile.getName(); StorageReference path = storeRef.child(uid).child("Photos").child(fileName); // 执行上传逻辑 path.putFile(uri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() { @Override public void onComplete(@NonNull Task<UploadTask.TaskSnapshot> task) { if(task.isSuccessful()){ // 文件上传成功后的处理 } } }); }
这种方式不需要依赖字符串分割,直接通过系统API获取文件名,兼容性和稳定性更好。
内容的提问来源于stack exchange,提问作者Baranto
相关产品推荐
相关产品推荐

