Выбор контактов

Интерфейс выбора контактов Android Contact Picker — это стандартизированный, удобный для просмотра интерфейс, позволяющий пользователям делиться контактами с вашим приложением. Доступный на устройствах под управлением Android 17 и выше, этот интерфейс предлагает альтернативу широкому разрешению READ_CONTACTS обеспечивающую конфиденциальность. Вместо запроса доступа ко всей адресной книге пользователя, ваше приложение указывает необходимые поля данных, такие как номера телефонов или адреса электронной почты, а пользователь выбирает конкретные контакты для обмена. Это предоставляет вашему приложению доступ на чтение только к выбранным данным, обеспечивая детальный контроль и предоставляя единообразный пользовательский опыт со встроенным поиском, переключением профилей и возможностью множественного выбора без необходимости разработки или поддержки пользовательского интерфейса.

Интегрируйте средство выбора контактов.

Для интеграции средства выбора контактов используйте интент Intent.ACTION_PICK_CONTACTS . Этот интент запускает средство выбора и возвращает выбранные контакты в ваше приложение.

В отличие от устаревшего ACTION_PICK , Contact Picker позволяет одновременно указывать несколько полей данных, необходимых вашему приложению. Это делается с помощью 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 для запуска средства выбора. Вы можете настроить Intent таким образом, чтобы разрешить одиночный или множественный выбор.

Выберите один контакт

В этом примере приложение запрашивает только номера телефонов. Средство выбора отфильтрует список, чтобы отобразить только контакты с номерами телефонов, и позволит пользователю выбрать конкретный номер.

Котлин

// 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 . При желании вы можете ограничить количество элементов, которые может выбрать пользователь.

Котлин

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 сессии. Этот URI предоставляет временный доступ для чтения к выбранным данным.

Вы можете запросить этот URI, используя стандартный ContentResolver . Полученный Cursor содержит запрошенные поля данных и соответствует схеме ContactsContract.Data .

Котлин

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")
                }
            }
        }
    }
}

Обратная совместимость

Для приложений, ориентированных на Android 17 и выше, система автоматически обновляет существующий Intent.ACTION_PICK для использования нового интерфейса выбора контактов.

Если ваше приложение уже использует ACTION_PICK , вам не нужно менять код для получения нового пользовательского интерфейса. Однако, чтобы воспользоваться новыми функциями, такими как получение одного Uri для запроса контактных данных, переключение между личным и рабочим профилями или запросы нескольких полей данных, вам необходимо обновить свою реализацию, чтобы использовать Intent.ACTION_PICK_CONTACTS или новые дополнительные параметры Intent.

Тестирование на более старых версиях SDK.

Вы можете протестировать новое поведение средства выбора на устройствах под управлением Android 17 и выше, даже если ваше приложение ориентировано на более старую версию SDK, добавив логическую переменную EXTRA_USE_SYSTEM_CONTACTS_PICKER в ваш интент ACTION_PICK .

Передовые методы

  • Запрашивайте только то, что вам нужно : если вашему приложению нужно только отправить SMS, запросите Phone.CONTENT_ITEM_TYPE . Средство выбора автоматически отфильтрует контакты, у которых нет номеров телефонов, что обеспечит более удобный пользовательский интерфейс.
  • Сохранение данных немедленно : URI сессии предоставляет временное разрешение на чтение. Если вам потребуется получить доступ к этой контактной информации позже (после завершения процесса вашего приложения), ваше приложение должно сохранить контактные данные.
  • Не полагайтесь на данные учетной записи : для защиты конфиденциальности пользователей и предотвращения идентификации по отпечатку учетной записи метаданные, относящиеся к конкретной учетной записи, удаляются из результатов.