Pick Contact - Android Studio - Kotlin

Implement the 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.




Video Tutorial:

Code:

Add permission in AndroidManifest.xml:

<?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.technifysoft.myapplication

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.provider.ContactsContract
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.technifysoft.myapplication.databinding.ActivityMainBinding

class MainActivityKt : AppCompatActivity(){

    private lateinit var binding: ActivityMainBinding

    //UI Views
    private lateinit var thumbnailIv: ImageView
    private lateinit var contactTv: TextView
    private lateinit var addContactFab: FloatingActionButton

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }

        //init UI Views
        thumbnailIv = findViewById(R.id.thumbnailIv)
        contactTv = findViewById(R.id.contactTv)
        addContactFab = findViewById(R.id.addFab)

        //handle click, to pick contact
        addContactFab.setOnClickListener {
            //first we need to check read contact permission
            if (checkContactPermission()) {
                //permission granted, pick contact
                pickContactIntent()
            } else {
                //permission not granted, request
                requestContactPermission()
            }
        }
    }

    private fun checkContactPermission(): Boolean {
        //check if contact permission was granted or not

        return ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.READ_CONTACTS
        ) == (PackageManager.PERMISSION_GRANTED) //true if permission granted, false if not
    }

    private fun requestContactPermission() {
        //permissions to request
        val permission = Manifest.permission.READ_CONTACTS

        requestPermissionLauncher.launch(permission)
    }

    private fun pickContactIntent() {
        //intent to pick contact
        val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
        contactPickerLauncher.launch(intent)
    }

    private val requestPermissionLauncher = registerForActivityResult(
        RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // Permission is granted. Continue the action or workflow in your app.
            pickContactIntent()
        } else {
            // Explain to the user that the feature is unavailable because the features requires a permission that the user has denied.
            Toast.makeText(this, "Permission denied...", Toast.LENGTH_SHORT).show()
        }
    }

    private val contactPickerLauncher = registerForActivityResult(
        StartActivityForResult()
    ) { result: ActivityResult ->
        
        if (result.resultCode == RESULT_OK) {
            //handle intent results
            val data = result.data
            if (data != null) {
                //calls when user click a contact from list
                val uri = data.data
                //get data from intent
                val 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()

                    contactTv.append("ID: $contactId")
                    contactTv.append("\nName: $contactName")

                    if (idResultHold == 1) {
                        val 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 details
                            contactTv.append("\nPhone: $contactNumber")
                            //before setting image, check if have or not
                            if (contactThumbnail != null) {
                                thumbnailIv.setImageURI(contactThumbnail.toUri())
                            } else {
                                thumbnailIv.setImageResource(R.drawable.ic_person)
                            }
                        }
                        cursor2.close()
                    }
                    cursor1.close()
                }
            }
        } else {
            //calls when user click back button | don't pick contact
            Toast.makeText(this, "No contact selected...", Toast.LENGTH_SHORT).show()
        }
    }

}

Screenshots:

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



Comments

Popular posts from this blog

Picture In Picture - Android Studio - Kotlin

Manage External Storage Permission - Android Studio - Kotlin

How to add AIDL folder | Android Studio