Android Tutorials
Working With Android Contacts
Accessing Data With Android Cursors
Creating Lists Using The Android ListActivity
Android 9 Patch Scaled PNG Image Guide
Working With Images In Android
Exploring Android LinearLayout And RelativeLayout
Writing A Basic Android Application
Installing The Android SDK In Eclipse

Working With Android Contacts

API For 1.6 and Before

If you just read the begining of this article the first bit of this page is going to look familiar. This page is designed to act as a standalone guide to working with the contacts API in Android 1.6 and before.

Granting Access

Before an application can query the contact records access must be granted through the AndroidManifest.xml file stored in the root of the project. Add the following uses-permission belows the uses-sdk statement.

 <uses-permission android:name="android.permission.READ_CONTACTS" />

Querying the contact database

Retrieving Contact Details

Basic contact information stored in Contacts table with detailed information stored in individual tables for normalization. In Android 1.x to query the base contact records the URI to query is stored in People.CONTENT_URI.

package higherpass.TestContacts;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts;
import android.provider.Contacts.People;

public class TestContacts extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ContentResolver cr = getContentResolver();
        Cursor cur = cr.query(People.CONTENT_URI, 
			null, null, null, null);
        if (cur.getCount() > 0) {
	     while (cur.moveToNext()) {
	         String id = cur.getString(cur.getColumnIndex(People._ID));
	         String name = cur.getString(cur.getColumnIndex(People.DISPLAY_NAME));
	     }
        }
    }
}

Start off with the standard view loading. Then we create a ContentResolver instance that will be used to query the SQLite database that stores the contacts. The ContentResolver query returns a Cursor instance that holds the contact records queried from the database. Then take the ID field from the contact record and store it in the string id and take the DISPLAY_NAME field and place it in the string name. For more information about cursors see the Android Cursor Tutorial.

Phone Numbers

Phone numbers are stored in their own table and need to be queried separately. To query the phone number table use the URI stored in the SDK variable Contacts.Phones.CONTENT_URI. Use a WHERE conditional to get the phone numbers for the specified contact.

	if (Integer.parseInt(cur.getString(
            cur.getColumnIndex(People.PRIMARY_PHONE_ID))) > 0) {
		Cursor pCur = cr.query(
				Contacts.Phones.CONTENT_URI, 
				null, 
				Contacts.Phones.PERSON_ID +" = ?", 
				new String[]{id}, null);
		int i=0;
		int pCount = pCur.getCount();
		String[] phoneNum = new String[pCount];
		String[] phoneType = new String[pCount];
		while (pCur.moveToNext()) {
			phoneNum[i] = pCur.getString(
                               pCur.getColumnIndex(Contacts.Phones.NUMBER));
			phoneType[i] = pCur.getString(
                               pCur.getColumnIndex(Contacts.Phones.TYPE));
			i++;
		} 
	}

Query the phones table and get a Cursor stored in pCur. Since the Android contacts database can store multiple phone numbers per contact we need to loop through the returned results. In addition to returning the phone number the query also returned the type of number (home, work, mobile, etc).

Email Addresses

Querying email addresses is similar to phone numbers. A special query must be performed to get email addresses from the database. Query the URI stored in Contacts.ContactMethods.CONTENT_EMAIL_URI to query the email addresses.

	Cursor emailCur = cr.query( 
			Contacts.ContactMethods.CONTENT_EMAIL_URI, 
			null,
			Contacts.ContactMethods.PERSON_ID + " = ?", 
			new String[]{id}, null); 
	while (emailCur.moveToNext()) { 
	    // This would allow you get several email addresses
	} 
	emailCur.close();

Simple query Contacts.ContactMethods.CONTENT_EMAIL_URI with a conditional limiting the results to numbers that match the ID of the contact record matches the value in the field Contacts.ContactMethods.PERSON_ID. As with phone numbers each contact can contain multiple email addresses so we need to loop through the Cursor records.

Notes

Custom notes can be attached to each contact record. Notes though are stored in the main contact record and are simply accessed through the data stored in People.NOTES.

 cur.getString(cur.getColumnIndex(People.NOTES));

Postal Addresses

Android can store multiple postal addresses per contact. Addresses are stored in the contact methods table and need to have a second conditional added to retrieve the data. Add a conditional Contacts.ContactMethods.KIND that matches Contacts.ContactMethods.CONTENT_POSTAL_ITEM_TYPE to only query postal addresses from Contacts.ContactMethods.CONTENT_URI.

	String addrWhere = Contacts.ContactMethods.PERSON_ID 
                + " = ? AND " + Contacts.ContactMethods.KIND + " = ?"; 
	String[] addrWhereParams = new String[]{id, 
		Contacts.ContactMethods.CONTENT_POSTAL_ITEM_TYPE}; 		
	Cursor addrCur = cr.query(Contacts.ContactMethods.CONTENT_URI, 
                null, addrWhere, addrWhereParams, null); 
	while(addrCur.moveToNext()) {
		String addr = addrCur.getString(
                   addrCur.getColumnIndex(Contacts.ContactMethodsColumns.DATA));
		String type = addrCur.getString(
                   addrCur.getColumnIndex(Contacts.ContactMethodsColumns.TYPE));
	} 
	addrCur.close();

Query Contacts.ContactMethods.CONTENT_URI with 2 conditionals, one limiting the contact ID and the second Contacts.ContactMethods.KIND matching Contacts.ContactMethods.CONTENT_POSTAL_ITEM_TYPE to only query postall addresses. Android can store multiple postal addresses so loop through the list of returned results. Android also stores a type record for the address. In Android 1.6 and before the address is stored as a free-form string containing the data. In Android 2.0 and later this has changed to being a series of fields containing parts of the address.

Instant Messenger (IM)

The instant messenger query works just like the previous 2. The data is queried from Contacts.ContactMethods.CONTENT_URI and needs conditionals for the contact ID and Contacts.ContactMethods.KIND matching Contacts.ContactMethods.CONTENT_IM_ITEM_TYPE.

	String imWhere = Contacts.ContactMethods.PERSON_ID 
               + " = ? AND " + Contacts.ContactMethods.KIND + " = ?"; 
	String[] imWhereParams = new String[]{id, 
		Contacts.ContactMethods.CONTENT_IM_ITEM_TYPE}; 
	Cursor imCur = cr.query(Contacts.ContactMethods.CONTENT_URI, 
                null, imWhere, imWhereParams, null); 
	if (imCur.moveToFirst()) { 
		String imName = imCur.getString(
                    imCur.getColumnIndex(Contacts.ContactMethodsColumns.DATA));
		String imType = imCur.getString(
                    imCur.getColumnIndex(Contacts.ContactMethodsColumns.TYPE));
	} 
	imCur.close();

Organizations

The last part of the contact record to be covered is the Organizations data. The Android contact record can contain information about Employment, professional, and social memberships as well as roles and titles. These records are queried from the URI stored in Contacts.Organizations.CONTENT_URI.

	String orgWhere = Contacts.ContactMethods.PERSON_ID + " = ?"; 
	String[] orgWhereParams = new String[]{id}; 
	Cursor orgCur = cr.query(Contacts.Organizations.CONTENT_URI, 
              null, orgWhere, orgWhereParams, null);
	if (orgCur.moveToFirst()) { 
		String orgName = orgCur.getString(
                   orgCur.getColumnIndex(Contacts.Organizations.COMPANY));
		String title = orgCur.getString(
                   orgCur.getColumnIndex(Contacts.Organizations.TITLE));
	} 
	orgCur.close();
Contacts in Android 2.0 <<  1 2 3 4 5  >> Data Classes For Combined API
New Content