Pick Contact | Android Studio | Kotlin

Implement Contact Pick feature in and Android App

To allow the user to pick a contact from the phone's contacts list, we can use contact intent. You will get all information of the contact e.g. Name, Phone Number(s), Address, Thumbnail, Email, etc. You can use get the specific information according to your requirement. To pick a contact we need to READ_CONTACTS permission.

Check for Java



Video Tutorial:

Add permission in AndroidMenifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.blogspot.atifsoftwares.pickcontact">

    <!--Read contact permission-->
    <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/Theme.PickContact">
        <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>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    android:padding="10dp"
    tools:context=".MainActivity">
    <!--ImageView: Show contact thumbnail-->
    <ImageView
        android:id="@+id/thumbnailIv"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:src="@drawable/ic_person"
        android:layout_centerHorizontal="true"/>
    <!--TextView: Show contact info e.g. name, phone(s) etc-->
    <TextView
        android:id="@+id/contactTv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/thumbnailIv"/>
    <!--FloatingActionButton: Click to begin contact pick-->
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/addFab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:src="@drawable/ic_person_add"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"/>

</RelativeLayout>

MainActivity.kt

package com.blogspot.atifsoftwares.contactpick

import android.content.Intent
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.ContactsContract
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.blogspot.atifsoftwares.contactpick.databinding.ActivityMainBinding
import java.util.jar.Manifest

class MainActivity : AppCompatActivity() {

    //view binding
    lateinit var binding: ActivityMainBinding

    //contact permission code
    private val CONTACT_PERMISSION_CODE = 1;
    //contact pick code
    private val CONTACT_PICK_CODE = 2

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //handle click, to pick contact
        binding.addFab.setOnClickListener {
            //check permission allowed or not
            if (checkContactPermission()){
                //allowed
                pickContact()
            }
            else{
                //not allowed, request
                requestContactPermission()
            }
        }
    }


    private fun checkContactPermission(): Boolean{
        //check if permission was granted/allowed or not, returns true if granted/allowed, false if not
        return  ContextCompat.checkSelfPermission(
            this,
            android.Manifest.permission.READ_CONTACTS
        ) == PackageManager.PERMISSION_GRANTED
    }

    private fun requestContactPermission(){
        //request the READ_CONTACTS permission
        val permission = arrayOf(android.Manifest.permission.READ_CONTACTS)
        ActivityCompat.requestPermissions(this, permission, CONTACT_PERMISSION_CODE)
    }

    private fun pickContact(){
        //intent ti pick contact
        val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
        startActivityForResult(intent, CONTACT_PICK_CODE)
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        //handle permission request results || calls when user from Permission request dialog presses Allow or Deny
        if (requestCode == CONTACT_PERMISSION_CODE){
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //permission granted, can pick contact
                pickContact()
            }
            else{
                //permission denied, cann't pick contact, just show message
                Toast.makeText(this, "Permission denied...", Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        //handle intent results || calls when user from Intent (Contact Pick) picks or cancels pick contact
        if (resultCode == RESULT_OK){
            //calls when user click a contact from contacts (intent) list
            if (requestCode == CONTACT_PICK_CODE){
                binding.contactTv.text = ""

                val cursor1: Cursor
                val cursor2: Cursor?

                //get data from intent
                val uri = data!!.data
                cursor1 = contentResolver.query(uri!!, null, null, null, null)!!
                if (cursor1.moveToFirst()){
                    //get contact details
                    val contactId = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts._ID))
                    val contactName = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
                    val contactThumbnail = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.PHOTO_THUMBNAIL_URI))
                    val idResults = cursor1.getString(cursor1.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))
                    val idResultHold = idResults.toInt()
                    //set details: contact id, contact name, image
                    binding.contactTv.append("ID: $contactId")
                    binding.contactTv.append("\nName: $contactName")
                    //set image, first check if uri/thumbnail is not null
                    if (contactThumbnail != null){
                        binding.thumbnailIv.setImageURI(Uri.parse(contactThumbnail))
                    }
                    else{
                        binding.thumbnailIv.setImageResource(R.drawable.ic_person)
                    }

                    //check if contact has a phone number or not
                    if (idResultHold == 1){
                        cursor2 = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+contactId,
                        null,
                        null
                        )
                        //a contact may have multiple phone numbers
                        while (cursor2!!.moveToNext()){
                            //get phone number
                            val contactNumber = cursor2.getString(cursor2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                            //set phone number
                            binding.contactTv.append("\nPhone: $contactNumber")

                        }
                        cursor2.close()
                    }
                    cursor1.close()
                }
            }

        }
        else{
            //cancelled picking contact
            Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show()
        }
    }


}

That's it, tun project and check, here are some screenshots...

Pick Contact | Android Studio | Java
Pick Contact | Android Studio | Java



Comments

Popular posts from this blog

Manage External Storage Permission | Android Studio | Kotlin

Manage External Storage Permission | Android Studio | Java

Add a Back Button to Action Bar Android Studio (Kotlin)