Pemilih kontak

Pemilih Kontak Android adalah antarmuka standar yang dapat dijelajahi bagi pengguna untuk membagikan kontak ke aplikasi Anda. Tersedia di perangkat yang menjalankan Android 17 atau yang lebih tinggi, pemilih ini menawarkan alternatif yang menjaga privasi untuk izin READ_CONTACTS yang luas. Daripada meminta akses ke seluruh buku alamat pengguna, aplikasi Anda menentukan kolom data yang diperlukan, seperti nomor telepon atau alamat email, dan pengguna memilih kontak tertentu untuk dibagikan. Hal ini memberi aplikasi Anda akses baca hanya ke data yang dipilih, sehingga memastikan kontrol terperinci sekaligus memberikan pengalaman pengguna yang konsisten dengan kemampuan penelusuran bawaan, penggantian profil, dan multi-seleksi tanpa harus membangun atau memelihara UI.

Mengintegrasikan Pemilih Kontak

Untuk mengintegrasikan Pemilih Kontak, gunakan intent Intent.ACTION_PICK_CONTACTS. Intent ini meluncurkan pemilih dan menampilkan kontak yang dipilih ke aplikasi Anda.

Tidak seperti ACTION_PICK lama, Pemilih Kontak memungkinkan Anda menentukan beberapa kolom data yang diperlukan aplikasi Anda secara bersamaan. Anda melakukannya menggunakan Intent.EXTRA_REQUESTED_DATA_FIELDS, dengan meneruskan ArrayList<String> jenis MIME yang ditentukan dalam ContactsContract.CommonDataKinds.

Jenis MIME umum meliputi:

  • ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
  • ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
  • ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE

Meluncurkan pemilih

Gunakan registerForActivityResult dengan kontrak StartActivityForResult untuk meluncurkan pemilih. Anda dapat mengonfigurasi maksud untuk mengizinkan satu atau beberapa pilihan.

Memilih satu kontak

Dalam contoh ini, aplikasi hanya meminta nomor telepon. Pemilih akan memfilter daftar untuk hanya menampilkan kontak dengan nomor telepon dan memungkinkan pengguna memilih nomor tertentu.

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);

Memilih beberapa kontak

Untuk mengaktifkan multi-pilihan, tambahkan ekstra Intent.EXTRA_ALLOW_MULTIPLE. Anda dapat secara opsional membatasi jumlah item yang dapat dipilih pengguna.

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)

Menangani hasil

Saat pengguna menyelesaikan pemilihan, sistem akan menampilkan RESULT_OK dan URI Sesi. URI ini memberikan akses baca sementara ke data yang dipilih.

Anda dapat membuat kueri URI ini menggunakan ContentResolver standar. Cursor yang dihasilkan berisi kolom data yang diminta dan mengikuti skema 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")
                }
            }
        }
    }
}

Kompatibilitas Mundur

Untuk aplikasi yang menargetkan Android 17 dan yang lebih tinggi, sistem akan otomatis mengupgrade intent Intent.ACTION_PICK yang ada untuk menggunakan antarmuka Pemilih Kontak yang baru.

Jika aplikasi Anda sudah menggunakan ACTION_PICK, Anda tidak perlu mengubah kode untuk menerima UI baru. Namun, untuk memanfaatkan fitur baru, seperti menerima satu Uri untuk membuat kueri data kontak, beralih antara profil pribadi & kerja atau beberapa permintaan kolom data, Anda harus memperbarui penerapan untuk menggunakan Intent.ACTION_PICK_CONTACTS atau ekstra intent baru.

Pengujian di SDK lama

Anda dapat menguji perilaku pemilih baru di perangkat yang menjalankan Android 17 dan yang lebih tinggi, meskipun aplikasi Anda menargetkan versi SDK yang lebih rendah, dengan menambahkan ekstra boolean EXTRA_USE_SYSTEM_CONTACTS_PICKER ke intent ACTION_PICK Anda.

Praktik terbaik

  • Hanya minta izin yang Anda butuhkan: Jika aplikasi Anda hanya perlu mengirim SMS, minta Phone.CONTENT_ITEM_TYPE. Pemilih akan otomatis memfilter kontak yang tidak memiliki nomor telepon, sehingga menghasilkan UI yang lebih bersih bagi pengguna.
  • Mempertahankan data secara langsung: URI Sesi memberikan izin baca sementara. Jika Anda perlu mengakses informasi kontak ini nanti (setelah proses aplikasi Anda dihentikan), aplikasi Anda harus mempertahankan data kontak.
  • Jangan mengandalkan Data Akun: Untuk melindungi privasi pengguna dan mencegah sidik jari digital, metadata khusus akun dihapus dari hasil.