如何获取联系人照片Bitmap?转换content URI时遇‘unimplemented’错误
解决联系人照片转Bitmap的"unimplemented"错误
问题原因
你碰到的Failed to create image decoder with message 'unimplemented'错误,核心是content://com.android.contacts/display_photo/这类URI属于系统封装的联系人照片资源,不能直接用BitmapFactory.decodeStream解析。此外你的代码还有两个明显问题:
- 同一个InputStream被连续两次调用
decodeStream,第一次读取后流指针已到末尾,第二次必然返回null - 没有处理联系人无自定义照片时的默认头像逻辑
修复代码
替换原照片读取逻辑,使用系统提供的专用接口处理联系人照片,同时补充默认头像的加载逻辑:
private fun getContactNumbers(): ArrayList<ArrayList<String>> { val contactsNumberMap = ArrayList<ArrayList<String>>() val phoneCursor: Cursor? = context.contentResolver.query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null ) if (phoneCursor != null && phoneCursor.count > 0) { val numberIndex = phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER) val nameIndex = phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) // 改用联系人ID获取照片,比直接读取PHOTO_URI更稳定 val contactIdIndex = phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID) while (phoneCursor.moveToNext()) { val number: String = phoneCursor.getString(numberIndex) val name: String = phoneCursor.getString(nameIndex) val contactId: Long = phoneCursor.getLong(contactIdIndex) val objectNameNumber = ArrayList<String>() objectNameNumber.add(name) objectNameNumber.add(number) // 处理联系人照片 var contactBitmap: Bitmap? = null val contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId) // 系统专用接口读取联系人照片流 context.contentResolver.openContactPhotoInputStream(contactUri)?.use { inputStream -> contactBitmap = BitmapFactory.decodeStream(inputStream) } // 无自定义照片时加载默认头像 if (contactBitmap == null) { contactBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.ic_default_contact) } // 可根据需求将contactBitmap加入数据结构,比如objectNameNumber.add(contactBitmap)(需调整结构类型) println("${name}的头像处理完成") if (!contactsNumberMap.contains(objectNameNumber)) { contactsNumberMap.add(objectNameNumber) } } phoneCursor.close() } return contactsNumberMap }
关键修复点
- 专用接口解析照片:
openContactPhotoInputStream是系统为联系人照片提供的适配接口,能正确解析display_photo类型的URI - 避免流重复读取:用
use关键字自动管理流的生命周期,确保只读取一次 - 默认头像兜底:当无自定义照片时,加载应用内的默认头像资源
- 改用Contact ID生成URI:相比直接读取PHOTO_URI,通过Contact ID拼接的URI格式更稳定,减少异常概率
额外注意事项
- 必须在AndroidManifest.xml中声明权限:
<uses-permission android:name="android.permission.READ_CONTACTS" /> - Android 6.0及以上版本需动态申请
READ_CONTACTS权限
内容的提问来源于stack exchange,提问作者Avadhesh Mourya
相关产品推荐
相关产品推荐

