Android上传图片到Firebase Storage报No content provider问题及解决
Android Firebase Storage上传本地图片No content provider错误解决方案
问题复现代码
最初用于上传图片到Firebase Storage的代码如下:
override fun click(url: String?) { if (url != null) { Glide.with(requireContext()).load(url).into(binding.userAvatar) val uri = Uri.parse(url) val storageRef = storage.reference val avatarRef = auth.currentUser?.let { storageRef.child(it.uid).child("avatar.png") } val uploadTask: UploadTask = avatarRef!!.putFile(uri) uploadTask.addOnCompleteListener { if (it.isSuccessful) { avatarRef.downloadUrl.addOnCompleteListener { url -> user.userAvatar = url.toString() Toast.makeText(context, "Upload image success!", Toast.LENGTH_SHORT).show() } } else { Toast.makeText(context, it.exception?.message, Toast.LENGTH_SHORT).show() it.exception?.message?.let { it1 -> Log.e(TAG, it1) } } } } }
报错信息
运行后抛出如下异常:
发生未知错误,请检查HTTP返回码及服务端响应的内部异常。 Code: -13000 HttpResult: 0 No content provider: /storage/emulated/0/Download/download.png java.io.FileNotFoundException: No content provider: /storage/emulated/0/Download/download.png at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1673) at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1503) at android.content.ContentResolver.openInputStream(ContentResolver.java:1187) at com.google.firebase.storage.UploadTask.<init>(UploadTask.java:137) at com.google.firebase.storage.StorageReference.putFile(StorageReference.java:241) at com.animals.snowy.profile.SetProfileFragment.click(SetProfileFragment.kt:87) at com.animals.snowy.util.GetImage.lambda$getOneImage$3$GetImage(GetImage.java:109) at com.animals.snowy.util.GetImage$$ExternalSyntheticLambda3.onClick(Unknown Source:6) at android.view.View.performClick(View.java:7125) at android.view.View.performClickInternal(View.java:7102) at android.view.View.access$3500(View.java:801) at android.view.View$PerformClick.run(View.java:27336) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
问题原因
传入的参数url是本地文件的绝对路径字符串,直接调用Uri.parse()生成的Uri缺少file://协议标识,Firebase Storage的putFile方法会默认把无协议的Uri当作Content Uri尝试通过ContentResolver读取,本地文件路径没有对应的Content Provider,因此抛出文件未找到异常。
修复方案
调整Uri生成逻辑,先将路径字符串转为File对象,再通过Uri.fromFile()生成带有正确file://协议的Uri,修复后代码如下:
override fun click(url: String?) { if (url != null) { Glide.with(requireContext()).load(url).into(binding.userAvatar) val file = File(url) val uriAvatar = Uri.fromFile(file) val storageRef = storage.reference val avatarRef = auth.currentUser?.let { storageRef.child(it.uid).child("avatar.png") } val uploadTask: UploadTask = avatarRef!!.putFile(uriAvatar) uploadTask.addOnCompleteListener { if (it.isSuccessful) { avatarRef.downloadUrl.addOnCompleteListener { url -> user.userAvatar = url.toString() Toast.makeText(context, "Upload image success!", Toast.LENGTH_SHORT).show() } } else { Toast.makeText(context, it.exception?.message, Toast.LENGTH_SHORT).show() it.exception?.message?.let { it1 -> Log.e(TAG, it1) } } } } }
内容的提问来源于stack exchange,提问作者Lộc Trần Phước
相关产品推荐
相关产品推荐

