17

How can I show the list of contacts in phonebook on a click of a button and then select one of the contacts from it and then retrieve its contact number?

I don’t want to make my custom list. Is there a way to use Android's built-in functionality?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mdanishs
  • 1,996
  • 8
  • 24
  • 50

7 Answers7

20

TRY THIS-->

   setContentView(R.layout.main);

   contactNumber = (TextView)findViewById(R.id.contactnumber);

   Button buttonPickContact = (Button)findViewById(R.id.pickcontact);
   buttonPickContact.setOnClickListener(new Button.OnClickListener(){

   @Override
    public void onClick(View arg0) {
   // TODO Auto-generated method stub


   Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
   intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
   startActivityForResult(intent, 1);             


    }});
   }

   @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);

   if(requestCode == RQS_PICK_CONTACT){
   if(resultCode == RESULT_OK){
    Uri contactData = data.getData();
    Cursor cursor =  managedQuery(contactData, null, null, null, null);
    cursor.moveToFirst();

      String number =       cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));

      //contactName.setText(name);
      contactNumber.setText(number);
      //contactEmail.setText(email);
     }
     }
     }
     }

EDIT XML ADDED;

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

      <Button
        android:id="@+id/pickcontact"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Pick Contact" />

      <TextView
       android:id="@+id/contactnumber"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" />

 </LinearLayout>
Ger
  • 889
  • 1
  • 12
  • 21
Mohit
  • 2,940
  • 2
  • 24
  • 32
  • @Dani if it worked for you can select it as an answer to help someone facing same issue in future. – Mohit Aug 25 '12 at 16:54
  • 1
    Its an argument that has to be passed. When you receive the result Intent, the callback provides the same argument so that your app can properly identify the result and determine how to handle it. Reason you have to change is that you might have used PICK_CONTACT instead of RQS_ PICK_CONTACT. Think of this as a Token that u passing and getting back to identify your request. – Mohit May 04 '14 at 19:08
  • 1
    managedQuery() is depricated, now it's best practice to use getContentResolver().query() – Bibaswann Bandyopadhyay Aug 27 '15 at 07:56
12

I was doing the same thing in my application, and this is how to start a new intent for showing the list

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);

And this is how to process the result:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PICK_CONTACT) {
        if (resultCode == RESULT_OK) {
            Uri contactData = data.getData();
            String number = "";
            Cursor cursor = getContentResolver().query(contactData, null, null, null, null);
            cursor.moveToFirst();
            String hasPhone = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.HAS_PHONE_NUMBER));
            String contactId = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID));
            if (hasPhone.equals("1")) {
                Cursor phones = getContentResolver().query
                        (ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                        + " = " + contactId, null, null);
                while (phones.moveToNext()) {
                    number = phones.getString(phones.getColumnIndex
                    (ContactsContract.CommonDataKinds.Phone.NUMBER)).replaceAll("[-() ]", "");
                }
                phones.close();

            // Do something with the number
            }
            else {
                Toast.makeText(getApplicationContext(), "This contact has no phone number", Toast.LENGTH_LONG).show();
            }
            cursor.close();
            }
        }
    }
}

PICK_CONTACT is a constant defined in the class.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bibaswann Bandyopadhyay
  • 3,389
  • 2
  • 31
  • 30
3
Intent i=new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);

startActivityForResult(i, PICK_REQUEST);

The Intent delivered to your onActivityResult() method will contain the Uri of the chosen contact -- you will get this by calling getData() on that Intent.

Here is a sample project that demonstrates this, with the logic being implemented in a retained fragment, so we hang onto the selected contact across configuration changes (e.g., user rotating the screen).

You can also use ACTION_GET_CONTENT for this, and I think that's the more modern pattern, though ACTION_PICK certainly works and is all I have sample code for at the time of this writing. If you are reading this in the future (hi, future!), it's possible that the linked-to sample has been updated to use ACTION_GET_CONTENT.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
1

For Kotlin, the request code for fetching a contact

private val REQUEST_CONTACT = 201

Intent to launch the phone book

private fun fetchPhoneNo() {
    val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
    startActivityForResult(intent, REQUEST_CONTACT)
}

Get the phone number in onActivityResult

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == REQUEST_CONTACT && data?.data != null) {
        val contactUri = data.data;
        val crContacts = contentResolver.query(contactUri, null, null, null, null);
        crContacts.moveToFirst()
        val id = crContacts.getString(crContacts.getColumnIndex(ContactsContract.Contacts._ID));
        if (Integer.parseInt(crContacts.getString(crContacts.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
            val crPhones =
               contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                     null,
                                     ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                       + " = ?",
                                     arrayOf(id),
                                     null)
            crPhones.moveToFirst()
            var phoneNo = crPhones.getString(
                crPhones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
            crPhones.close()
        }
        crContacts.close()
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Raja Jawahar
  • 6,742
  • 9
  • 45
  • 56
1

Here is the working code which I tried in API Level 29+

Step 1: Add Permission in AndroidManifest.xml

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

Step 2: Code to open the contacts dialog on a button click

private static final int REQ_PICK_CONTACT = 3;
private static final int CONTACT_PERMISSION_CODE = 1;

// Onclick handler
public void openContacts(View view) {
    if(checkContactPermission()) {
        openContactsDialog();
    } else {
        requestContactPermission();
    }
}

// If permission is granted, then open contact box
private void openContactsDialog() {
    Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
    startActivityForResult(intent, REQ_PICK_CONTACT);
}

// Check if the user has the permission granted
private boolean checkContactPermission() {
    boolean result = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
    return result;
}

// Invoke request permission dialog
private void requestContactPermission() {
    String[] permission = {Manifest.permission.READ_CONTACTS};
    ActivityCompat.requestPermissions(this, permission, CONTACT_PERMISSION_CODE);
}

// After the permission is granted, open the contact dialog
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if(requestCode == CONTACT_PERMISSION_CODE) {
        if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            openContactsDialog();
        }
    }
}

Step 3: Handle contact selection

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQ_PICK_CONTACT) {
        if (resultCode == RESULT_OK) {
            Cursor cursor1, cursor2;
            Uri uri = data.getData();

            cursor1 = getContentResolver().query(uri, null, null, null, null);
            if(cursor1.moveToFirst()) {
                String contactId = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts._ID));
                String contactName = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                String hasNumber = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

                if("1".equals(hasNumber)) {
                    cursor2 = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + contactId, null, null);
                    while(cursor2.moveToNext()) {
                        String contactNumber = cursor2.getString(cursor2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        // Use contactName and contactNumber for your purposes
                    }
                    cursor2.close();
                }
            }
            cursor1.close();
            //edtName.setText(contactName);
            //edtNumber.setText(number);
        }
    }
}

Solution courtesy: Pick Contact | Android Studio | Java (no audio whatsoever and very little annotation)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Akhil
  • 2,602
  • 23
  • 36
0

In the Nexus 5X emulator that I tested this with:

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
startActivityForResult(intent, 1);

Or:

Uri uri = Uri.parse("content://contacts");
Intent intent = new Intent(Intent.ACTION_PICK, uri);
intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
startActivityForResult(intent, 1);

did not work for all contacts. I don't know why. But this works:

Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, 1);
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
David
  • 2,129
  • 25
  • 34
0

Add the PICK_CONTACT field:

private final int PICK_CONTACT = 55;

In onCreate():

viewPhonebook.setOnClickListener(v -> {
    try {
        Uri uri = Uri.parse("content://contacts");
        Intent intent = new Intent(Intent.ACTION_PICK, uri);
        intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
        startActivityForResult(intent, PICK_CONTACT);
    }
    catch (Exception e) {
        e.printStackTrace();
    }
});

In onActivityResult():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case PICK_CONTACT:
                Uri contactData = data.getData();
                Cursor cursor = managedQuery(contactData, null, null, null, null);
                cursor.moveToFirst();
                String number = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
                String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                edtName.setText(contactName);
                edtNumber.setText(number);
                break;
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Shahab Saalami
  • 862
  • 10
  • 18