Overview
In this tutorial, we show you how to get all contacts information in Android, then display them in ListView. We will create a 'Show Contacts' Button widget. When user clicks the 'Show Contacts' button for fetch all phone, display name contacts information into ListView.Follow the steps mentioned below to develop this application.
Project Structure
Creating the Android Studio Project
Open Android Studio and create a new project with an empty activity called MainActivity.javaAdding READ_CONTACTS Permissions in AndroidManifest.xml
Open AndroidManifest.xml file and add READ_CONTACTS permission inside it. This code snippet is shown below.<uses-permission android:name="android.permission.READ_CONTACTS" />AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jackrutorial.readcontactsexample"> <uses-permission android:name="android.permission.READ_CONTACTS" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
MainActivity.java
We create the requestContactPermission() method to to request read contact permission. Please view detail Android request contact permission Example. This code snippet is shown below.public void requestContactPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_CONTACTS)) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Read contacts access needed"); builder.setPositiveButton(android.R.string.ok, null); builder.setMessage("Please enable access to contacts."); builder.setOnDismissListener(new DialogInterface.OnDismissListener() { @TargetApi(Build.VERSION_CODES.M) @Override public void onDismiss(DialogInterface dialog) { requestPermissions( new String[] {android.Manifest.permission.READ_CONTACTS} , PERMISSIONS_REQUEST_READ_CONTACTS); } }); builder.show(); } else { ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS); } } else { getContacts(); } } else { getContacts(); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case PERMISSIONS_REQUEST_READ_CONTACTS: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { getContacts(); } else { Toast.makeText(this, "You have disabled a contacts permission", Toast.LENGTH_LONG).show(); } return; } } }Create the getContacts() method, to get all Contacts.
private void getContacts(){ ContentResolver contentResolver = getContentResolver(); String contactId = null; String displayName = null; contactsInfoList = new ArrayList<ContactsInfo>(); Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"); if (cursor.getCount() > 0) { while (cursor.moveToNext()) { int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))); if (hasPhoneNumber > 0) { ContactsInfo contactsInfo = new ContactsInfo(); contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); contactsInfo.setContactId(contactId); contactsInfo.setDisplayName(displayName); Cursor phoneCursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contactId}, null); if (phoneCursor.moveToNext()) { String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); contactsInfo.setPhoneNumber(phoneNumber); } phoneCursor.close(); contactsInfoList.add(contactsInfo); } } } cursor.close(); dataAdapter = new MyCustomAdapter(MainActivity.this, R.layout.contact_info, contactsInfoList); listView.setAdapter(dataAdapter); }In the snippet code above, we get all contacts and to fill the ArrayList in each while loop add a ContactsInfo object to ArrayList. Then we set adapter with our custom layout xml.
Complete MainActivity.java Code
package com.jackrutorial.readcontactsexample; import android.annotation.TargetApi; import android.app.AlertDialog; import android.content.ContentResolver; import android.content.DialogInterface; import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Build; import android.provider.ContactsContract; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { public static final int PERMISSIONS_REQUEST_READ_CONTACTS = 1; MyCustomAdapter dataAdapter = null; ListView listView; Button btnGetContacts; List<ContactsInfo> contactsInfoList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnGetContacts = (Button) findViewById(R.id.btnGetContacts); listView = (ListView) findViewById(R.id.lstContacts); listView.setAdapter(dataAdapter); btnGetContacts.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { requestContactPermission(); } }); } private void getContacts(){ ContentResolver contentResolver = getContentResolver(); String contactId = null; String displayName = null; contactsInfoList = new ArrayList<ContactsInfo>(); Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC"); if (cursor.getCount() > 0) { while (cursor.moveToNext()) { int hasPhoneNumber = Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))); if (hasPhoneNumber > 0) { ContactsInfo contactsInfo = new ContactsInfo(); contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); contactsInfo.setContactId(contactId); contactsInfo.setDisplayName(displayName); Cursor phoneCursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{contactId}, null); if (phoneCursor.moveToNext()) { String phoneNumber = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); contactsInfo.setPhoneNumber(phoneNumber); } phoneCursor.close(); contactsInfoList.add(contactsInfo); } } } cursor.close(); dataAdapter = new MyCustomAdapter(MainActivity.this, R.layout.contact_info, contactsInfoList); listView.setAdapter(dataAdapter); } public void requestContactPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(this, android.Manifest.permission.READ_CONTACTS)) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Read contacts access needed"); builder.setPositiveButton(android.R.string.ok, null); builder.setMessage("Please enable access to contacts."); builder.setOnDismissListener(new DialogInterface.OnDismissListener() { @TargetApi(Build.VERSION_CODES.M) @Override public void onDismiss(DialogInterface dialog) { requestPermissions( new String[] {android.Manifest.permission.READ_CONTACTS} , PERMISSIONS_REQUEST_READ_CONTACTS); } }); builder.show(); } else { ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, PERMISSIONS_REQUEST_READ_CONTACTS); } } else { getContacts(); } } else { getContacts(); } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case PERMISSIONS_REQUEST_READ_CONTACTS: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { getContacts(); } else { Toast.makeText(this, "You have disabled a contacts permission", Toast.LENGTH_LONG).show(); } return; } } } }
ContactsInfo.java
Create a ContactsInfo class under com.jackrutorial.readcontactsexample package and write the following code in it.package com.jackrutorial.readcontactsexample; public class ContactsInfo { private String contactId; private String displayName; private String phoneNumber; public String getContactId() { return contactId; } public void setContactId(String contactId) { this.contactId = contactId; } public String getDisplayName() { return displayName; } public void setDisplayName(String displayName) { this.displayName = displayName; } public String getPhoneNumber() { return phoneNumber; } public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; } }
Custom adapter Class
Create a MyCustomAdapter class under com.jackrutorial.readcontactsexample package and write the following code in it.package com.jackrutorial.readcontactsexample; import android.content.Context; import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.TextView; import java.util.List; public class MyCustomAdapter extends ArrayAdapter{ private List contactsInfoList; private Context context; public MyCustomAdapter(@NonNull Context context, int resource, @NonNull List objects) { super(context, resource, objects); this.contactsInfoList = objects; this.context = context; } private class ViewHolder { TextView displayName; TextView phoneNumber; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { LayoutInflater vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.contact_info, null); holder = new ViewHolder(); holder.displayName = (TextView) convertView.findViewById(R.id.displayName); holder.phoneNumber = (TextView) convertView.findViewById(R.id.phoneNumber); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } ContactsInfo contactsInfo = contactsInfoList.get(position); holder.displayName.setText(contactsInfo.getDisplayName()); holder.phoneNumber.setText(contactsInfo.getPhoneNumber()); return convertView; } }
Design the Layouts
Change the activity_main.xml layout to the following.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:layout_marginBottom="300px" > <Button android:id="@+id/btnGetContacts" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Contacts" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Contacts" android:padding="5dp" android:textStyle="bold" android:layout_marginBottom="10dp" /> <ListView android:id="@+id/lstContacts" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> </android.support.constraint.ConstraintLayout>Create the contact_info.xml file under res/layout/ folder to the following.
Click on app > res > layout > Right Click on layout. Select New > XML > Layout XML File. In the dialog that appears, enter contact_info as name for the file. Then change the contact_info.xml layout to the following.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/displayName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" /> <TextView android:id="@+id/phoneNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="5dp" /> </LinearLayout>
Run this application with the Android Emulator
You can run this app from an Android Studio project. Or you can run this app that's been installed on the emulator as you would run any app on a device. To start the emulator and run this app in your project.- Open Android Studio project and click Run.
- In the Select Deployment Target dialog, select an existing emulator definition, and then click OK.
- If you don’t see a definition you want to use, click Create New Virtual Device to launch the AVD Manager. After you define a new AVD, in the Select Deployment Target dialog (Android 6.0 API level 23 or higher), click OK.
- If you want to use this emulator definition as the default for your project, select Use same selection for future launches.