使用ContentResolver获取本地图片宽高时Cursor崩溃的问题求助
解决MediaStore查询图片宽高时Cursor崩溃的问题
崩溃原因很明确:你调用query时传入的projection数组没有包含MediaStore.Images.Media.WIDTH字段,导致Cursor找不到该列,getColumnIndex返回-1,后续调用getInt(-1)就会触发IllegalStateException。
正确实现步骤
- 明确指定查询的投影字段:必须把需要获取的
_ID、WIDTH、HEIGHT等字段加入projection数组,MediaStore不会默认返回所有字段。 - 安全处理Cursor:避免强制非空,用
?.use自动关闭Cursor;优先用getColumnIndexOrThrow替代getColumnIndex,列不存在时会抛出明确异常,便于调试。
完整代码示例
// 定义需要查询的字段集合 val projection = arrayOf( MediaStore.Images.Media._ID, MediaStore.Images.Media.WIDTH, MediaStore.Images.Media.HEIGHT ) // 执行查询,安全处理Cursor空值 contentResolver.query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, // 目标集合URI projection, null, // 可选:添加过滤条件,比如筛选特定格式图片 null, null // 可选:排序规则 )?.use { cursor -> // 先判断Cursor是否有数据 if (cursor.moveToFirst()) { do { // 获取列索引(不存在会抛出异常,便于排查) val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID) val widthColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.WIDTH) val heightColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.HEIGHT) // 读取字段值 val imageId = cursor.getLong(idColumn) val imageWidth = cursor.getInt(widthColumn) val imageHeight = cursor.getInt(heightColumn) // 这里处理获取到的图片ID和宽高 } while (cursor.moveToNext()) } }
额外注意事项
- 权限:Android 13及以上需要申请
READ_MEDIA_IMAGES权限;Android 10-12需要READ_EXTERNAL_STORAGE权限,且需适配Scoped Storage规则。 - 兼容性:部分旧版系统中,部分图片可能没有
WIDTH/HEIGHT字段(比如损坏的图片),可以用getColumnIndex判断索引是否为-1,做容错处理。
内容的提问来源于stack exchange,提问作者Jacek Kwiecień
相关产品推荐
相关产品推荐

