أداة اختيار جهات الاتصال

أداة اختيار جهات الاتصال في 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_TYPE
  • ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
  • ContactsContract.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) للجلسة. يمنح معرّف الموارد الموحّد هذا إذن قراءة مؤقتًا للبيانات المحدّدة.

يمكنك طلب البحث عن معرّف الموارد الموحّد هذا باستخدام 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")
                }
            }
        }
    }
}

التوافق مع الأنظمة القديمة

بالنسبة إلى التطبيقات التي تستهدف الإصدار 17 من نظام التشغيل Android والإصدارات الأحدث، سيعدّل النظام تلقائيًا الغرض الحالي Intent.ACTION_PICK لاستخدام واجهة "أداة اختيار جهات الاتصال" الجديدة.

إذا كان تطبيقك يستخدم ACTION_PICK، لن تحتاج إلى تغيير الرمز لتلقّي واجهة المستخدم الجديدة. ومع ذلك، للاستفادة من الميزات الجديدة، مثل تلقّي Uri واحد للاستعلام عن بيانات جهات الاتصال أو التبديل بين ملفات العمل والملفات الشخصية أو طلبات حقول البيانات المتعددة، يجب تعديل عملية التنفيذ لاستخدام Intent.ACTION_PICK_CONTACTS أو إضافات الأهداف الجديدة.

الاختبار على حِزم SDK القديمة

يمكنك اختبار سلوك أداة الاختيار الجديدة على الأجهزة التي تعمل بالإصدار 17 من نظام التشغيل Android والإصدارات الأحدث حتى إذا كان تطبيقك يستهدف إصدارًا أقدم من حزمة تطوير البرامج (SDK)، وذلك عن طريق إضافة قيمة EXTRA_USE_SYSTEM_CONTACTS_PICKER المنطقية الإضافية إلى الغرض ACTION_PICK.

أفضل الممارسات

  • طلب الأذونات اللازمة فقط: إذا كان تطبيقك يحتاج فقط إلى إرسال رسالة SMS، اطلب الإذن Phone.CONTENT_ITEM_TYPE. سيستبعد المنتقي تلقائيًا جهات الاتصال التي لا تتضمّن أرقام هواتف، ما يؤدي إلى توفير واجهة مستخدم أكثر سلاسة.
  • الاحتفاظ بالبيانات على الفور: يمنح معرّف الموارد المنتظم للجلسة إذن قراءة مؤقتًا. إذا كنت بحاجة إلى الوصول إلى معلومات الاتصال هذه لاحقًا (بعد إيقاف عملية تطبيقك)، يجب أن يحتفظ تطبيقك ببيانات جهات الاتصال.
  • عدم الاعتماد على بيانات الحساب: لحماية خصوصية المستخدم ومنع إنشاء بصمة رقمية، تتم إزالة البيانات الوصفية الخاصة بالحساب من النتائج.