أخبار المنتجات
منتقي جهات الاتصال: مشاركة جهات الاتصال مع الحفاظ على الخصوصية أولاً
مدة القراءة: 4 دقائق
تظل الخصوصية وتحكّم المستخدم في صميم تجربة Android. وكما جعلت أداة اختيار الصور مشاركة الوسائط آمنة وسهلة التنفيذ، فإنّنا الآن نقدّم المستوى نفسه من الخصوصية والبساطة وتجربة المستخدم الرائعة عند اختيار جهات الاتصال.
معيار جديد لخصوصية جهات الاتصال
في السابق، كانت التطبيقات التي تتطلّب الوصول إلى جهات اتصال مستخدم معيّن تعتمد على الإذن الواسع النطاق READ_CONTACTS. وعلى الرغم من أنّ هذا النهج كان فعّالاً، غالبًا ما كان يمنح التطبيقات بيانات أكثر من اللازم. يغيّر "منتقي جهات الاتصال في Android" الجديد، الذي تم طرحه في Android 17، هذه الديناميكية من خلال توفير واجهة موحّدة وآمنة وقابلة للبحث لاختيار جهات الاتصال.
تتيح هذه الميزة للمستخدمين منح التطبيقات إذن الوصول إلى جهات الاتصال المحدّدة التي يختارونها فقط، بما يتوافق مع التزام Android بشفافية البيانات وتقليل أذونات الوصول إلى الحد الأدنى.
كيفية العمل
يمكن للمطوّرين دمج "منتقي جهات الاتصال" باستخدام الغرض Intent.ACTION_PICK_CONTACTS. توفّر واجهة برمجة التطبيقات المعدَّلة هذه إمكانات قوية متعددة:
- طلبات البيانات الدقيقة: يمكن للتطبيقات تحديد الحقول التي تحتاج إليها بالضبط، مثل أرقام الهواتف أو عناوين البريد الإلكتروني، بدلاً من تلقّي سجل جهة الاتصال بالكامل.
- إمكانية اختيار جهات اتصال متعددة: تتيح أداة الاختيار إمكانية اختيار جهة اتصال واحدة أو جهات اتصال متعددة، ما يمنح المطوّرين مرونة أكبر في ميزات مثل دعوات المجموعة.
- حدود الاختيار: يمكن للمطوّرين ضبط حدود مخصّصة لعدد جهات الاتصال التي يمكن للمستخدم اختيارها في وقت واحد.
- الوصول المؤقت: عند الاختيار، يعرض النظام معرّف موارد منتظمًا لجلسة يمنح إذن قراءة مؤقتًا للبيانات المطلوبة، ما يضمن عدم استمرار إذن الوصول لفترة أطول من اللازم.
- الوصول إلى ملفات شخصية أخرى: عند استخدام هذا الغرض الجديد، ستسمح الواجهة للمستخدمين باختيار محتوى من ملفات شخصية أخرى، مثل ملف شخصي للعمل أو ملف شخصي مستنسَخ أو مساحة خاصة.
- الأداء المحسّن: يعرض "منتقي جهات الاتصال" معرّف موارد منتظمًا واحدًا يتيح الاستعلام عن النتائج بشكل جماعي، ما يلغي الحاجة إلى الاستعلام عن معرّف الموارد المنتظم لجهة اتصال فردية بشكل منفصل كما هو مطلوب في
ACTION_PICK. تؤدي هذه الكفاءة إلى تقليل الحمل الزائد على النظام بشكل أكبر من خلال استخدام معاملةBinderواحدة.
التوافق مع الأنظمة القديمة والتنفيذ
بالنسبة إلى الأجهزة التي تعمل بنظام التشغيل Android 17 أو الإصدارات الأحدث، يرقّي النظام تلقائيًا أغراض ACTION_PICK القديمة التي تحدّد أنواع بيانات جهات الاتصال إلى الواجهة الجديدة الأكثر أمانًا. ومع ذلك، للاستفادة الكاملة من الميزات المتقدّمة، مثل إمكانية اختيار جهات اتصال متعددة، ننصح المطوّرين بتعديل رمز التنفيذ واستخدام ContentResolver للاستعلام عن معرّف الموارد المنتظم للجلسة الذي تم عرضه.
دمج "منتقي جهات الاتصال": لدمج "منتقي جهات الاتصال"، يستخدم المطوّرون الغرض ACTION_PICK_CONTACTS. في ما يلي مثال على التعليمات البرمجية يوضّح كيفية تشغيل أداة الاختيار وطلب حقول بيانات محدّدة، مثل البريد الإلكتروني وأرقام الهواتف.
// State to hold the list of selected contacts var contacts by remember { mutableStateOf<List>(emptyList()) } // 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 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_PICK_CONTACTS_SELECTION_LIMIT, 5) putStringArrayListExtra( EXTRA_PICK_CONTACTS_REQUESTED_DATA_FIELDS, requestedFields ) putExtra(EXTRA_PICK_CONTACTS_MATCH_ALL_DATA_FIELDS, false) } // Launch the picker pickContact.launch(pickContactIntent)
بعد أن يختار المستخدم، يعالج التطبيق النتيجة من خلال الاستعلام عن معرّف الموارد المنتظم للجلسة الذي تم عرضه لاستخراج معلومات جهة الاتصال المطلوبة.
// Data class representing a parsed Contact with selected details data class Contact(val id: String, val name: String, val email: String?, val phone: 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._ID, 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) ) val results = mutableListOf<Contact>() // Note: The Contact Picker Session Uri doesn't support custom selection & selectionArgs. context.contentResolver.query(sessionUri, projection, null, null, null)?.use { cursor -> // Get the column indices for our requested projection val contactIdIdx = cursor.getColumnIndex(ContactsContract.Contacts._ID) 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 contactId = cursor.getString(contactIdIdx) val mimeType = cursor.getString(mimeTypeIdx) val name = cursor.getString(nameIdx) ?: "" val data1 = cursor.getString(data1Idx) ?: "" // Determine if the current row represents an email or a phone number val email = if (mimeType == Email.CONTENT_ITEM_TYPE) data1 else null val phone = if (mimeType == Phone.CONTENT_ITEM_TYPE) data1 else null // Add the parsed contact to our results list results.add(Contact(contactId, name, email, phone)) } } return@withContext results }
يمكنك الاطّلاع على المستندات الكاملة هنا.
أفضل الممارسات للمطوّرين
لتقديم أفضل تجربة للمستخدم والحفاظ على معايير الأمان العالية، ننصح بما يلي:
- تقليل البيانات: لا تطلب سوى حقول البيانات المحدّدة (مثل البريد الإلكتروني) التي يحتاج إليها تطبيقك.
- الاحتفاظ بالبيانات على الفور: احتفِظ بالبيانات المحدّدة على الفور، لأنّ إذن الوصول إلى معرّف الموارد المنتظم للجلسة مؤقت.
متابعة القراءة
-
أخبار المنتجات
أداة اختيار الصور المضمّنة: طريقة أكثر سلاسة لطلب الصور والفيديوهات بشكل خاص في تطبيقك
Roxanna Aliabadi Walker, Yacine Rezgui • مدة القراءة: 8 دقائق
-
أخبار المنتجات
استنادًا إلى هذا الأساس، يمنح الإصدار 1.1.0 من Jetpack Telecom تطبيقات بروتوكول الصوت على الإنترنت التابعة لجهات خارجية إمكانية الظهور بشكل طبيعي وسهولة الاستخدام.
Nataraj K R • مدة القراءة: دقيقتان
-
أخبار المنتجات
أعلنّا اليوم خلال The Android Show أنّ Android ينتقل من نظام تشغيل إلى نظام ذكاء، ما يوفّر المزيد من الفرص للتفاعل مع تطبيقاتك.
Matthew McCullough • مدة القراءة: 4 دقائق
البقاء على اطّلاع على آخر التحديثات
يمكنك تلقّي أحدث الإحصاءات حول تطوير تطبيقات Android في بريدك الوارد أسبوعيًا.