כלי בחירת אנשי הקשר ב-Android הוא ממשק סטנדרטי שמאפשר למשתמשים לשתף אנשי קשר עם האפליקציה שלכם. הכלי זמין במכשירים עם Android 17 ואילך, והוא מציע חלופה ששומרת על הפרטיות להרשאה הרחבה READ_CONTACTS. במקום לבקש גישה לכל פנקס הכתובות של המשתמש, האפליקציה מציינת את שדות הנתונים שהיא צריכה, כמו מספרי טלפון או כתובות אימייל, והמשתמש בוחר אנשי קשר ספציפיים לשיתוף. ההרשאה הזו מעניקה לאפליקציה גישת קריאה רק לנתונים שנבחרו, וכך מאפשרת שליטה מדויקת תוך שמירה על חוויית משתמש עקבית עם יכולות מובנות של חיפוש, מעבר בין פרופילים ובחירה מרובה, בלי שתצטרכו ליצור או לתחזק את ממשק המשתמש.
שילוב בורר אנשי הקשר
כדי לשלב את הכלי לבחירת אנשי קשר, משתמשים בכוונה Intent.ACTION_PICK_CONTACTS.
הכוונה הזו מפעילה את הכלי לבחירת אנשי קשר ומחזירה את אנשי הקשר שנבחרו לאפליקציה.
בניגוד לACTION_PICK מדור קודם, כלי בחירת אנשי הקשר מאפשר לציין כמה שדות נתונים שהאפליקציה צריכה בו-זמנית. כדי לעשות את זה, משתמשים ב-Intent.EXTRA_REQUESTED_DATA_FIELDS ומעבירים ArrayList<String> של סוגי MIME שמוגדרים ב-ContactsContract.CommonDataKinds.
סוגי MIME נפוצים:
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
הפעלת הכלי לבחירה
משתמשים ב-registerForActivityResult עם החוזה StartActivityForResult כדי להפעיל את הכלי לבחירת חשבונות. אתם יכולים להגדיר את הכוונה כך שתאפשר בחירה של אפשרות אחת או כמה אפשרויות.
בחירת איש קשר אחד
בדוגמה הזו, האפליקציה מבקשת רק מספרי טלפון. הכלי לבחירת אנשי קשר יסנן את הרשימה כך שיוצגו רק אנשי קשר עם מספרי טלפון, ויאפשר למשתמש לבחור מספר ספציפי.
Kotlin
// Define the specific data fields you need
val requestedFields = arrayListOf(
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
)
// Set up the intent
val pickContactIntent = Intent(Intent.ACTION_PICK_CONTACTS).apply {
type = ContactsContract.Contacts.CONTENT_TYPE
putStringArrayListExtra(Intent.EXTRA_REQUESTED_DATA_FIELDS, requestedFields)
}
// Launch the picker
pickContactLauncher.launch(pickContactIntent)
Java
// Define the specific data fields you need
ArrayList<String> requestedFields = new ArrayList<>();
requestedFields.add(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
// Set up the intent
Intent pickContactIntent = new Intent(Intent.ACTION_PICK_CONTACTS);
pickContactIntent.setType(ContactsContract.Contacts.CONTENT_TYPE);
pickContactIntent.putStringArrayListExtra(Intent.EXTRA_REQUESTED_DATA_FIELDS,
requestedFields);
// Launch the picker
pickContactLauncher.launch(pickContactIntent);
בחירה של כמה אנשי קשר
כדי להפעיל בחירה מרובה, מוסיפים את התוסף Intent.EXTRA_ALLOW_MULTIPLE. אפשר להגביל את מספר הפריטים שמשתמש יכול לבחור.
Kotlin
val requestedFields = arrayListOf(
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE,
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
)
val pickMultipleIntent = Intent(Intent.ACTION_PICK_CONTACTS).apply {
type = ContactsContract.Contacts.CONTENT_TYPE
putStringArrayListExtra(Intent.EXTRA_REQUESTED_DATA_FIELDS, requestedFields)
// Enable multi-select
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
// Optional: Set a custom limit (max 50 recommended)
putExtra(Intent.EXTRA_SELECTION_LIMIT, 10)
}
pickMultipleLauncher.launch(pickMultipleIntent)
טיפול בתוצאות
כשהמשתמש משלים את הבחירה, המערכת מחזירה RESULT_OK ו-URI של סשן. ה-URI הזה מעניק גישת קריאה זמנית לנתונים שנבחרו.
אפשר לשלוח שאילתה ל-URI הזה באמצעות ContentResolver סטנדרטי. הערך
Cursor שמתקבל מכיל את שדות הנתונים המבוקשים ופועל לפי הסכימה של
ContactsContract.Data.
Kotlin
private val pickContactLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// The result data contains the Session URI
val sessionUri = result.data?.data
sessionUri?.let { uri ->
processSelectedContacts(uri)
}
} else {
// User cancelled the picker
}
}
private fun processSelectedContacts(sessionUri: Uri) {
// Define the projection (columns) you want to retrieve
val projection = arrayOf(
ContactsContract.Data.CONTACT_ID,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Data.MIMETYPE,
ContactsContract.Data.DATA1 // Generic data column (Phone number, Email, etc.)
)
contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor ->
val mimeTypeIdx = cursor.getColumnIndex(ContactsContract.Data.MIMETYPE)
val dataIdx = cursor.getColumnIndex(ContactsContract.Data.DATA1)
val nameIdx = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME_PRIMARY)
while (cursor.moveToNext()) {
val mimeType = cursor.getString(mimeTypeIdx)
val dataValue = cursor.getString(dataIdx)
val name = cursor.getString(nameIdx)
when (mimeType) {
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE -> {
Log.d("ContactPicker", "Picked Phone: $dataValue for $name")
}
ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE -> {
Log.d("ContactPicker", "Picked Email: $dataValue for $name")
}
}
}
}
}
תאימות לאחור
באפליקציות שמטרגטות ל-Android 17 ומעלה, המערכת משדרגת אוטומטית את כוונת Intent.ACTION_PICK הקיימת לשימוש בממשק החדש של בוחר אנשי הקשר.
אם האפליקציה שלך כבר משתמשת ב-ACTION_PICK, לא צריך לשנות את הקוד כדי לקבל את ממשק המשתמש החדש. עם זאת, כדי ליהנות מתכונות חדשות, כמו קבלת Uri יחיד לשאילתת נתוני אנשי קשר, מעבר בין פרופילים אישיים ופרופילים של מקומות עבודה או בקשות מרובות של שדות נתונים, צריך לעדכן את ההטמעה לשימוש ב-Intent.ACTION_PICK_CONTACTS או בתוספים החדשים של הכוונות.
בדיקה בגרסאות ישנות יותר של SDK
אתם יכולים לבדוק את ההתנהגות החדשה של הכלי לבחירת תמונות במכשירים עם Android 17 ומעלה, גם אם האפליקציה שלכם מיועדת לגרסת SDK נמוכה יותר. לשם כך, צריך להוסיף את הערך הבוליאני EXTRA_USE_SYSTEM_CONTACTS_PICKER extra ל-intent ACTION_PICK.
שיטות מומלצות
- מבקשים רק את מה שצריך: אם האפליקציה צריכה רק לשלוח SMS,
מבקשים
Phone.CONTENT_ITEM_TYPE. הכלי לבחירת אנשי קשר יסנן באופן אוטומטי אנשי קשר שאין להם מספרי טלפון, וכך הממשק יהיה נקי יותר למשתמש. - שמירת הנתונים באופן מיידי: ה-URI של הסשן מעניק הרשאת קריאה זמנית. אם תצטרכו לגשת לפרטי הקשר האלה בהמשך (אחרי שתהליך האפליקציה יופסק), האפליקציה שלכם תצטרך לשמור את נתוני הקשר.
- אל תסתמכו על נתוני החשבון: כדי להגן על פרטיות המשתמשים ולמנוע טכניקות של זיהוי ייחודי (fingerprinting), המערכת מסירה מהתוצאות מטא-נתונים שספציפיים לחשבון.