Android कॉन्टैक्ट पिकर, एक स्टैंडर्ड और ब्राउज़ किया जा सकने वाला इंटरफ़ेस है. इसकी मदद से, उपयोगकर्ता आपके ऐप्लिकेशन के साथ संपर्क शेयर कर सकते हैं. यह पिकर, Android 17 (एपीआई लेवल 37) या इसके बाद के वर्शन वाले डिवाइसों पर उपलब्ध है. यह पिकर, READ_CONTACTS अनुमति के विकल्प के तौर पर काम करता है और उपयोगकर्ता की निजता को बनाए रखता है. आपका ऐप्लिकेशन, उपयोगकर्ता की पूरी अड्रेस बुक का ऐक्सेस मांगने के बजाय, उन डेटा फ़ील्ड के बारे में बताता है जिनकी उसे ज़रूरत है. जैसे, फ़ोन नंबर या ईमेल पते. इसके बाद, उपयोगकर्ता उन संपर्कों को चुनता है जिन्हें शेयर करना है. इससे आपके ऐप्लिकेशन को सिर्फ़ चुने गए डेटा को पढ़ने का ऐक्सेस मिलता है. इससे आपको डेटा पर ज़्यादा कंट्रोल मिलता है. साथ ही, यूज़र इंटरफ़ेस (यूआई) को बनाए या मैनेज किए बिना, पहले से मौजूद खोज, प्रोफ़ाइल स्विच करने, और एक से ज़्यादा आइटम चुनने की सुविधाओं के साथ, उपयोगकर्ता को बेहतर अनुभव मिलता है.
कॉन्टैक्ट पिकर को इंटिग्रेट करना
कॉन्टैक्ट पिकर को इंटिग्रेट करने के लिए, ContactsPickerSessionContract.ACTION_PICK_CONTACTS इंटेंट का इस्तेमाल करें.
इस इंटेंट के ज़रिए, कॉन्टैक्ट पिकर लॉन्च होता है और यह आपके चुने गए संपर्कों को ऐप्लिकेशन में वापस लाता है.
पुराने ACTION_PICK के मुकाबले, कॉन्टैक्ट पिकर की मदद से अपने ऐप्लिकेशन के लिए एक साथ कई ज़रूरी डेटा फ़ील्ड चुने जा सकते हैं. ऐसा करने के लिए, ContactsPickerSessionContract.EXTRA_REQUESTED_DATA_FIELDS का इस्तेमाल करें. साथ ही, ContactsContract.CommonDataKinds में तय किए गए एमआईएमई टाइप का ArrayList<String> पास करें.
सामान्य एमआईएमई टाइप में ये शामिल हैं:
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
पिकर लॉन्च करना
पिकर लॉन्च करने के लिए, registerForActivityResult का इस्तेमाल StartActivityForResult कॉन्ट्रैक्ट के साथ करें. इंटेंट को इस तरह कॉन्फ़िगर किया जा सकता है कि एक या एक से ज़्यादा विकल्प चुने जा सकें.
// Launcher for the Contact Picker intent
val pickContact = rememberLauncherForActivityResult(StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val resultUri = it.data?.data ?: return@rememberLauncherForActivityResult
// Process the result URI in a background thread to fetch all selected contacts
coroutine.launch {
contacts = processContactPickerResultUri(resultUri, context)
}
}
}
चुनने का मोड
कॉन्टैक्ट पिकर का यूज़र इंटरफ़ेस (यूआई), अनुरोध किए गए डेटा फ़ील्ड के हिसाब से अडजस्ट हो जाता है. इन ज़रूरी शर्तों के आधार पर, उपयोगकर्ता कई फ़ील्ड की ज़रूरत होने पर, संपर्क का पूरा रिकॉर्ड चुन सकते हैं. इसके अलावा, वे संपर्क की जानकारी में से खास डेटा आइटम भी चुन सकते हैं.
कोई एक संपर्क चुनें
इस उदाहरण में, ऐप्लिकेशन सिर्फ़ फ़ोन नंबर का अनुरोध करता है. पिकर, सूची को फ़िल्टर करके सिर्फ़ फ़ोन नंबर वाले संपर्क दिखाएगा. साथ ही, उपयोगकर्ता को कोई खास नंबर चुनने की सुविधा देगा.
// Define the specific contact data fields you need
val requestedFields = arrayListOf(
Email.CONTENT_ITEM_TYPE,
Phone.CONTENT_ITEM_TYPE,
)
// Set up the intent for the Contact Picker
val pickContactIntent = Intent(ACTION_PICK_CONTACTS).apply {
putExtra(EXTRA_USE_SYSTEM_CONTACTS_PICKER, true)
putStringArrayListExtra(
EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS,
requestedFields
)
}
// Launch the picker
pickContact.launch(pickContactIntent)
एक से ज़्यादा संपर्क चुनना
एक से ज़्यादा विकल्प चुनने की सुविधा चालू करने के लिए, Intent.EXTRA_ALLOW_MULTIPLE अतिरिक्त जोड़ें. आपके पास यह तय करने का विकल्प होता है कि कोई उपयोगकर्ता कितने आइटम चुन सकता है.
val requestedFields = arrayListOf(
Email.CONTENT_ITEM_TYPE,
Phone.CONTENT_ITEM_TYPE,
)
// Set up the intent for the Contact Picker
val pickContactIntent = Intent(ACTION_PICK_CONTACTS).apply {
putExtra(EXTRA_USE_SYSTEM_CONTACTS_PICKER, true)
// Enable multi-select
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
// Set limit of selectable contacts
putExtra(EXTRA_PICK_CONTACTS_SELECTION_LIMIT, 5)
// Define the specific contact data fields you need
putStringArrayListExtra(
EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS,
requestedFields
)
// Enable this option to only filter contacts that have all the requested data fields
putExtra(EXTRA_PICK_CONTACTS_MATCH_ALL_DATA_FIELDS, false)
}
// Launch the picker
pickContact.launch(pickContactIntent)
नतीजों को मैनेज करना
जब उपयोगकर्ता अपनी पसंद चुन लेता है, तो सिस्टम RESULT_OK और सेशन यूआरआई दिखाता है. इस यूआरआई से, चुने गए डेटा को कुछ समय के लिए पढ़ने का ऐक्सेस मिलता है.
इस यूआरआई को स्टैंडर्ड ContentResolver का इस्तेमाल करके क्वेरी किया जा सकता है. नतीजे के तौर पर मिलने वाले Cursor में, अनुरोध किए गए डेटा फ़ील्ड शामिल होते हैं. साथ ही, यह ContactsContract.Data के स्कीमा का पालन करता है.
// Data class representing a parsed Contact with selected details.
data class Contact(
val lookupKey: String,
val name: String,
val emails: List<String>,
val phones: List<String>
)
// Helper function to query the content resolver with the URI returned by the Contact Picker.
// Parses the cursor to extract contact details such as name, email, and phone number.
private suspend fun processContactPickerResultUri(
sessionUri: Uri,
context: Context
): List<Contact> = withContext(Dispatchers.IO) {
// Define the columns we want to retrieve from the ContactPicker ContentProvider
val projection = arrayOf(
ContactsContract.Contacts.LOOKUP_KEY,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Data.MIMETYPE, // Type of data (e.g., email or phone)
ContactsContract.Data.DATA1, // The actual data (Phone number / Email string)
)
// We use `LOOKUP_KEY` as a unique ID to aggregate all contact info related to a same person
val contactsMap = mutableMapOf<String, Contact>()
// Note: The Contact Picker Session Uri doesn't support custom selection & selectionArgs.
// We query the URI directly to get the results chosen by the user.
context.contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor ->
// Get the column indices for our requested projection
val lookupKeyIdx = cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY)
val mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE)
val nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY)
val data1Idx = cursor.getColumnIndex(ContactsContract.Data.DATA1)
while (cursor.moveToNext()) {
val lookupKey = cursor.getString(lookupKeyIdx)
val mimeType = cursor.getString(mimeTypeIdx)
val name = cursor.getString(nameIdx) ?: ""
val data1 = cursor.getString(data1Idx) ?: ""
val email = if (mimeType == Email.CONTENT_ITEM_TYPE) data1 else null
val phone = if (mimeType == Phone.CONTENT_ITEM_TYPE) data1 else null
val existingContact = contactsMap[lookupKey]
if (existingContact != null) {
contactsMap[lookupKey] = existingContact.copy(
emails = if (email != null) existingContact.emails + email else existingContact.emails,
phones = if (phone != null) existingContact.phones + phone else existingContact.phones
)
} else {
contactsMap[lookupKey] = Contact(
lookupKey = lookupKey,
name = name,
emails = if (email != null) listOf(email) else emptyList(),
phones = if (phone != null) listOf(phone) else emptyList()
)
}
}
}
return@withContext contactsMap.values.toList()
}
पुराने सिस्टम के साथ काम करने की सुविधा
Android 17 (एपीआई लेवल 37) और इसके बाद के वर्शन को टारगेट करने वाले ऐप्लिकेशन के लिए, सिस्टम अपने-आप मौजूदा Intent.ACTION_PICK इंटेंट को अपग्रेड करता है, ताकि नए कॉन्टैक्ट पिकर इंटरफ़ेस का इस्तेमाल किया जा सके.
अगर आपका ऐप्लिकेशन पहले से ही ACTION_PICK का इस्तेमाल करता है, तो आपको नया यूज़र इंटरफ़ेस (यूआई) पाने के लिए, अपने कोड में बदलाव करने की ज़रूरत नहीं है. हालांकि, नई सुविधाओं का फ़ायदा पाने के लिए, आपको अपने ऐप्लिकेशन को अपडेट करना होगा, ताकि वह ContactsPickerSessionContract.ACTION_PICK_CONTACTS या नए इंटेंट एक्स्ट्रा का इस्तेमाल कर सके. इन सुविधाओं में, संपर्क डेटा के लिए क्वेरी करने पर एक ही Uri मिलना, निजी और वर्क प्रोफ़ाइल के बीच स्विच करना या एक से ज़्यादा डेटा फ़ील्ड के अनुरोध करना शामिल है.
पुराने टारगेट एसडीके पर टेस्टिंग
Android 17 और इसके बाद के वर्शन वाले डिवाइसों पर, नए पिकर के काम करने के तरीके को टेस्ट किया जा सकता है. भले ही, आपका ऐप्लिकेशन एसडीके के किसी पुराने वर्शन को टारगेट करता हो. इसके लिए, आपको अपने ACTION_PICK इंटेंट में EXTRA_USE_SYSTEM_CONTACTS_PICKER बूलियन एक्स्ट्रा जोड़ना होगा.
सबसे सही तरीके
- सिर्फ़ ज़रूरी अनुमतियों का अनुरोध करें: अगर आपके ऐप्लिकेशन को सिर्फ़ एसएमएस भेजने की ज़रूरत है, तो
Phone.CONTENT_ITEM_TYPEका अनुरोध करें. पिकर, उन संपर्कों को अपने-आप फ़िल्टर कर देगा जिनके फ़ोन नंबर नहीं हैं. इससे उपयोगकर्ता को एक साफ़-सुथरा यूज़र इंटरफ़ेस (यूआई) मिलेगा. - हर संपर्क के लिए कई डेटा एंट्री मैनेज करना: अलग-अलग संपर्कों में अक्सर कई ईमेल पते या फ़ोन नंबर होते हैं. यह पक्का करने के लिए कि ये उपयोगकर्ता को साफ़ तौर पर और आसानी से दिखें, हमारा सुझाव है कि इन्हें
ContactsContract.Contacts.LOOKUP_KEYका इस्तेमाल करके ग्रुप करें. इसके अलावा, हर एंट्री के लिए खास लेबल (जैसे, ऑफ़िस या निजी) वापस पाए जा सकते हैं. इससे आपके ऐप्लिकेशन के इंटरफ़ेस में, ज़्यादा सटीक विकल्प चुनने की सुविधा मिलती है. - डेटा को तुरंत सेव करें: सेशन यूआरआई, कुछ समय के लिए पढ़ने की अनुमति देता है. अगर आपको बाद में इस संपर्क जानकारी को ऐक्सेस करना है (ऐप्लिकेशन की प्रोसेस बंद होने के बाद), तो आपके ऐप्लिकेशन को संपर्क डेटा को सेव रखना होगा.
- खाते में मौजूद डेटा पर भरोसा न करें: उपयोगकर्ता की निजता की सुरक्षा और फ़िंगरप्रिंटिंग को रोकने के लिए, खाते से जुड़े मेटाडेटा को नतीजों से हटा दिया जाता है.