通过Android中的PHOTO_FILE_ID将联系人的图像更改为大照片
问题内容:
这似乎适用于小图像:
ContentValues values = new ContentValues();
values.put(ContactsContract.Data.RAW_CONTACT_ID, id);
values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, photo);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
if (photoRow >= 0) {
context.getContentResolver().update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data._ID + " = " + photoRow, null);
} else {
context.getContentResolver().insert(ContactsContract.Data.CONTENT_URI, values);
}
从文档中我意识到,对于大图像,我需要设置PHOTO_FILE_ID,因此我可以替换:
ContactsContract.CommonDataKinds.Photo.PHOTO
与:
ContactsContract.CommonDataKinds.Photo.PHOTO_FILE_ID
但是,然后我需要提供一个PHOTO_FILE_ID而不是原始数据。我的问题:
- 如何保存照片(字节[])并获取PHOTO_FILE_ID?
- 如果已经有可用的照片(PHOTO不是PHOTO_FILE_ID)。我需要删除它才能看到大图像,还是要优先处理大图像?如果没有,如何删除?
问题答案:
您自己的答案会奏效,但效率不高,因为需要将照片编码为SQL查询并通过Android
IPC传输。这也使它受制于Android的IPC大小限制1MB(即,如果您的照片太大,则内容提供商操作将失败)。
设置(创建或覆盖)RawContact的(主)照片的最有效方法是使用openAssetFileDescriptor
和这样的
ContactsContract.RawContacts.DisplayPhoto
URI(例如,从Android文档复制的示例):
public void writeDisplayPhoto(long rawContactId, byte[] photo) {
Uri rawContactPhotoUri = Uri.withAppendedPath(
ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId),
RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
try {
AssetFileDescriptor fd =
getContentResolver().openAssetFileDescriptor(rawContactPhotoUri, "rw");
OutputStream os = fd.createOutputStream();
os.write(photo);
os.close();
fd.close();
} catch (IOException e) {
// Handle error cases.
}
}
这种方法的唯一缺点是,它总是创建/替换的主要照片RawContact
。如果RawContact还没有照片,它将添加一张。
不幸的是没有办法用openAssetFileDescriptor
了PHOTO_FILE_ID
,所以你不能覆盖使用这种方法的ID标识的特定照片。但是,在现实生活中,大多数联系人最多只能有一张照片,所以这并不是一个真正的限制。
这将自动Photo.PHOTO
使用大照片的缩略图更新列,并分配一个PHOTO_FILE_ID
。