Selektor kontaktów na Androidzie to standardowy interfejs przeglądania, który umożliwia użytkownikom udostępnianie kontaktów w Twojej aplikacji. Jest on dostępny na urządzeniach z Androidem 17 lub nowszym i stanowi alternatywę dla szerokiego uprawnienia READ_CONTACTS, która zapewnia ochronę prywatności. Zamiast prosić o dostęp do całej książki adresowej użytkownika, aplikacja określa potrzebne jej pola danych, takie jak numery telefonów lub adresy e-mail, a użytkownik wybiera konkretne kontakty do udostępnienia. Dzięki temu aplikacja uzyskuje dostęp do odczytu tylko wybranych danych, co zapewnia szczegółową kontrolę i spójne wrażenia użytkowników dzięki wbudowanym funkcjom wyszukiwania, przełączania profili i wielokrotnego wyboru bez konieczności tworzenia interfejsu użytkownika ani zarządzania nim.
Integracja selektora kontaktów
Aby zintegrować selektor kontaktów, użyj intencji Intent.ACTION_PICK_CONTACTS.
Ten zamiar uruchamia selektor i zwraca wybrane kontakty do aplikacji.
W przeciwieństwie do starszego interfejsu ACTION_PICK selektor kontaktów umożliwia jednoczesne określanie wielu pól danych wymaganych przez aplikację. Możesz to zrobić za pomocą elementu Intent.EXTRA_REQUESTED_DATA_FIELDS, przekazując ArrayList<String> typów MIME zdefiniowanych w ContactsContract.CommonDataKinds.
Najczęstsze typy MIME to:
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
Uruchamianie selektora
Użyj registerForActivityResult z umową StartActivityForResult, aby uruchomić selektor. Możesz skonfigurować intencję tak, aby zezwalała na pojedynczy lub wielokrotny wybór.
Wybieranie pojedynczego kontaktu
W tym przykładzie aplikacja prosi tylko o numery telefonów. Selektor odfiltruje listę, aby wyświetlić tylko kontakty z numerami telefonów, i umożliwi użytkownikowi wybranie konkretnego numeru.
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);
Wybieranie wielu kontaktów
Aby włączyć wielokrotny wybór, dodaj Intent.EXTRA_ALLOW_MULTIPLE. Możesz opcjonalnie ograniczyć liczbę elementów, które użytkownik może wybrać.
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)
Obsługa wyników
Gdy użytkownik dokona wyboru, system zwraca wartość RESULT_OK i adres URI sesji. Ten identyfikator URI przyznaje tymczasowy dostęp do odczytu wybranych danych.
Możesz wysyłać zapytania do tego identyfikatora URI za pomocą standardowego ContentResolver. Wynikowy plik Cursor zawiera żądane pola danych i jest zgodny ze schematem pliku 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")
}
}
}
}
}
Zgodność wsteczna
W przypadku aplikacji kierowanych na Androida 17 i nowsze wersje system automatycznie uaktualnia istniejący zamiar Intent.ACTION_PICK, aby korzystać z nowego interfejsu selektora kontaktów.
Jeśli Twoja aplikacja korzysta już z ACTION_PICK, nie musisz zmieniać kodu, aby otrzymać nowy interfejs. Aby jednak korzystać z nowych funkcji, takich jak otrzymywanie pojedynczego Uri do wysyłania zapytań o dane kontaktowe, przełączanie się między profilami osobistym i służbowym czy wysyłanie wielu próśb o pola danych, musisz zaktualizować implementację, aby używać Intent.ACTION_PICK_CONTACTS lub nowych dodatków do intencji.
Testowanie na starszych wersjach pakietu SDK
Możesz przetestować nowe działanie selektora na urządzeniach z Androidem 17 i nowszym, nawet jeśli Twoja aplikacja jest kierowana na starszą wersję pakietu SDK. Wystarczy, że dodasz do intencji ACTION_PICK dodatkowy parametr logiczny EXTRA_USE_SYSTEM_CONTACTS_PICKER.
Sprawdzone metody
- Proś tylko o to, czego potrzebujesz: jeśli Twoja aplikacja musi tylko wysyłać SMS-y, poproś o
Phone.CONTENT_ITEM_TYPE. Selektor automatycznie odfiltruje kontakty, które nie mają numerów telefonów, co zapewni użytkownikowi przejrzysty interfejs. - Natychmiastowe utrwalanie danych: identyfikator URI sesji przyznaje tymczasowe uprawnienia do odczytu. Jeśli chcesz później uzyskać dostęp do tych informacji kontaktowych (po zamknięciu procesu aplikacji), musisz zapisać dane kontaktowe.
- Nie polegaj na danych konta: aby chronić prywatność użytkowników i zapobiegać tworzeniu odcisków cyfrowych, z wyników usuwane są metadane dotyczące konta.