java – 通过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);
}

docs我意识到,对于大图像,我需要设置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(主)照片的最有效的方法是使用openAssetFileDescriptorContactsContract.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没有照片,这将添加一个.

不幸的是,没有办法使用带有PHOTO_FILE_ID的openAssetFileDescriptor,因此您不能使用此方法覆盖其ID标识的特定照片.然而,在现实生活中,大多数联系人最多可能有一张照片,所以这不是一个真正的限制.

这将自动更新Photo.PHOTO列与大照片的缩略图,并分配一个PHOTO_FILE_ID.

相关文章

Android 如何解决dialog弹出时无法捕捉Activity的back事件 在...
Android实现自定义带文字和图片的Button 在Android开发中经常...
Android 关于长按back键退出应用程序的实现最近在做一个Andr...
android自带的时间选择器只能精确到分,但是对于某些应用要求...