اخبار محصول

انتخابگر مخاطب: هم‌رسانی مخاطب با اولویت حریم خصوصی

‫۴ دقیقه مطالعه
دیدن نمایه Roxanna Aliabadi Walker
Roxanna Aliabadi Walker مدیر محصول

حریم خصوصی و کنترل کاربر همچنان در قلب تجربه Android قرار دارند. همان‌طور که انتخابگر عکس هم‌رسانی رسانه را ایمن و پیاده‌سازی آن را آسان کرد، اکنون همان سطح از حریم خصوصی، سادگی، و تجربه کاربری عالی را به انتخاب مخاطب می‌آوریم.

استاندارد جدیدی برای حریم خصوصی مخاطب

از گذشته، برنامه‌هایی که نیاز به دسترسی به مخاطبین کاربر خاصی داشتند، به اجازه گسترده READ_CONTACTS متکی بودند. اگرچه این رویکرد کارآمد بود، اما اغلب به برنامه‌ها داده‌های بیشتری از آنچه لازم بود اعطا می‌کرد. «انتخابگر مخاطب Android» جدید که در Android 17 معرفی شده است، با ارائه یک واسط استاندارد، ایمن، و قابل‌جستجو برای انتخاب مخاطب، این پویاشناسی را تغییر می‌دهد.

این ویژگی به کاربران امکان می‌دهد به برنامه‌ها فقط برای مخاطبین خاصی که انتخاب می‌کنند دسترسی اعطا کنند، که با تعهد Android به شفافیت داده‌ها و حداقل کردن ردپای اجازه‌ها هم‌راستا است.

picker.png
selection.png

روش کار

توسعه‌دهندگان می‌توانند «انتخابگر مخاطب» را بااستفاده از هدف Intent.ACTION_PICK_CONTACTS ادغام کنند. این «میانای برنامه‌سازی کاربردی» به‌روزشده قابلیت‌های قدرتمند متعددی ارائه می‌دهد:

  • درخواست‌های داده‌های دقیق: برنامه‌ها می‌توانند دقیقاً مشخص کنند که به کدام فیلدها نیاز دارند، مثلاً شماره تلفن یا نشانی ایمیل، به‌جای اینکه کل سابقه مخاطب را دریافت کنند.
  • پشتیبانی از چندانتخابی: انتخابگر از انتخاب یک یا چند مخاطب پشتیبانی می‌کند و به توسعه‌دهندگان انعطاف‌پذیری بیشتری برای ویژگی‌هایی مثل دعوت گروهی می‌دهد.
  • محدودیت‌های انتخاب: توسعه‌دهندگان می‌توانند محدودیت‌های سفارشی برای تعداد مخاطبانی که کاربر می‌تواند در یک زمان انتخاب کند تعیین کنند.
  • دسترسی موقت: پس‌از انتخاب، سیستم یک «نشانی وب جلسه» برمی‌گرداند که دسترسی خواندن موقت به داده‌های درخواست‌شده را فراهم می‌کند و تضمین می‌کند که دسترسی بیش‌از حد لازم ادامه نمی‌یابد.
  • دسترسی به نمایه‌های دیگر: هنگام استفاده از این هدف جدید، میانای کاربری به کاربران اجازه می‌دهد محتوا را از نمایه‌های کاربری دیگر مثل نمایه کاری، نمایه شبیه‌سازی‌شده، یا فضای خصوصی انتخاب کنند.
  • عملکرد بهینه: «انتخابگر مخاطب» یک Uri واحد برمی‌گرداند که امکان پُرسمان نتیجه جمعی را فراهم می‌کند و نیاز به پُرسمان جداگانه Uri مخاطب تکی را که 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
}

مستندات کامل را اینجا ببینید.

روال‌های مطلوب برای توسعه‌دهندگان

برای ارائه بهترین تجربه کاربری و حفظ استانداردهای امنیتی بالا، موارد زیر را توصیه می‌کنیم:

  • کمینه‌سازی داده‌ها: فقط فیلدهای داده خاصی را که برنامه‌تان نیاز دارد (مثلاً ایمیل) درخواست کنید.
  • ماندگاری فوری: داده‌های انتخاب‌شده را فوراً ماندگار کنید، زیرا دسترسی به نشانی وب جلسه موقتی است.
ادامه خواندن