0

I was recently playing around with some code that goes through my contacts and creates an identicon for any contact that does not have a photo set. For the most part this ended up working quite well but for some reason I have a handful of contacts that will not update. Log output says it is creating the photo. The update() returns 1 indicating 1 row was updated and stepping through the code for a contact that never seems to show the new photo looks good.

The fact that only a select few are not updating is what is really bugging me and I'm guessing there must be something I am doing wrong or missing here.

private void processContacts() {
    Cursor cursor = getContacts();
    Log.d(TAG, "Processing " + cursor.getCount() + " contacts");
    while(cursor.moveToNext()) {
        final long contactId = cursor.getLong(0);
        final String name = cursor.getString(1);
        if (!TextUtils.isEmpty(name)) {
            final Uri contactUri = ContentUris.withAppendedId(
                    ContactsContract.Contacts.CONTENT_URI,
                    contactId);
            if(ContactsContract.Contacts.openContactPhotoInputStream(getContentResolver(),
                    contactUri, true) == null) {
                Log.d(TAG, String.format("Creating identicon for %s", name));
                generateIdenticon(contactId, name);
            } else {
                Log.i(TAG, String.format("%s already has a contact photo", name));
            }
        }
    }
    cursor.close();
}

private Cursor getContacts() {
    Uri uri = ContactsContract.Contacts.CONTENT_URI;
    String[] projection = new String[] { ContactsContract.Contacts._ID,
            ContactsContract.Contacts.DISPLAY_NAME };
    String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
            + " COLLATE LOCALIZED ASC";

    return getContentResolver().query(uri, projection, null, null, sortOrder);
}

private void generateIdenticon(long contactId, String name) {
    if (!TextUtils.isEmpty(name)) {
        updateNotification(getString(R.string.identicons_creation_service_running_title),
                String.format(getString(R.string.identicons_creation_service_contact_summary),
                        name));
        final byte[] hash = Identicon.generateHash(name);
        final byte[] identicon = Identicon.generateIdenticonByteArray(hash);
        if (identicon == null) {
            Log.e(TAG, "generateIdenticon() - identicon for " + name + " is null!");
        } else {
            if (!setContactPhoto(getContentResolver(), identicon, contactId)) {
                Log.e(TAG, "Unable to save identicon for " + name);
            }
        }
    }
}

private boolean setContactPhoto(ContentResolver resolver, byte[] bytes, long personId) {
    ContentValues values = new ContentValues();
    int photoRow = -1;
    String where = ContactsContract.Data.RAW_CONTACT_ID + " == " +
            String.valueOf(personId) + " AND " + ContactsContract.Data.MIMETYPE + "=='" +
            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE + "'";
    Cursor cursor = resolver.query(
            ContactsContract.Data.CONTENT_URI,
            null,
            where,
            null,
            null);
    int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Data._ID);
    if(cursor.moveToFirst()){
        photoRow = cursor.getInt(idIdx);
    }
    cursor.close();

    values.put(ContactsContract.Data.RAW_CONTACT_ID, personId);
    values.put(ContactsContract.Data.IS_PRIMARY, 1);
    values.put(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
    values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bytes);
    values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);

    if (photoRow >= 0) {
        final int rowsUpdated = resolver.update(ContactsContract.Data.CONTENT_URI,
                values, ContactsContract.Data._ID + "=" + photoRow, null);
        return rowsUpdated >= 1;
    } else {
        final Uri uri = resolver.insert(ContactsContract.Data.CONTENT_URI, values);
        return uri != null && !TextUtils.isEmpty(uri.toString());
    }
}

All this is being done inside a background service and all my contacts are synced via google. One last thing to note is that these select contacts always return null when I call ContactsContract.Contacts.openContactPhotoInputStream() to see if a photo is available (even after I've attempted to update the photo).

Any help or insight about what may be going on is greatly appreciated.

clark
  • 507
  • 7
  • 14
  • 1
    Refer this one maybe helpful..http://stackoverflow.com/questions/18112272/how-to-update-contact-image-using-contact-provider-operation/18118617#18118617 – Aravin Oct 21 '13 at 17:53
  • I'm not using ContentProviderOperation(s) but refining my update to match the one in that example does yield better results. I have just a couple contacts now that are not showing an updated photo so this is a step in the right direction. Kudos. – clark Oct 21 '13 at 18:19
  • Did you finally find out why those select contacts refused to update? – Oladipo Olasemo May 23 '17 at 11:58

0 Answers0