Sunday, April 10, 2011

How to insert and update email addresses in Android contacts

Lately I've been working to insert an email address or update an already existing one, in an existing Android contact. The examples I found from the Internet mainly focus on creating a contact entry from scratch and insering it into the list of contacts. I had to find the correct steps by trial and error and it took me some time before get it working. I decided to write a short blog about this experience, hoping that it might be useful for others and save time.

Although there are alternative ways on how to insert and update an email address of an Android contact, I chose to work with ContentProviderOperation. This has the great advantage of applying many inserts and many updates in batch mode. 

Below I provide a complete example which works out of the box for it's purpose. The same approach should work for other fields, like the postal address as well.

Enjoy,
-Ali


/*
 * Copyright (C) 2011 Ali Chousein
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package com.apps.experiment;

import java.util.ArrayList;
import android.app.Activity;
import android.content.ContentProviderOperation;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;


public class Main extends Activity
{
  // For the sake of keeping the example simply, the query operation are done
  //   in onCreate. Normally query operations should NOT be done in onCreate, 
  //   but in a dedicated thread.
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // For performance reasons, normally you would define a projection over the columns you need.
    Cursor cur = managedQuery(ContactsContract.Data.CONTENT_URI, null, null, null, null);

    if ( (null == cur) || (!cur.moveToFirst()) )
      return;

    // For keeping the example simple we consider only the first contact. 
    //   Normally you would iterate over all contacts
    String raw_contact_id = cur.getString(cur.getColumnIndex(ContactsContract.Data.RAW_CONTACT_ID));

    String where = ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " + 
                   ContactsContract.Data.MIMETYPE + " = ? AND " + 
                   String.valueOf(ContactsContract.CommonDataKinds.Email.TYPE) + " = ?"; 
    String[] params = new String[]{raw_contact_id, 
                                   ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
                                   String.valueOf(ContactsContract.CommonDataKinds.Email.TYPE_HOME)}; 

    // For performance reasons, normally you would define a projection over the columns you need.
    Cursor emailCur = managedQuery(ContactsContract.Data.CONTENT_URI, null, where, params, null);

    ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();

    // If nothing has been found, no HOME email has been specified yet.
    // Insert the HOME email to the contact.
    if ( (null == emailCur) || (!emailCur.moveToFirst()) )
    {
      ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
        .withValue(ContactsContract.Data.RAW_CONTACT_ID, raw_contact_id)
        .withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
        .withValue(ContactsContract.CommonDataKinds.Email.DATA, "somebody@gmail.com")
        .withValue(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_HOME)
        .build());
    }
    else
    { // Otherwise update the existing HOME email address.
      ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
        .withSelection(where, params)
        .withValue(ContactsContract.CommonDataKinds.Email.DATA, "somebody@gmail.com")
        .build());
    }

    try
    {
      getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
    } 
    catch (Exception e) 
    {
      // Handle your exception here.
    }

  }
}


Other related blogs
Android contacts: CONTACT_ID vs RAW_CONTACT_ID
http://android-contact-id-vs-raw-contact-id.blogspot.com/


Geo-Filtered Assistant
http://geo-filtered-assistant.blogspot.com/

Support information sharing
To support free information sharing please visit one of our sponsors below.