Insert Contact (ContactsContract) via Intent with Image (Photo)

Bitmap bit = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); // your image

ArrayList<ContentValues> data = new ArrayList<ContentValues>();

ContentValues row = new ContentValues();
row.put(Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
row.put(ContactsContract.CommonDataKinds.Photo.PHOTO, bitmapToByteArray(bit));
data.add(row);

Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
intent.putParcelableArrayListExtra(Insert.DATA, data);

The accepted answer does not do what the question asked.

Please refer to @yeo100's answer which uses the ContactsContract.Intents.Insert.DATA (docs - somewhat obscure and hard to find :/), as contact photos are saved in the Data table under a specific mimetype:

Data.MIMETYPE -> ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE

That worked for me, and is much neater and easier to manage.


to help you, i found original documentation: http://java.llp2.dcc.ufmg.br/apiminer/docs/reference/android/provider/ContactsContract.RawContacts.DisplayPhoto.html

and read this: http://java.llp2.dcc.ufmg.br/apiminer/docs/reference/android/provider/ContactsContract.RawContacts.html

for me, a simple solution would be if your code works call:

startActivityForResult(inOrUp, CODE_INSERT_CONTACT);

Then in "onActivityResult" call "setDisplayPhotoByRawContactId.":

    /** @return true if picture was changed false otherwise. */
public boolean setDisplayPhotoByRawContactId(long rawContactId, Bitmap bmp) {
     ByteArrayOutputStream stream = new ByteArrayOutputStream();
     bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
     byte[] byteArray = stream.toByteArray();
     Uri pictureUri = Uri.withAppendedPath(ContentUris.withAppendedId(RawContacts.CONTENT_URI, 
             rawContactId), RawContacts.DisplayPhoto.CONTENT_DIRECTORY);
     try {
         AssetFileDescriptor afd = getContentResolver().openAssetFileDescriptor(pictureUri, "rw");
         OutputStream os = afd.createOutputStream();
         os.write(byteArray);
         os.close();
         afd.close();
         return true;
     } catch (IOException e) {
         e.printStackTrace();
     }
     return false;
 }

Normally, this code works from version 14 of the API. I had to do research on this topic.

You can get rawContactId as indicated in the documentation:

Uri rawContactUri = RawContacts.URI.buildUpon()
      .appendQueryParameter(RawContacts.ACCOUNT_NAME, accountName)
      .appendQueryParameter(RawContacts.ACCOUNT_TYPE, accountType)
      .build();
long rawContactId = ContentUris.parseId(rawContactUri);

I'm not sure but the documentation will help you. Sorry for my english.