Many of you are dealing with the deprecation problem of android contacts api so for that android says you to use the new ContactsContract package to avoid the issues related to the deprecation of this package.So now for that i have writen this tutorial to give you the clear view to handle the query on the contacs with this new package which was introduced in api level 5 android 2.0 and was further gets inproved in the api level 11 i.e android 3.0.
As this post is written for beginners you might want to jump directly to a specific topic within this post:
Permission
Querying a list of all available contacts
Querying basic information of a specific contact
Querying the photo of a contact
Querying all phone numbers of a contact
Querying all email addresses of a contact
Basic concept of Content Providers
Before we start let’s take a short look at the basic concept to access content providers. Content providers are providing data using a database like approach. The database of the content provider is always addressed by an unique URI e.g. “content://com.appsolut.example/exampleData”. To access a specific content provider, the first step is to create a query resulting in a Cursor which represents the returned data as an object with random access. The configuration of queries is straightforward and can be described in five steps:
Identify the unique resource identifier (URI) of the desired content provider
Generate a String array which is holding the names of the columns which you require from the database (e.g. RawContacts.CONTACT_ID). This is called projection.
If you want to filter the results using the query define a selection clause (e.g. to filter by contact ids: RawContacts.CONTACT_ID + “=?”). The ? operator acts as a parameter which is defined in the next step. This is called selection.
Create another String array for all parameters which you’ve used in your selection clause. For the above example it could be something like new String[]{contactId}. If no parameters where used just ignore this step. This array is called selectionArgs.
If you want to sort your results by table columns define a sort order like RawContacts.CONTACT_ID + ” ASC”, which will sort the results in ascending order using their contact ids. This string is called sortOrder.
Using the parameters from these five steps the query method can be called.
1 public final Cursor managedQuery(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
Note: starting with API level 11 the managedQuery method will also be marked as deprecated but the new concept is quite similar.
Using the cursor rows can be selected and specific values of columns in this row can be returned using getters like getString or getInt.
For a more detailed description about content providers visit the documentation at http://developer.android.com/guide/topics/providers/content-providers.html – but don’t use the proposed way to access the contacts content provider as it is outdated and deprecated.
Querying contacts and further details of a contact
Enough basics, let’s query contacts and information related to these contacts. For that purpose the “android.provider.ContactsContract“ class and subpackages were introduced at API level 5.
Permission
Now we can start accessing the “ContactsContract.RawContacts” (http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html) content provider to query all available contacts stored in the smartphone. This table represents every person as a single entry (one row). In this table an unique id is assigned to each person which is stored in the RawContacts.CONTACT_ID field (column). Unlike the default _ID column this id is used in the other tables as well, so we can later use it to query additional information about this person. To get access to the RawContacts content provider we first define a projection as shown here:
1 final String[] projection = new String[] {
2 RawContacts.CONTACT_ID, // the contact id column
3 RawContacts.DELETED // column if this contact is deleted
4 };
We are interested in the contact id column and the deleted column. The deleted column is important because there can be entries in the RawContacts table which have been deleted and therefore should not be displayed anymore. With the help of the projection we can now create the Cursor using a query.
1 final Cursor rawContacts = managedQuery(
2 RawContacts.CONTENT_URI, // the URI for raw contact provider
3 projection
4 null, // selection = null, retrieve all entries
5 null, // selection is without parameters
6 null); // do not order
Using this cursor we can iterate through all available contact ids. To do so we need to identify the index of the contact id and deleted column. We can use the getColumnIndex of the cursor object to get this index.
11 final int contactIdColumnIndex = rawContacts.getColumnIndex(RawContacts.CONTACT_ID);
12
13 final int deletedColumnIndex = rawContacts.getColumnIndex(RawContacts.DELETED);
To ensure that the cursor is pointing to the beginning and that there are valid entries we use the moveToFirst method, which will move the cursor to the first entry and return true if there are entries available. Now we can iterate over all entries using a while loop which checks the isAfterLast method of the cursor which will return true if the cursor is pointing to an non-existing entry.
14 if(rawContacts.moveToFirst()) {
15 while(!rawContacts.isAfterLast()) { // still a valid entry left?
16 final int contactId = rawContacts.getInt(contactIdColumnIndex);
17 final boolean deleted = (rawContacts.getInt(deletedColumnIndex) == 1);
18 if(!deleted) {
19 doSomethingWithAContactId(contactId));
20 }
21 rawContacts.moveToNext(); // move to the next entry
22 }
23 }
Finally we can close the cursor to free resources:
24 rawContacts.close();
Querying basic information of a specific contact
Using a given contact id (for example from the previous part) we can access basic information about this person in the “ContactsContract.Contacts” (http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html) table. In our example we will query the name of the contact as well as the photo id which is a reference to the photo entry in the data table and can thus later be used to query the photo as a bitmap. So first we define our projection for the columns DISPLAY_NAME and PHOTO_ID.
1 final String[] projection = new String[] {
2 Contacts.DISPLAY_NAME, // the name of the contact
3 Contacts.PHOTO_ID // the id of the column in the data table for the image
4 };
Using this selection we can create a cursor pointing to that specific contact. By using the selection and selectionArgs parameter of the query method we can filter the results of the query according to the given contact id (in our case the field contactId).
05 final Cursor contact = managedQuery(
06 Contacts.CONTENT_URI,
07 projection,
08 Contacts._ID + "=?", // filter entries on the basis of the contact id
09 new String[]{String.valueOf(contactId)}, // the parameter to which the contact id column is compared to
10 null);
Now we can retrieve the desired information.
11 if(contact.moveToFirst()) {
12 final String name = contact.getString(
13 contact.getColumnIndex(Contacts.DISPLAY_NAME));
14 final String photoId = contact.getString(
15 contact.getColumnIndex(Contacts.PHOTO_ID));
16 doSomethingWithAContactName(name);
17 doSomethingWithAContactPhotoId(photoId);
18 }
19 contact.close();
Querying the photo of a contact
The contact photos are stored as binary large objects (blob) in the “ContactsContract.Data” table. In this table all kinds of data about a contact is stored so we need a given photo id to retrieve the correct entry (see Querying basic information of a specific contact). In our example we use the field photoId to represent this id. The column in which the blob is stored is defined in the “CommonDataKinds.Photo” class. Using this Photo.PHOTO column we can define our query as shown below.
1 final Cursor photo = managedQuery(
2 Data.CONTENT_URI,
3 new String[] {Photo.PHOTO}, // column for the blob
4 Data._ID + "=?", // select row by id
5 new String[]{photoId}, // filter by photoId
6 null);
If the contact has a photo linked to its entry, the cursor will return the photo blob. Using the “BitmapFactory” we can create a Bitmap using this blob.
07 if(photo.moveToFirst()) {
08 byte[] photoBlob = photo.getBlob(
09 photo.getColumnIndex(Photo.PHOTO));
10 final Bitmap photoBitmap = BitmapFactory.decodeByteArray(
11 photoBlob, 0, photoBlob.length);
12 doSomethingWithAContactPhoto(photoBitmap);
13 }
14 photo.close();
Querying all phone numbers of a contact
The phone numbers are stored in the “ContactsContract.Data” table. Every number is represented by one entry in this table. To access the columns used for phone numbers we can use the definitions in the “ContactsContract.CommonDataKinds.Phone” class. There are three different columns available: number, type and label. The type column is used to define the type of the number e.g. work, home or other. If the type other is defined the label column can be used to get the defined name of this type. In our example we will just look at the types which are defined so our projection does not contain the label column.
1 final String[] projection = new String[] {
2 Phone.NUMBER,
3 Phone.TYPE,
4 };
As an URI for the phone number entries we can use the “Phone.CONTENT_URI” URI which filters the data table according to the media type of phone numbers. Because we only want phone numbers of a specific contact we filter the results on the basis of the given contactId field.
05 final Cursor phone = managedQuery(
06 Phone.CONTENT_URI,
07 projection,
08 Data.CONTACT_ID + "=?",
09 new String[]{String.valueOf(contactId)},
10 null);
Because there can be multiple entries we use a while loop to iterate over this cursor. To get a human readable version of the phone number type we use the getTypeLabelResource method to get the resource id of the label for a specific type.
11 if(phone.moveToFirst()) {
12 final int contactNumberColumnIndex = phone.getColumnIndex(Phone.NUMBER);
13 final int contactTypeColumnIndex = phone.getColumnIndex(Phone.TYPE);
14
15 while(!phone.isAfterLast()) {
16 final String number = phone.getString(contactNumberColumnIndex);
17 final int type = phone.getInt(contactTypeColumnIndex);
18 final int typeLabelResource = Phone.getTypeLabelResource(type);
19 doSomethingWithAContactPhoneNumber(number, typeLabelResource);
20 phone.moveToNext();
21 }
22
23 }
24 phone.close();
Querying all email addresses of a contact
The email addresses of a contact are also stored in the “ContactsContract.Data” table. To retrieve the desired information we use the defined column names and URI in the “CommonDataKinds.Email” class. With API level 11 an extra field was added to this class to represent the address of the email but as this example is designed for API level 5+ we use the old field.
1 final String[] projection = new String[] {
2 Email.DATA, // use Email.ADDRESS for API-Level 11+
3 Email.TYPE
4 };
The type of the email address is implemented like the type of phone numbers and using the getTypeLabelResource method we can retrieve a human readable label resource id of the type. So now we can create our cursor to retrieve all available email addresses.
05 final Cursor email = managedQuery(
06 Email.CONTENT_URI,
07 projection,
08 Data.CONTACT_ID + "=?",
09 new String[]{String.valueOf(contactId)},
10 null);
Just like we did process the results of the phone query we can iterate over the email cursor to extract every address.
view source
print?
11 if(email.moveToFirst()) {
12 final int contactEmailColumnIndex = email.getColumnIndex(Email.DATA);
13 final int contactTypeColumnIndex = email.getColumnIndex(Email.TYPE);
14
15 while(!email.isAfterLast()) {
16 final String address = email.getString(contactEmailColumnIndex);
17 final int type = email.getInt(contactTypeColumnIndex);
18 final int typeLabelResource = Email.getTypeLabelResource(type);
19 doSomethingWithAContactEmailAddress(address, typeLabelResource);
20 email.moveToNext();
21 }
22
23 }
24 email.close();
I hope this tutorial can be beneficial for you drop any comment or query!!!!
As this post is written for beginners you might want to jump directly to a specific topic within this post:
Permission
Querying a list of all available contacts
Querying basic information of a specific contact
Querying the photo of a contact
Querying all phone numbers of a contact
Querying all email addresses of a contact
Basic concept of Content Providers
Before we start let’s take a short look at the basic concept to access content providers. Content providers are providing data using a database like approach. The database of the content provider is always addressed by an unique URI e.g. “content://com.appsolut.example/exampleData”. To access a specific content provider, the first step is to create a query resulting in a Cursor which represents the returned data as an object with random access. The configuration of queries is straightforward and can be described in five steps:
Identify the unique resource identifier (URI) of the desired content provider
Generate a String array which is holding the names of the columns which you require from the database (e.g. RawContacts.CONTACT_ID). This is called projection.
If you want to filter the results using the query define a selection clause (e.g. to filter by contact ids: RawContacts.CONTACT_ID + “=?”). The ? operator acts as a parameter which is defined in the next step. This is called selection.
Create another String array for all parameters which you’ve used in your selection clause. For the above example it could be something like new String[]{contactId}. If no parameters where used just ignore this step. This array is called selectionArgs.
If you want to sort your results by table columns define a sort order like RawContacts.CONTACT_ID + ” ASC”, which will sort the results in ascending order using their contact ids. This string is called sortOrder.
Using the parameters from these five steps the query method can be called.
1 public final Cursor managedQuery(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
Note: starting with API level 11 the managedQuery method will also be marked as deprecated but the new concept is quite similar.
Using the cursor rows can be selected and specific values of columns in this row can be returned using getters like getString or getInt.
For a more detailed description about content providers visit the documentation at http://developer.android.com/guide/topics/providers/content-providers.html – but don’t use the proposed way to access the contacts content provider as it is outdated and deprecated.
Querying contacts and further details of a contact
Enough basics, let’s query contacts and information related to these contacts. For that purpose the “android.provider.ContactsContract“ class and subpackages were introduced at API level 5.
Permission
Now we can start accessing the “ContactsContract.RawContacts” (http://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html) content provider to query all available contacts stored in the smartphone. This table represents every person as a single entry (one row). In this table an unique id is assigned to each person which is stored in the RawContacts.CONTACT_ID field (column). Unlike the default _ID column this id is used in the other tables as well, so we can later use it to query additional information about this person. To get access to the RawContacts content provider we first define a projection as shown here:
1 final String[] projection = new String[] {
2 RawContacts.CONTACT_ID, // the contact id column
3 RawContacts.DELETED // column if this contact is deleted
4 };
We are interested in the contact id column and the deleted column. The deleted column is important because there can be entries in the RawContacts table which have been deleted and therefore should not be displayed anymore. With the help of the projection we can now create the Cursor using a query.
1 final Cursor rawContacts = managedQuery(
2 RawContacts.CONTENT_URI, // the URI for raw contact provider
3 projection
4 null, // selection = null, retrieve all entries
5 null, // selection is without parameters
6 null); // do not order
Using this cursor we can iterate through all available contact ids. To do so we need to identify the index of the contact id and deleted column. We can use the getColumnIndex of the cursor object to get this index.
11 final int contactIdColumnIndex = rawContacts.getColumnIndex(RawContacts.CONTACT_ID);
12
13 final int deletedColumnIndex = rawContacts.getColumnIndex(RawContacts.DELETED);
To ensure that the cursor is pointing to the beginning and that there are valid entries we use the moveToFirst method, which will move the cursor to the first entry and return true if there are entries available. Now we can iterate over all entries using a while loop which checks the isAfterLast method of the cursor which will return true if the cursor is pointing to an non-existing entry.
14 if(rawContacts.moveToFirst()) {
15 while(!rawContacts.isAfterLast()) { // still a valid entry left?
16 final int contactId = rawContacts.getInt(contactIdColumnIndex);
17 final boolean deleted = (rawContacts.getInt(deletedColumnIndex) == 1);
18 if(!deleted) {
19 doSomethingWithAContactId(contactId));
20 }
21 rawContacts.moveToNext(); // move to the next entry
22 }
23 }
Finally we can close the cursor to free resources:
24 rawContacts.close();
Querying basic information of a specific contact
Using a given contact id (for example from the previous part) we can access basic information about this person in the “ContactsContract.Contacts” (http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html) table. In our example we will query the name of the contact as well as the photo id which is a reference to the photo entry in the data table and can thus later be used to query the photo as a bitmap. So first we define our projection for the columns DISPLAY_NAME and PHOTO_ID.
1 final String[] projection = new String[] {
2 Contacts.DISPLAY_NAME, // the name of the contact
3 Contacts.PHOTO_ID // the id of the column in the data table for the image
4 };
Using this selection we can create a cursor pointing to that specific contact. By using the selection and selectionArgs parameter of the query method we can filter the results of the query according to the given contact id (in our case the field contactId).
05 final Cursor contact = managedQuery(
06 Contacts.CONTENT_URI,
07 projection,
08 Contacts._ID + "=?", // filter entries on the basis of the contact id
09 new String[]{String.valueOf(contactId)}, // the parameter to which the contact id column is compared to
10 null);
Now we can retrieve the desired information.
11 if(contact.moveToFirst()) {
12 final String name = contact.getString(
13 contact.getColumnIndex(Contacts.DISPLAY_NAME));
14 final String photoId = contact.getString(
15 contact.getColumnIndex(Contacts.PHOTO_ID));
16 doSomethingWithAContactName(name);
17 doSomethingWithAContactPhotoId(photoId);
18 }
19 contact.close();
Querying the photo of a contact
The contact photos are stored as binary large objects (blob) in the “ContactsContract.Data” table. In this table all kinds of data about a contact is stored so we need a given photo id to retrieve the correct entry (see Querying basic information of a specific contact). In our example we use the field photoId to represent this id. The column in which the blob is stored is defined in the “CommonDataKinds.Photo” class. Using this Photo.PHOTO column we can define our query as shown below.
1 final Cursor photo = managedQuery(
2 Data.CONTENT_URI,
3 new String[] {Photo.PHOTO}, // column for the blob
4 Data._ID + "=?", // select row by id
5 new String[]{photoId}, // filter by photoId
6 null);
If the contact has a photo linked to its entry, the cursor will return the photo blob. Using the “BitmapFactory” we can create a Bitmap using this blob.
07 if(photo.moveToFirst()) {
08 byte[] photoBlob = photo.getBlob(
09 photo.getColumnIndex(Photo.PHOTO));
10 final Bitmap photoBitmap = BitmapFactory.decodeByteArray(
11 photoBlob, 0, photoBlob.length);
12 doSomethingWithAContactPhoto(photoBitmap);
13 }
14 photo.close();
Querying all phone numbers of a contact
The phone numbers are stored in the “ContactsContract.Data” table. Every number is represented by one entry in this table. To access the columns used for phone numbers we can use the definitions in the “ContactsContract.CommonDataKinds.Phone” class. There are three different columns available: number, type and label. The type column is used to define the type of the number e.g. work, home or other. If the type other is defined the label column can be used to get the defined name of this type. In our example we will just look at the types which are defined so our projection does not contain the label column.
1 final String[] projection = new String[] {
2 Phone.NUMBER,
3 Phone.TYPE,
4 };
As an URI for the phone number entries we can use the “Phone.CONTENT_URI” URI which filters the data table according to the media type of phone numbers. Because we only want phone numbers of a specific contact we filter the results on the basis of the given contactId field.
05 final Cursor phone = managedQuery(
06 Phone.CONTENT_URI,
07 projection,
08 Data.CONTACT_ID + "=?",
09 new String[]{String.valueOf(contactId)},
10 null);
Because there can be multiple entries we use a while loop to iterate over this cursor. To get a human readable version of the phone number type we use the getTypeLabelResource method to get the resource id of the label for a specific type.
11 if(phone.moveToFirst()) {
12 final int contactNumberColumnIndex = phone.getColumnIndex(Phone.NUMBER);
13 final int contactTypeColumnIndex = phone.getColumnIndex(Phone.TYPE);
14
15 while(!phone.isAfterLast()) {
16 final String number = phone.getString(contactNumberColumnIndex);
17 final int type = phone.getInt(contactTypeColumnIndex);
18 final int typeLabelResource = Phone.getTypeLabelResource(type);
19 doSomethingWithAContactPhoneNumber(number, typeLabelResource);
20 phone.moveToNext();
21 }
22
23 }
24 phone.close();
Querying all email addresses of a contact
The email addresses of a contact are also stored in the “ContactsContract.Data” table. To retrieve the desired information we use the defined column names and URI in the “CommonDataKinds.Email” class. With API level 11 an extra field was added to this class to represent the address of the email but as this example is designed for API level 5+ we use the old field.
1 final String[] projection = new String[] {
2 Email.DATA, // use Email.ADDRESS for API-Level 11+
3 Email.TYPE
4 };
The type of the email address is implemented like the type of phone numbers and using the getTypeLabelResource method we can retrieve a human readable label resource id of the type. So now we can create our cursor to retrieve all available email addresses.
05 final Cursor email = managedQuery(
06 Email.CONTENT_URI,
07 projection,
08 Data.CONTACT_ID + "=?",
09 new String[]{String.valueOf(contactId)},
10 null);
Just like we did process the results of the phone query we can iterate over the email cursor to extract every address.
view source
print?
11 if(email.moveToFirst()) {
12 final int contactEmailColumnIndex = email.getColumnIndex(Email.DATA);
13 final int contactTypeColumnIndex = email.getColumnIndex(Email.TYPE);
14
15 while(!email.isAfterLast()) {
16 final String address = email.getString(contactEmailColumnIndex);
17 final int type = email.getInt(contactTypeColumnIndex);
18 final int typeLabelResource = Email.getTypeLabelResource(type);
19 doSomethingWithAContactEmailAddress(address, typeLabelResource);
20 email.moveToNext();
21 }
22
23 }
24 email.close();
I hope this tutorial can be beneficial for you drop any comment or query!!!!