Android Photo Picker Uri无法读取完整文件内容求助
解决Photo Picker Uri读取文件不完整的问题
你遇到的问题是从Photo Picker拿到Uri后,读取文件转成Base64只得到部分图片——解码后仅显示图片的四分之一,而完整图片应为正常全图。下面是具体的排查和解决方法:
可能的原因
- 你使用的
fileInputStream之前被读取过(比如有其他操作移动了流的读取指针),导致readAllBytes()只能读到剩余部分。 - 没有通过
ContentResolver正确获取Uri对应的输入流,而是直接操作文件路径(这种方式在Android 10+的沙箱机制下会出现权限或读取不完整的问题)。
解决步骤
1. 正确获取并读取流
用ContentResolver的openInputStream()获取Uri对应的流,同时用Kotlin的use函数自动管理流的关闭(避免资源泄漏),确保流从头开始读取:
// 替换成你的上下文对象,比如Activity或Application的context val context = this // 从Photo Picker的Intent中拿到的目标Uri val photoUri = intent.data context.contentResolver.openInputStream(photoUri)?.use { inputStream -> val fullFileBytes = inputStream.readAllBytes() val base64EncodedStr = Base64.getEncoder().encodeToString(fullFileBytes) println(base64EncodedStr) }
2. 验证读取的完整性
如果问题仍存在,可以先对比文件实际大小和读取到的字节数,确认是否真的读取不完整:
context.contentResolver.openInputStream(photoUri)?.use { inputStream -> // 查询文件在系统中的实际大小 val actualFileSize = context.contentResolver.query( photoUri, arrayOf(MediaStore.Images.Media.SIZE), null, null, null )?.use { cursor -> if (cursor.moveToFirst()) { cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE)) } else 0L } ?: 0L val readBytes = inputStream.readAllBytes() println("文件实际大小:$actualFileSize 字节,读取到的字节数:${readBytes.size} 字节") if (actualFileSize == readBytes.size.toLong()) { val base64EncodedStr = Base64.getEncoder().encodeToString(readBytes) println(base64EncodedStr) } else { println("读取不完整,实际大小与读取字节数不符") } }
3. 避免重复使用同一输入流
确保在调用readAllBytes()之前,没有对同一个fileInputStream执行过read()、skip()等操作——这些操作会移动流的读取指针,导致后续只能读取剩余内容。
内容的提问来源于stack exchange,提问作者Luca Strambeanu
相关产品推荐
相关产品推荐

