I'm trying to update contact images via the ContentProvider
in my app. This works nearly always (I use this method for about 4 years in a production app, with ~50000 users and 1M downloads). I nearly never have problems, but it seems like the function is not bullet proof. It fails on one users device repeatedly and I don't know why.
What I do
I simply have bitmap and try to save if for a known contact id. If the contact already has an image, I replace it, otherwise I add the image.
Result and Quesiton
The contact image is not updated on one users device. The log says, the failing contact does not have an image yet. That's fine, so I just create a new one. The function returns an Uri
but this one is null, so saving the image failed. Why? Any ideas?
Log info:
Contact image set - updated: -1, newUri: NULL, old photoId: -1
Device info:
- other contacts do work, only a handful of contacts fail
- the device has plenty of space left, so this can't be the source either
- user only uses google contacts and no other service (like outlook or similar, so no read only contacts or similar)
Code
// the id of the contact
long contactRawId = ...;
// 1) get bitmap
Bitmap bitmap = ...;
// 2) Convert Bitmap to byte
byte[] photo =
// 3) save or update contact picture via content provider
ContentValues values = new ContentValues();
int photoId = -1;
String where = ContactsContract.Data.RAW_CONTACT_ID + " == " +
contactRawId + " AND " + ContactsContract.Contacts.Data.MIMETYPE + "=='" +
ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
Cursor cursor = MainApp.get().getContentResolver().query(
ContactsContract.Data.CONTENT_URI,
null,
where,
null,
null);
int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
if (cursor.moveToFirst()) {
photoId = cursor.getInt(idIdx);
}
cursor.close();
values.put(ContactsContract.Data.RAW_CONTACT_ID, contactRawId);
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);
int updated = -1;
Uri newUri = null;
if (photoId >= 0) {
updated = MainApp.get().getContentResolver().update(
ContactsContract.Data.CONTENT_URI,
values,
ContactsContract.Data._ID + " = " + photoId, null);
} else {
newUri = MainApp.get().getContentResolver().insert(
ContactsContract.Data.CONTENT_URI,
values);
}
L.d("Contact image set - updated: %d, newUri: %s, old photoId: %d", updated, newUri, photoId);
Observations
- one guy with this problem had a rooted OnePlus 3t running Nougat 7.1.1
- in the meantime he cleared the app data and now all contacts are working