Firebase Storage图片上传失败:java.io.FileNotFoundException: Not a whole file
Firebase Storage图片上传报错“Not a whole file”解决方案
问题概述
上传图片至Firebase Storage时持续触发java.io.FileNotFoundException: Not a whole file错误,目前临时返回空字符串跳过上传流程,相关代码及报错堆栈信息如下:
相关代码
private String upload_image_to_firestore_db(Uri imagem, String key, String nome_campo, int tamanho) throws FileNotFoundException { final StorageReference imageRef = storage_reference.child("imagens/"+ imagem.getLastPathSegment()); imageRef.putFile(imagem) //ERROR POINTS HERE .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { @Override public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { Task<Uri> downloadUrl = imageRef.getDownloadUrl(); downloadUrl.addOnSuccessListener(new OnSuccessListener<Uri>() { @Override public void onSuccess(Uri uri) { String imageReference = uri.toString(); if (nome_campo == Imagem_Capa){ reference.child("atividades").child(key).child(nome_campo).setValue(imageReference); }else if (imagensUrlTemp.size()!= tamanho){ imagensUrlTemp.add(imageReference); }else { reference.child("atividades").child(key).child(nome_campo).setValue(imagensUrlTemp); } } }); } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception exception) { Log.d("Upload:","Failed."); } }); return ""; }
报错堆栈
java.io.FileNotFoundException: Not a whole file at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1648) at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:1578) at com.google.firebase.storage.UploadTask.<init>(UploadTask.java:124) at com.google.firebase.storage.StorageReference.putFile(StorageReference.java:241) at com.example.azoresexperience.database.DataBaseHandlerFireBase.upload_image_to_firestore_db(DataBaseHandlerFireBase.java:197) at com.example.azoresexperience.database.DataBaseHandlerFireBase.addDataAtividades(DataBaseHandlerFireBase.java:183) at com.example.azoresexperience.database.DataBaseHandlerFireBase.adicionarAtividades(DataBaseHandlerFireBase.java:368) at com.example.azoresexperience.database.DataBaseHandlerFireBase.run(DataBaseHandlerFireBase.java:96) at com.example.azoresexperience.MainActivity$AsyncCaller.doInBackground(MainActivity.java:271) at com.example.azoresexperience.MainActivity$AsyncCaller.doInBackground(MainActivity.java:223) at android.os.AsyncTask$3.call(AsyncTask.java:394) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:923)
解决方法
这个错误核心是传入的Uri无法被ContentResolver识别为完整可读取的文件,可按以下步骤排查修复:
- 验证Uri有效性:检查Uri的来源(相机/相册/本地文件),确保生成流程正确,比如相机拍照后需确认文件已写入本地,相册选择的文件未被删除或移动。
- 适配Android权限与Uri规范:
- Android 7.0+需使用
FileProvider生成content://开头的Uri,避免直接暴露文件路径触发权限异常; - 对应版本申请存储权限:Android 13+申请
READ_MEDIA_IMAGES,低版本申请READ_EXTERNAL_STORAGE,并确保权限已授予。
- Android 7.0+需使用
- 替换上传方式:若Uri问题无法快速解决,可改用
InputStream上传:InputStream stream = getContentResolver().openInputStream(imagem); imageRef.putStream(stream) .addOnSuccessListener(taskSnapshot -> { // 原成功逻辑 }) .addOnFailureListener(e -> { Log.d("Upload:", "Failed: " + e.getMessage()); }); - 调整线程逻辑:
putFile本身是异步操作,建议将Uri的验证、权限检查放在主线程完成,再调用上传方法,避免后台线程中ContentResolver访问异常。
额外优化
当前代码中return ""的逻辑会丢失上传结果反馈,建议改用回调接口或返回Task对象,让上层业务能监听上传状态,避免逻辑断层。
内容的提问来源于stack exchange,提问作者Paulo Santos
相关产品推荐
相关产品推荐

