Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Reading Contact Data Using a Content Provider

Author: Ian Darwin
Published? true -- FormatLanguage: W


You need to extract details, such as a phone number or email address, from the Contacts database.


Use an Intent to let the user pick one contact. Use a ContentResolver to create an SQLite Query for the chosen contact. Use SQLite and pre-defined constants in the dunningly-named ContactContract class to retrieve the parts you want. Be aware that the Contacts database was designed for generality, not for simplicity.


This code is from TabbyText, my SMS Text Message sender for Tablets. The user has already picked the given contact (using the Contact app; see Retrieving Data from a Content Provider). In this code we want to extract the Mobile number and save it in a text field in the current Activity, so the user can post-edit it if need be, or even reject it, so we just set it on an EditText once we find it.

Finding it turns out to be the hard part. We start with a Query that we get from the Content Provider, to extract the ID field for the given contact. Information like phone numbers and emails are in their own tables, so we need a second query, to feed in the Id as part of the "select" part of the query. This query gives a list of the contact's phone numbers. We iterate through this, taking each valid phone number and setting it on the EditText.

A further elaboration would restrict this to only selecting the Mobile number (Contacts allows both Home Fax and Work Fax, but only one Mobile number, at least as of Honeycomb 3.2).

	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode == REQ_GET_CONTACT) {
			switch(resultCode) {
			case Activity.RESULT_OK:
				// The Contacts API is about the most complex to use.
				// First we have to retrieve the Contact, since we only get its URI from the Intent
				Uri resultUri = data.getData(); // e.g., content://contacts/people/123
				Cursor cont = getContentResolver().query(resultUri, null, null, null, null);
				if (!cont.moveToNext()) {	// expect 001 row(s)
					Toast.makeText(this, "Cursor contains no data", Toast.LENGTH_LONG).show(); 
				int columnIndexForId = cont.getColumnIndex(ContactsContract.Contacts._ID);
				String contactId = cont.getString(columnIndexForId);
				int columnIndexForHasPhone = cont.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER);
				boolean hasAnyPhone = Boolean.parseBoolean(cont.getString(columnIndexForHasPhone));
				if (!hasAnyPhone) {
					Toast.makeText(this, "Selected contact seems to have no phone numbers ", Toast.LENGTH_LONG).show(); 

				// Now we have to do another query to actually get the numbers!
				Cursor numbers = getContentResolver().query(
						ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, // "selection", 
						null, null);
				// XXX still need to restrict to Mobile number!
				while (numbers.moveToNext()) {
					String aNumber = numbers.getString(numbers.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
				if (cont.moveToNext()) {
					System.out.println("WARNING: More than one contact returned from picker!");
			case Activity.RESULT_CANCELED:
				// nothing to do here
				Toast.makeText(this, "Unexpected resultCode: " + resultCode, Toast.LENGTH_LONG).show(); 
		super.onActivityResult(requestCode, resultCode, data);


The source code for this project can be downloaded from http://projects.darwinsys.com/TabbyText-src.zip.
idarwin 2012-06-28 14:54:32.013 Thanks Bernard. While TabbyText is by no means production ready, I have repaired the link so you can download what there is of it. --Ian
bernard 2012-06-26 15:42:36.178 Hi, When I try to click on the link to the TabbyText-src.zip file, I get a 404 message: HTTP Status 404 - /TabbyText-src.zip type Status report message /TabbyText-src.zip description The requested resource (/TabbyText-src.zip) is not available Is the source code somewhere else? Many thanks, Bernard