This seems to work for small images:
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);
}
From the docs I realise that for large images I need to set the PHOTO_FILE_ID, so I can replace:
ContactsContract.CommonDataKinds.Photo.PHOTO
with:
ContactsContract.CommonDataKinds.Photo.PHOTO_FILE_ID
However, then I need to supply a PHOTO_FILE_ID rather than raw data. My question:
- How do I save the photo (byte []) and get a PHOTO_FILE_ID?
- If there is already a photo available (PHOTO not PHOTO_FILE_ID). Do I need to delete it for the big image to be seen or does the big image take precedence, if not, how do I delete it?
Your own answer will work, but it's not very efficient because the photo needs to be encoded into an SQL query and piped through Android IPC. That also makes it a subject to Android's IPC size limit of 1MB (i.e. if your photo is too large the content provider operation will fail).
The most efficient way to set (create or override) a RawContact's (primary) photo is by using
openAssetFileDescriptor
and a ContactsContract.RawContacts.DisplayPhoto URI like so (example copied from Android docs):The only drawback of this approach is that it always creates/replaces the primary photo of the
RawContact
. If the RawContact doesn't have a photo yet this will add one.Unfortunately there is no way to use
openAssetFileDescriptor
with aPHOTO_FILE_ID
, so you can't override a specific photo identified by its ID using this method. However, in real life most contacts probably have at most one photo, so that's not a real limitation.This will automatically update the
Photo.PHOTO
column with a thumbnail of the large photo and assign aPHOTO_FILE_ID
.The PHOTO_FILE_ID is the ID not of a file (confusingly) but of a row in the database which contains your raw photo data. According to the docs I've looked at you can actually avoid using it (from the docs) :
Under PHOTO_FILE_ID
and Under PHOTO_ID (which is guaranteed populated if
PHOTO_FILE_ID
exists)This implies that if you just use
PHOTO_URI
you will get the same resulting image as if you made the method openDisplayPhoto. It also suggests that the URI methods are better compatible with 3rd part directories so are probably preferable to work withFinally was able to solve it with:
You can get the contact photo uri without using ContactsContract.CommonDataKinds.Email.PHOTO_URI this way: Read Full Answer here More
Where! to get Contact URI as you said try this:
To get the conatct id using the phone number use the following code:
}
and use the contact id obtained to get the contatc photo URI. Use the following code for getting photo URI:
Please let me know if this does not answer your question