Android如何从MediaStore生成的Uri获取图片输入流?
Android MediaStore Uri 获取输入流问题解决
场景与需求
通过MediaStore创建图片并调用相机拍照保存,代码如下:
val values = ContentValues(2) values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM) picUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values) Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent -> takePictureIntent.resolveActivity(packageManager)?.also { takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, picUri ) startActivityForResult(takePictureIntent, CAMERA_CAPTURE) } }
后续需要在自定义WebViewClient的shouldInterceptRequest()方法中,将该图片内容传入WebResourceResponse,这需要获取图片的输入流来执行return WebResourceResponse("image/jpeg", "utf-8", inputStream)。
已知图片路径为/external/images/media/40,需从content://external/images/media/40这类Uri获取输入流,或通过MediaStore定位到该图片。
尝试与错误
尝试通过拼接Uri字符串获取输入流,代码如下:
val uriString = "content:/" + path //结果为content://external/images/media/40 val uri = Uri.parse(uriString) val inputStream = getContentResolver().openInputStream(uri); if(inputStream==null) return WebResourceResponse("image/jpeg", "utf-8", ByteArrayInputStream(byteArrayOf()))//返回空图片(404会触发onReceivedHttpError) return WebResourceResponse("image/jpeg", "utf-8", inputStream)
Logcat出现以下错误:
Failed to find provider info for external
Client raised exception in shouldInterceptRequest. Re-throwing on UI thread.
问题排查与解决
对比日志输出发现Uri格式差异:
- 拼接得到的
uriString输出:content://external/images/media/47 - 解析后
uri!!.path!!输出:/images/media/47 - 原始创建的
picUri.path输出:/external/images/media/47 - 原始创建的
picUri.toString()输出:content://media/external/images/media/47
问题根源是拼接的Uri缺少**media/**授权部分,正确的Uri格式应为content://media/external/images/media/xxx,补充该部分后即可正常获取输入流。
经验总结
Android的Uri并非简单的协议+路径结构,而是包含协议、授权段(可理解为隐藏内容)和路径三部分,后续处理Uri时直接使用uri.toString()即可避免格式错误。
内容的提问来源于stack exchange,提问作者fpierrat
相关产品推荐
相关产品推荐

