Search code examples
androidbitmapandroid-contactsandroid-contentresolver

How come updating the contact photo doesn't work in this case?


Background

I want to change the photo of specific contacts in the address book.

The problem

I do some query of the contacts, as such:

final Cursor phonesCursor = context.getContentResolver()
            .query(ContactsContract.Data.CONTENT_URI,null,null,null,null);

and then, inside the loop that goes over the cursor, I tried to update the first contact's photo :

    if (phonesCursor != null) {
        while (phonesCursor.moveToNext()) {
            final int rawContactId = phonesCursor.getInt(phonesCursor
                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID));
            final String phoneNumber = phonesCursor.getString(phonesCursor
                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            String name = phonesCursor.getString(phonesCursor.getColumnIndex(Phone.DISPLAY_NAME));
            phonesMap.put(rawContactId, phoneNumber);
            Log.d("AppLog", "trying to set image for " + name);
            int photoRow = phonesCursor.getInt(phonesCursor.getColumnIndex(Phone._ID));
            phonesCursor.close();
            final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher);
            ByteArrayOutputStream streamy = new ByteArrayOutputStream();
            bitmap.compress(CompressFormat.PNG, 0, streamy);
            byte[] photo = streamy.toByteArray();

            final ContentValues values = new ContentValues();
            values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
            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);
            final int update = context.getContentResolver().update(ContactsContract.Data.CONTENT_URI, values, ContactsContract.Data._ID + " = " + photoRow, null);
            Log.d("AppLog", "update result:" + update);
            break;
        }
    }

Thing is, the result is that "update" returns "1", so it is supposed to be successful, but when I get to the contacts, I don't see this photo.

What I tried

I tried to use a batch instead (using ArrayList and getContentResolver().applyBatch ), but it also didn't work .

I also tried to change the update call, to identify the item I wish to change in a different way (using RAW_CONTACT_ID instead). It also didn't work.

The questions

  1. How come it occurs? What should I do to fix this?

  2. What's the best way to update multiple contacts with new photos?

  3. Is it possible to also get the photo of the contact using the query that I had, without an extra query ? I wish to do it in order to see for myself that the contact was different before.


Solution

  • OK, the correct field to use is "LOOKUP_KEY" :

    int lookupKeyIdx = phonesCursor.getColumnIndex(Phone.LOOKUP_KEY);
    final String lookupKey = phonesCursor.getString(lookupKeyIdx);
    ...
    final int update = context.getContentResolver().update(ContactsContract.Data.CONTENT_URI, values, Phone.LOOKUP_KEY + " = " + lookupKey , null);