Android Contacts Content Provider – Retrieving and Listing Contacts in ListView Example

September 22, 2012
By

In this article, we will create an Android application which will query Android contacts content provider to retrieve the contacts available in the phone and list those contacts in a listview with various details such as name, mobile number, home number, work email id, photo etc.

This application is developed in Eclipse ( 4.2.0 ) with ADT plugin ( 20.0.3 ) and Android SDK ( R20.0.3 ) .


1. Create a new Android application project namely “ListViewContacts”

Create new Android application project

Figure 1 : Create new Android application project


2. Design application launcher icon

Design Application Launcher Icon

Figure 2 : Design Application Launcher Icon


3. Create a blank activity to define the class MainActivity

Create a blank Activity

Figure 3 : Create a blank Activity


4. Enter MainActivity details

Enter MainActivity Details

Figure 4 : Enter MainActivity Details


5. Add Android’s Support library

In this application, we are using SimpleCursorAdapter to load contacts in the listview. SimpleCursorAdapter has an API function called swapCursor() which is introduced in Android API level 11(Honeycomb). Since our application support pre-Honeycomb versions, we have to add Android Support Library to use this function in our application.

By default, Android support library (android-support-v4.jar ) is added to this project by Eclipse IDE to the directory libs. If it is not added, we can do it manually by the following steps :

  • Open Project Explorer by Clicking “Window -> Show View -> Project Explorer”
  • Right click this project
  • Then from popup window, Click “Android Tools -> Add Support Library “

6. Create a new folder namely “drawable” under the filder “res”


7. Download the given below file to res/drawable folder


8. Update the file res/values/strings.xml


<resources>
    <string name="app_name">ContactsContentProvider</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">Contacts Content Provider</string>
</resources>


9. Update the layout activity_main in the file res/layout/activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/lst_contacts"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>


10. Create a new layout for the listview in the file res/layout/lv_layout.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:textSize="20dp"
        android:textStyle="bold" />

    <ImageView
        android:id="@+id/iv_photo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_name"
        android:layout_centerHorizontal="true"
        android:padding="5dp" />

    <TextView
        android:id="@+id/tv_details"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/iv_photo"  />
</RelativeLayout>


11. Update the file res/values/styles.xml

<resources>
    <style name="AppTheme" parent="android:Theme" />
</resources>

12. Update the file res/values-v11/styles.xml

<resources>
    <style name="AppTheme" parent="android:Theme.Holo" />
</resources>

13. Update the file res/values-v14/styles.xml


<resources>
    <style name="AppTheme" parent="android:Theme.Holo" />
</resources>


14. Update the class MainActivity in the file src/in/wptrafficanalyzer/listviewcontacts/MainActivity.java


package in.wptrafficanalzer.listviewcontacts;

import java.io.File;
import java.io.FileOutputStream;

import android.app.Activity;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.Menu;
import android.widget.ListView;

public class MainActivity extends Activity {

    SimpleCursorAdapter mAdapter;
    MatrixCursor mMatrixCursor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // The contacts from the contacts content provider is stored in this cursor
        mMatrixCursor = new MatrixCursor(new String[] { "_id","name","photo","details"} );

        // Adapter to set data in the listview
        mAdapter = new SimpleCursorAdapter(getBaseContext(),
            R.layout.lv_layout,
            null,
            new String[] { "name","photo","details"},
            new int[] { R.id.tv_name,R.id.iv_photo,R.id.tv_details}, 0);

        // Getting reference to listview
        ListView lstContacts = (ListView) findViewById(R.id.lst_contacts);

        // Setting the adapter to listview
        lstContacts.setAdapter(mAdapter);

        // Creating an AsyncTask object to retrieve and load listview with contacts
        ListViewContactsLoader listViewContactsLoader = new ListViewContactsLoader();

        // Starting the AsyncTask process to retrieve and load listview with contacts
        listViewContactsLoader.execute();
    }

    /** An AsyncTask class to retrieve and load listview with contacts */
    private class ListViewContactsLoader extends AsyncTask<Void, Void, Cursor>{

        @Override
        protected Cursor doInBackground(Void... params) {
            Uri contactsUri = ContactsContract.Contacts.CONTENT_URI;

            // Querying the table ContactsContract.Contacts to retrieve all the contacts
            Cursor contactsCursor = getContentResolver().query(contactsUri, null, null, null,
            ContactsContract.Contacts.DISPLAY_NAME + " ASC ");

            if(contactsCursor.moveToFirst()){
                do{
                    long contactId = contactsCursor.getLong(contactsCursor.getColumnIndex("_ID"));

                    Uri dataUri = ContactsContract.Data.CONTENT_URI;

                    // Querying the table ContactsContract.Data to retrieve individual items like
                    // home phone, mobile phone, work email etc corresponding to each contact
                    Cursor dataCursor = getContentResolver().query(dataUri, null,
                                        ContactsContract.Data.CONTACT_ID + "=" + contactId,
                                        null, null);

                    String displayName="";
                    String nickName="";
                    String homePhone="";
                    String mobilePhone="";
                    String workPhone="";
                    String photoPath="" + R.drawable.blank;
                    byte[] photoByte=null;
                    String homeEmail="";
                    String workEmail="";
                    String companyName="";
                    String title="";

                    if(dataCursor.moveToFirst()){
                        // Getting Display Name
                        displayName = dataCursor.getString(dataCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME ));
                        do{

                            // Getting NickName
                            if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE))
                                nickName = dataCursor.getString(dataCursor.getColumnIndex("data1"));

                            // Getting Phone numbers
                            if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)){
                                switch(dataCursor.getInt(dataCursor.getColumnIndex("data2"))){
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_HOME :
                                        homePhone = dataCursor.getString(dataCursor.getColumnIndex("data1"));
                                        break;
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE :
                                        mobilePhone = dataCursor.getString(dataCursor.getColumnIndex("data1"));
                                        break;
                                    case ContactsContract.CommonDataKinds.Phone.TYPE_WORK :
                                        workPhone = dataCursor.getString(dataCursor.getColumnIndex("data1"));
                                        break;
                                }
                            }

                            // Getting EMails
                            if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE ) ) {
                                switch(dataCursor.getInt(dataCursor.getColumnIndex("data2"))){
                                    case ContactsContract.CommonDataKinds.Email.TYPE_HOME :
                                        homeEmail = dataCursor.getString(dataCursor.getColumnIndex("data1"));
                                        break;
                                    case ContactsContract.CommonDataKinds.Email.TYPE_WORK :
                                        workEmail = dataCursor.getString(dataCursor.getColumnIndex("data1"));
                                        break;
                                }
                            }

                            // Getting Organization details
                            if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Organization.CONTENT_ITEM_TYPE)){
                                companyName = dataCursor.getString(dataCursor.getColumnIndex("data1"));
                                title = dataCursor.getString(dataCursor.getColumnIndex("data4"));
                            }

                            // Getting Photo
                            if(dataCursor.getString(dataCursor.getColumnIndex("mimetype")).equals(ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)){
                                photoByte = dataCursor.getBlob(dataCursor.getColumnIndex("data15"));

                                if(photoByte != null) {
                                    Bitmap bitmap = BitmapFactory.decodeByteArray(photoByte, 0, photoByte.length);

                                    // Getting Caching directory
                                    File cacheDirectory = getBaseContext().getCacheDir();

                                    // Temporary file to store the contact image
                                    File tmpFile = new File(cacheDirectory.getPath() + "/wpta_"+contactId+".png");

                                    // The FileOutputStream to the temporary file
                                    try {
                                        FileOutputStream fOutStream = new FileOutputStream(tmpFile);

                                        // Writing the bitmap to the temporary file as png file
                                        bitmap.compress(Bitmap.CompressFormat.PNG,100, fOutStream);

                                        // Flush the FileOutputStream
                                        fOutStream.flush();

                                        //Close the FileOutputStream
                                        fOutStream.close();

                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                    photoPath = tmpFile.getPath();
                                }
                            }
                        }while(dataCursor.moveToNext());
                        String details = "";

                        // Concatenating various information to single string
                        if(homePhone != null && !homePhone.equals("") )
                            details = "HomePhone : " + homePhone + "\n";
                        if(mobilePhone != null && !mobilePhone.equals("") )
                            details += "MobilePhone : " + mobilePhone + "\n";
                        if(workPhone != null && !workPhone.equals("") )
                            details += "WorkPhone : " + workPhone + "\n";
                        if(nickName != null && !nickName.equals("") )
                            details += "NickName : " + nickName + "\n";
                        if(homeEmail != null && !homeEmail.equals("") )
                            details += "HomeEmail : " + homeEmail + "\n";
                        if(workEmail != null && !workEmail.equals("") )
                            details += "WorkEmail : " + workEmail + "\n";
                        if(companyName != null && !companyName.equals("") )
                            details += "CompanyName : " + companyName + "\n";
                        if(title != null && !title.equals("") )
                            details += "Title : " + title + "\n";

                        // Adding id, display name, path to photo and other details to cursor
                        mMatrixCursor.addRow(new Object[]{ Long.toString(contactId),displayName,photoPath,details});
                    }
                }while(contactsCursor.moveToNext());
            }
            return mMatrixCursor;
        }

        @Override
        protected void onPostExecute(Cursor result) {
            // Setting the cursor containing contacts to listview
            mAdapter.swapCursor(result);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
}


15. Update the file AndroidManifest.xml


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.wptrafficanalzer.listviewcontacts"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="5"
        android:targetSdkVersion="15" />

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

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

16. Screenshots of the application

Contacts list in the Android's Contact Manager

Figure 5 : Contacts list in the Android's Contact Manager

 

Listing Contacts in a listview retrieved by Contacts Content Provider

Figure 6 : Listing Contacts in a listview retrieved by Contacts Content Provider


17. Download


18. Reference

http://developer.android.com/guide/index.html


How to hire me?

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in

You can hire me on hourly basis or on project basis for Android applications development.

For hiring me, please mail your requirements to info@wptrafficanalyzer.in.

My other blogs
store4js.blogspot.com


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: , , , ,

27 Responses to Android Contacts Content Provider – Retrieving and Listing Contacts in ListView Example

  1. ram on September 23, 2012 at 2:30 pm

    Hi this blog is very helpful thanks iam flowing your blog daily can you make a side index for this contact book like Samsung and i phone

  2. Dr.Luiji on December 19, 2012 at 2:23 pm

    Really a nice tutorial. Works like a charm and it cleared my concepts.
    Thank you very much!

    Dr.Luiji

  3. Tarunjot Singh on February 1, 2013 at 1:18 pm

    Thanks a lot for this code………………..God bless you with lots full of peace and prosperity…….

  4. Anoniim on March 6, 2013 at 12:46 pm

    The main disadvantage of this approach is that it takes far too long to load the list. I have more than 1500 contacts in my phone and loading takes tens of seconds which is completely unusable.

    Thanks for nice and clear tutorial anyway.

  5. akaihola on March 19, 2013 at 1:05 pm

    Hi,

    Just wanted to note that it’s very difficult to study the code on your blog since lines are clipped at 64 characters and the horizontal scrollbar doesn’t fit on screen in long examples.

    Besides that, thanks for the tutorial!

    • george on March 19, 2013 at 3:14 pm

      Thank you for your suggestion

  6. nitin on March 22, 2013 at 2:16 pm

    hello sir,
    your code is very helpful since i am new in android development.
    i w have 1 doubt which i am not able to solve since last few days, i want to add checkbox in above and want to get all those contacts which are checked.
    please help me in that.
    thank you in advanced

  7. Aaron on April 25, 2013 at 12:43 am

    God bless you mate! I tried a lot finally i found this tutorial.. Bowing down to you !!Lots of blessings..

    • amar on May 13, 2016 at 4:58 pm

      really very nice tutorial

  8. Aaron on April 26, 2013 at 12:36 am

    04-26 00:30:24.107: E/AndroidRuntime(9604): FATAL EXCEPTION: AsyncTask #1
    04-26 00:30:24.107: E/AndroidRuntime(9604): java.lang.RuntimeException: An error occured while executing doInBackground()
    04-26 00:30:24.107: E/AndroidRuntime(9604): at android.os.AsyncTask$3.done(AsyncTask.java:200)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.lang.Thread.run(Thread.java:1096)
    04-26 00:30:24.107: E/AndroidRuntime(9604): Caused by: java.lang.NullPointerException
    04-26 00:30:24.107: E/AndroidRuntime(9604): at in.wptrafficanalzer.listviewcontacts.MainActivity$ListViewContactsLoader.doInBackground(MainActivity.java:92)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at in.wptrafficanalzer.listviewcontacts.MainActivity$ListViewContactsLoader.doInBackground(MainActivity.java:1)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at android.os.AsyncTask$2.call(AsyncTask.java:185)
    04-26 00:30:24.107: E/AndroidRuntime(9604): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    04-26 00:30:24.107: E/AndroidRuntime(9604): … 4 more

    This is the error I got when I ran the code in my ace gts5830 froyo..plz provide a solution..thanks..

    • Aaron on April 26, 2013 at 12:36 am

      In emulator it works like butter but not in my phone..why?

      • Omar on June 28, 2015 at 10:12 pm

        Hey did you happen to find a solution for your device. Because i am going through the same problem and it crashes when i debug on my phone

  9. Sankaran on May 11, 2013 at 8:04 pm

    Hi i want to list contacts with checkbox and after that want to handle selected items .. can anyone help me thank you..

  10. carlos on June 15, 2013 at 9:07 am

    Lot of time looking for something like this! you rock!

  11. sajid on June 20, 2013 at 3:14 pm

    hello

    I tried this but when i am integrating this with my app, its n ot working. it is just showing a blank activity

  12. jay on June 27, 2013 at 5:27 pm

    Thnx a lot…………Really a nice tutorial……………well runnable n simple to understand ………..Thnx again

  13. jay on June 28, 2013 at 12:17 pm

    hello sir ds tutorial really nice..i get stuck here click event on image icon how can we create on same tutorial thnxxxxxxx a lot

  14. jay on July 4, 2013 at 5:20 pm

    I run this applictaion in Emulator runing well, but after runing same .Apk in Tab displaying blank screen ..why this happn ????????
    Thnx in advance

    • george on July 4, 2013 at 6:01 pm

      It may take some time, if your contacts list contain a lot of contacts.

  15. jay on July 5, 2013 at 3:09 pm

    Hello, m trying to make changes(actlly m trying change the query for favourite contact list it displaying all contact not favourite n i dont want to display photo but still displaying photo…) in same application after runing the code it didnt display m changes,n when i clean d application R.java get removed from application….

    2. when i copy paste the code in new project it run well in emulator but displaying blank screen in Mobile device or tablet ……

    i really get stuck here…………………..Plzz help m…

    Thnx a lot in advance for u r reply n ds is one of gud post i found which well explentary n well exicutable

  16. jay on July 5, 2013 at 5:43 pm

    Sorry sir its my Emulator Problem nw i solved, just i have one question,i want to display Favourite contact list in same application, how can i change above query for favourite contact list…………Many Thnx in advance….

  17. pavan raghamwar on July 26, 2013 at 5:50 pm

    thanks alot it is very helpful to me…..

  18. lokesh pathak on November 24, 2014 at 8:51 pm

    sir pls tell me how type add calling and delete function in it

  19. lokesh on November 27, 2014 at 11:10 am

    In emulator it works but not in my phone..why?

  20. Jithin Varghese on March 4, 2015 at 3:24 pm

    while clicking on each contact name. Show the details in new page using setOnItemClickListener. How to implement this? Please help.

  21. juliusham on August 11, 2015 at 7:46 pm

    hi thanks for this great guide..
    However where do u think the slow loading of contacts happens. can it be the type of query usd?

  22. ejeong kim on August 21, 2015 at 1:28 pm

    so helpful to me… thanyou…
    But Images coming from my cell address book show too small.
    i think that the reason is using cacheDirectory..
    is that right?

Leave a Reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner