Android Content Providers - Contacts Manager Example


In general Android application is not allowed to access the data of other application's. Each android application lives in its own security box. But when you want an application to share data with other applications then content providers can be useful.

Example of android's Content Providers :

  • Contacts.
  • Settings.
  • MediaStore.

Content providers provide data in form of relational database table in which each row is an instance of data. In this tutorials we will make an application in which we can add, view, delete and modify the contacts present on our phone.

Why we user content providers?

To facilitate the sharing of data among application's we use content providers.

You can perform

  • Query operations on content provider.
    Example: Displaying a phone contact.
  • Delete operation
    Example: Delete a contact.
  • Update operation
    Example: Edit an existing contact.
  • Insert operation
    Example: Add a new contact.

Request from Android System

The client application which request the data from content provider needs to add permissions in AndroidManifest file.

  • Ask a request to read contact.
  • Ask a permission for write access.
 <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
 <uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>

Display the contacts using Content providers

  1. Create a function inside your activity. Ths function will be used to display the contacts data on user-interface.
     void getContacts(){		
     	}
  2. Add the following line of code in your getContacts() function. ContentResolver helps to provide access to the data which we want to process.
     ContentResolver cr = getContentResolver();
  3. Query the data with the help of content resolver using query() method. Result of the query is stored inside a cursor.
     Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);		
  4. ContactsContract.Contacts.CONTENT_URI is the content URI.

Content URI

Content URI is used to identify the data. In above example ContactsContract.Contacts.CONTENT_URI helps to identify the data in contact provider. We can get the data by querying and passing content URI as an argument. Then we store the result inside a cursor.

We have the data inside our cursor and we can access this data and display it on our screen. Now we will display all contacts stored in android phone. We will be doing following steps :

  1. Create an URI.
  2. Create a projection.
  3. Create a Content Resolver.
  4. Run a query and save the result in a form of cursor.

Create a Content Resolver

ContentResolver cr = getContentResolver();

URI

URI helps to identify the data in content provider.  We will use the following URI to access contacts :

ContactsContract.CommonDataKinds.Phone.CONTENT_URI

Projection

It contains the name of columns you want to get. You pass this as a second argument to the query.

new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}

Get result and store it in cursor

Cursor contactsCursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, 
null, null, null);

How to fetch contact from cursor

We know the name of columns we want to get so we can get the column index to fetch it from Cursor.

"Name" column

ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME

"Number" column

ContactsContract.CommonDataKinds.Phone.NUMBER

Fetching data from cursor

 contactsCursor.moveToFirst();
	    do{
	    	String contactName = contactsCursor.getString(nameIndex);
	    	String contactNumber = contactsCursor.getString(numberIndex);
	    	String oldText = textView.getText().toString();
	    	textView.setText(oldText+"\nName: "+contactName+"- Number: "+contactNumber);
	    }while(contactsCursor.moveToNext());

Complete code for MainActivity

package com.example.kb4devcontacts;

import android.os.Bundle;
import android.provider.ContactsContract;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {
	TextView textView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		 textView = (TextView) findViewById(R.id.textView);
		 getContacts();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	 void getContacts(){
		ContentResolver cr = getContentResolver();
	    Cursor contactsCursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null);
	    int nameIndex = contactsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
	    int numberIndex = contactsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
	    contactsCursor.moveToFirst();
	    do{
	    	String contactName = contactsCursor.getString(nameIndex);
	    	String contactNumber = contactsCursor.getString(numberIndex);
	    	String oldText = textView.getText().toString();
	    	textView.setText(oldText+"\nName: "+contactName+"- Number: "+contactNumber);
	    }while(contactsCursor.moveToNext());
	   
	    contactsCursor.close();
	 
	 }
}

Complete code for 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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:text=" " 
        android:textAppearance="?android:attr/textAppearanceLarge"/>

</RelativeLayout>

So we learned about displaying contatcts data and fetched the data natively.