ข่าวสารผลิตภัณฑ์

เครื่องมือเลือกรายชื่อติดต่อ: การแชร์รายชื่อติดต่อแบบเน้นความเป็นส่วนตัว

ใช้เวลาอ่าน 4 นาที
Roxanna Aliabadi Walker
ผู้จัดการผลิตภัณฑ์

ความเป็นส่วนตัวและการควบคุมของผู้ใช้ยังคงเป็นหัวใจสำคัญของประสบการณ์การใช้งาน Android เช่นเดียวกับเครื่องมือเลือกรูปภาพที่ทำให้การแชร์สื่อปลอดภัยและใช้งานง่าย ตอนนี้เรากำลังนำระดับความเป็นส่วนตัว ความเรียบง่าย และประสบการณ์การใช้งานที่ยอดเยี่ยมแบบเดียวกันมาสู่การเลือกรายชื่อติดต่อ

มาตรฐานใหม่สำหรับความเป็นส่วนตัวของรายชื่อติดต่อ

ในอดีต แอปพลิเคชันที่ต้องเข้าถึงรายชื่อติดต่อของผู้ใช้ที่เฉพาะเจาะจงจะอาศัยREAD_CONTACTSสิทธิ์แบบกว้าง แม้ว่าวิธีนี้จะใช้งานได้ แต่ก็มักจะให้สิทธิ์แอปเข้าถึงข้อมูลมากกว่าที่จำเป็น เครื่องมือเลือกรายชื่อติดต่อ Android ใหม่ที่เปิดตัวใน Android 17 จะเปลี่ยนลักษณะนี้ด้วยการมอบอินเทอร์เฟซที่ได้มาตรฐาน ปลอดภัย และค้นหาได้สำหรับการเลือกรายชื่อติดต่อ

ฟีเจอร์นี้ช่วยให้ผู้ใช้ให้สิทธิ์แอปเข้าถึงเฉพาะรายชื่อติดต่อที่เลือกได้ ซึ่งสอดคล้องกับความมุ่งมั่นของ Android ในเรื่องความโปร่งใสของข้อมูลและร่องรอยสิทธิ์ที่น้อยที่สุด

picker.png
selection.png

วิธีการทำงาน

นักพัฒนาแอปสามารถผสานรวมเครื่องมือเลือกรายชื่อติดต่อโดยใช้ Intent Intent.ACTION_PICK_CONTACTS ได้ API ที่อัปเดตนี้มีความสามารถที่มีประสิทธิภาพหลายอย่าง ดังนี้

  • คำขอข้อมูลแบบละเอียด: แอปสามารถระบุฟิลด์ที่ต้องการได้อย่างชัดเจน เช่น หมายเลขโทรศัพท์หรืออีเมล แทนที่จะรับระเบียนรายชื่อติดต่อทั้งหมด
  • รองรับการเลือกหลายรายการ: เครื่องมือเลือกนี้รองรับการเลือกรายชื่อติดต่อแบบรายการเดียวและหลายรายการ ซึ่งช่วยให้นักพัฒนาแอปมีความยืดหยุ่นมากขึ้นสำหรับฟีเจอร์ต่างๆ เช่น คำเชิญแบบกลุ่ม
  • ขีดจํากัดการเลือก: นักพัฒนาแอปสามารถกําหนดขีดจํากัดที่กําหนดเองสําหรับจํานวนรายชื่อติดต่อที่ผู้ใช้เลือกได้ในครั้งเดียว
  • สิทธิ์เข้าถึงชั่วคราว: เมื่อเลือกแล้ว ระบบจะแสดง URI ของเซสชันซึ่งให้สิทธิ์เข้าถึงแบบอ่านชั่วคราวสำหรับข้อมูลที่ขอ เพื่อให้มั่นใจว่าสิทธิ์เข้าถึงจะไม่คงอยู่นานเกินกว่าที่จำเป็น
  • การเข้าถึงโปรไฟล์อื่นๆ: เมื่อใช้ Intent ใหม่นี้ อินเทอร์เฟซจะอนุญาตให้ผู้ใช้เลือกเนื้อหาจากโปรไฟล์ผู้ใช้รายอื่น เช่น โปรไฟล์งาน โปรไฟล์ที่โคลน หรือพื้นที่ส่วนตัว
  • ประสิทธิภาพที่เพิ่มขึ้น: เครื่องมือเลือกรายชื่อติดต่อจะแสดง Uri เดียวที่อนุญาตให้ค้นหาผลลัพธ์แบบรวม ซึ่งช่วยให้ไม่จำเป็นต้องค้นหา Uri ของรายชื่อติดต่อแต่ละรายการแยกกันตามที่กำหนดโดย ACTION_PICK ประสิทธิภาพนี้ช่วยลดค่าใช้จ่ายของระบบเพิ่มเติมด้วยการใช้ธุรกรรม Binder รายการเดียว

ความเข้ากันได้แบบย้อนหลังและการใช้งาน

สำหรับอุปกรณ์ที่ใช้ Android 17 ขึ้นไป ระบบจะอัปเกรด Intent ACTION_PICK รุ่นเดิมที่ระบุประเภทข้อมูลรายชื่อติดต่อเป็นอินเทอร์เฟซใหม่ที่ปลอดภัยยิ่งขึ้นโดยอัตโนมัติ อย่างไรก็ตาม เพื่อให้ใช้ประโยชน์จากฟีเจอร์ขั้นสูงอย่างเต็มที่ เช่น การเลือกหลายรายการ เราขอแนะนำให้นักพัฒนาแอปอัปเดตโค้ดการติดตั้งใช้งานและใช้ ContentResolver เพื่อค้นหา URI ของเซสชันที่ส่งคืน


ผสานรวมเครื่องมือเลือกรายชื่อติดต่อหากต้องการผสานรวมเครื่องมือเลือกรายชื่อติดต่อ นักพัฒนาแอปจะใช้ Intent 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)

หลังจากที่ผู้ใช้เลือกแล้ว แอปจะประมวลผลผลลัพธ์โดยการค้นหา URI ของเซสชันที่ส่งคืนเพื่อดึงข้อมูลติดต่อที่ขอ

// 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
}

ดูเอกสารประกอบทั้งหมดได้ที่นี่

แนวทางปฏิบัติแนะนำสำหรับนักพัฒนาแอป

เราขอแนะนำให้คุณดำเนินการต่อไปนี้เพื่อมอบประสบการณ์การใช้งานที่ดีที่สุดแก่ผู้ใช้และรักษามาตรฐานความปลอดภัยในระดับสูง

  • การลดปริมาณข้อมูล: ขอเฉพาะฟิลด์ข้อมูลที่เฉพาะเจาะจง (เช่น อีเมล) ที่แอปของคุณต้องการ
  • การคงอยู่ทันที: คงข้อมูลที่เลือกไว้ทันที เนื่องจากสิทธิ์เข้าถึง URI ของเซสชันเป็นแบบชั่วคราว
เขียนโดย

อ่านต่อ