在 ContactsContract 中更新照片的功能
Posted
技术标签:
【中文标题】在 ContactsContract 中更新照片的功能【英文标题】:Function to update a photo in ContactsContract 【发布时间】:2018-05-19 08:49:19 【问题描述】:我尝试使用获取联系人 id 和图片 uri 的函数更新 ContactsContract 中的照片,但它似乎不起作用(并且我的函数返回 true
)。
我真的不明白,因为代码看起来不错。
当联系人已经有照片时,它似乎正在工作......
这是我的功能:
boolean updatePhoto(String idStr, String uri)
if (uri != null)
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
File imgFile = new File(uri.replace("file://", ""));
if (imgFile.exists())
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ByteArrayOutputStream stream = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data.CONTACT_ID + " = ?" + " AND " + ContactsContract.Data.MIMETYPE + "=?",
new String[]idStr, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, stream.toByteArray())
.build());
try
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
catch(Exception e)
e.printStackTrace();
return false;
return true;
【问题讨论】:
【参考方案1】:您的代码仅在联系人已有照片时才有效,因为您使用的是ContentProviderOperation.newUpdate
,如果联系人没有照片,您将需要使用ContentProviderOperation.newInsert
。
您需要先查询该联系人是否有照片,然后更新/插入新照片:
private boolean hasPhoto(long contactId)
Uri uri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
InputStream input = Contacts.openContactPhotoInputStream(getContentResolver(), uri);
if (input == null)
return false;
Bitmap photo = BitmapFactory.decodeStream(input);
return (photo != null);
private long getRawId(long contactId)
String selection = RawContacts.CONTACT_ID + "='" + contactId + "'";
Cursor cur = contentResolver.query(RawContacts.CONTENT_URI, new String[] RawContacts._ID , selection, null, null);
try
if (cur.moveToNext())
return cur.getLong(0);
finally
cur.close();
return 0;
private boolean updatePhoto(long contactId, String uri)
if (uri == null)
// do nothing?
return false;
ContentProviderOperation.Builder builder;
if (hasPhoto(contactId))
builder = ContentProviderOperation.newUpdate(Data.CONTENT_URI);
builder.withSelection(Data.CONTACT_ID + " = ?" + " AND " + Data.MIMETYPE + "=?",
new String[] String.valueOf(contactId), Photo.CONTENT_ITEM_TYPE);
else
long rawId = getRawId(contactId);
builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
builder.withValue(Data.RAW_CONTACT_ID, rawId);
builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
builder.withValue(Data.IS_SUPER_PRIMARY, 1);
builder.withValue(Data.IS_PRIMARY, 1);
byte[] photo = getPhotoAsByteArray(uri); // to simplify the answer's code
builder.withValue(Photo.PHOTO, photo);
try
ArrayList<ContentProviderOperation> ops = new ArrayList<>();
ops.add(builder.build());
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
catch(Exception e)
e.printStackTrace();
return false;
return true;
【讨论】:
谢谢,但我也有同样的问题。当我的联系人没有照片时,它不起作用。当联系人有照片时,它就可以工作。 我还没有测试 hasPhoto 方法,它是否适合你,它是否进入 newInsert 子句? hasPhoto() 方法工作正常,因此它进入了 newInsert 子句。 当然...您不能将Data
行添加到Contact
,您需要指定将包含该数据行的RawContact
- 联系人是一个聚合或多个 RawContact,一个 RawContact 是一个或多个 Data 行的聚合
我找到了解决方案:我不必使用 builder.withValue(Data.CONTACT_ID, contactId);以上是关于在 ContactsContract 中更新照片的功能的主要内容,如果未能解决你的问题,请参考以下文章
获取与 facebook for android 同步的联系人照片
在 Kotlin 中查询 Androids ContactsContract