Android makes the full database of contact information available to any application that has been granted the READ_CONTACTS permission.
The Contacts Contract Provider provides an extensible database of contact-related information. This allows users to specify multiple sources for their contact information. More importantly, it allows developers to arbitrarily extend the data stored against each contact, or even become an alternative provider for contacts and contact details.
Rather than providing a single, fully defi ned table of contact detail columns, the Contacts Contract
provider uses a three-tier data model to store data, associate it with a contact, and aggregate it to a
single person using the following ContactsContract subclasses:
1. Data — Each row in the underlying table defi nes a set of personal data (phone numbers, email addresses, and so on), separated by MIME type. Although there is a predefined set of common column names for each personal data-type available (along with the appropriate MIME types from subclasses within ContactsContract.CommonDataKinds), this table can be used to store any value.The kind of data stored in a particular row is determined by the MIME type specifi ed for that row. A series of generic columns is then used to store up to 15 different pieces of data varying by MIME type. When adding new data to the Data table, you specify a Raw Contact to which a set of data
will be associated.
2. RawContacts — From Android 2.0 (API level 5) forward, users can add multiple contact account providers to their device. Each row in the Raw Contacts table defi nes an account to which a set of Data values is associated.
3. Contacts — The Contacts table aggregates rows from Raw Contacts that all describe the same person.
To access any contact details, you need to include the READ_CONTACTS uses-permission in your application manifest:
Use the Content Resolver to query any of the three Contact Contracts Providers previously described using their respective CONTENT_URI static constants. Each class includes their column names as static properties.
MainActivity.java
package com.example.contactcontentprovider; import android.app.Activity; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button but = (Button) findViewById(R.id.readBut); but.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub read(); } }); } @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; } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); finish(); } public void read() { Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show(); // Create a projection that limits the result Cursor // to the required columns. String[] projection = { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME }; // Get a Cursor over the Contacts Provider. Cursor cursor = getContentResolver().query( ContactsContract.Contacts.CONTENT_URI, projection, null, null, null); // Get the index of the columns. int nameIdx = cursor .getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME); int idIdx = cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID); // Initialize the result set. String[] result = new String[cursor.getCount()]; // Iterate over the result Cursor. while (cursor.moveToNext()) { // Extract the name. String name = cursor.getString(nameIdx); // Extract the unique ID. String id = cursor.getString(idIdx); result[cursor.getPosition()] = name + "(" + id + ")"; Toast.makeText(this, name + "(" + id + ")", Toast.LENGTH_LONG) .show(); } } }
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" 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" > <Button android:id="@+id/readBut" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginTop="112dp" android:text="Read" /> </RelativeLayout>
AndoridManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.contactcontentprovider" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.contactcontentprovider.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>