Die Android-Kontaktauswahl ist eine standardisierte, durchsuchbare Benutzeroberfläche, über die Nutzer Kontakte für Ihre App freigeben können. Sie ist auf Geräten mit Android 17 oder höher verfügbar und bietet eine datenschutzfreundliche Alternative zur umfassenden Berechtigung READ_CONTACTS. Anstatt Zugriff auf das gesamte Adressbuch des Nutzers anzufordern, gibt Ihre App die benötigten Datenfelder an, z. B. Telefonnummern oder E-Mail-Adressen, und der Nutzer wählt bestimmte Kontakte aus, die freigegeben werden sollen. Dadurch erhält Ihre App nur Lesezugriff auf die ausgewählten Daten. So haben Sie eine detaillierte Kontrolle und können gleichzeitig eine einheitliche Nutzererfahrung mit integrierter Suche, Profilwechsel und Mehrfachauswahl bieten, ohne die Benutzeroberfläche entwickeln oder verwalten zu müssen.
Kontaktauswahl einbinden
Verwenden Sie das Intent Intent.ACTION_PICK_CONTACTS, um die Kontaktauswahl zu integrieren.
Mit diesem Intent wird die Auswahl gestartet und die ausgewählten Kontakte werden an Ihre App zurückgegeben.
Im Gegensatz zur alten ACTION_PICK können Sie mit der Kontaktauswahl gleichzeitig mehrere Datenfelder angeben, die Ihre App benötigt. Dazu verwenden Sie Intent.EXTRA_REQUESTED_DATA_FIELDS und übergeben eine ArrayList<String> von MIME-Typen, die in ContactsContract.CommonDataKinds definiert sind.
Häufige MIME-Typen sind:
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPEContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE
Auswahl starten
Verwenden Sie registerForActivityResult mit dem StartActivityForResult-Vertrag, um die Auswahl zu starten. Sie können den Intent so konfigurieren, dass einzelne oder mehrere Auswahlen möglich sind.
Einzelnen Kontakt auswählen
In diesem Beispiel fordert die App nur Telefonnummern an. Die Auswahl wird gefiltert, sodass nur Kontakte mit Telefonnummern angezeigt werden. Der Nutzer kann dann eine bestimmte Nummer auswählen.
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);
Mehrere Kontakte auswählen
Fügen Sie das Intent.EXTRA_ALLOW_MULTIPLE-Extra hinzu, um die Mehrfachauswahl zu aktivieren. Optional können Sie die Anzahl der Elemente begrenzen, die ein Nutzer auswählen kann.
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)
Ergebnisse verarbeiten
Wenn der Nutzer die Auswahl abgeschlossen hat, gibt das System eine RESULT_OK und eine Sitzungs-URI zurück. Dieser URI gewährt temporären Lesezugriff auf die ausgewählten Daten.
Sie können diesen URI mit einem Standard-ContentResolver abfragen. Der resultierende Cursor enthält die angeforderten Datenfelder und entspricht dem Schema von 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")
}
}
}
}
}
Abwärtskompatibilität
Bei Apps, die für Android 17 und höher bestimmt sind, wird der vorhandene Intent.ACTION_PICK-Intent automatisch auf die neue Contact Picker-Oberfläche aktualisiert.
Wenn Ihre App bereits ACTION_PICK verwendet, müssen Sie Ihren Code nicht ändern, um die neue Benutzeroberfläche zu erhalten. Wenn Sie jedoch neue Funktionen wie den Empfang eines einzelnen Uri zum Abfragen von Kontaktdaten, das Umschalten zwischen privaten und Arbeitsprofilen oder mehrere Datenfeldanfragen nutzen möchten, müssen Sie Ihre Implementierung aktualisieren, damit Intent.ACTION_PICK_CONTACTS oder die neuen Intent-Extras verwendet werden.
Auf älteren SDKs testen
Sie können das neue Auswahltoolverhalten auf Geräten mit Android 17 und höher testen, auch wenn Ihre App auf eine niedrigere SDK-Version ausgerichtet ist. Fügen Sie dazu dem ACTION_PICK-Intent das boolesche Extra EXTRA_USE_SYSTEM_CONTACTS_PICKER hinzu.
Best Practices
- Nur das anfordern, was Sie benötigen: Wenn Ihre App nur eine SMS senden muss, fordern Sie
Phone.CONTENT_ITEM_TYPEan. In der Auswahl werden Kontakte ohne Telefonnummer automatisch herausgefiltert, was zu einer übersichtlicheren Benutzeroberfläche für den Nutzer führt. - Daten sofort speichern: Der Sitzungs-URI gewährt eine temporäre Leseberechtigung. Wenn Sie später (nachdem der App-Prozess beendet wurde) auf diese Kontaktdaten zugreifen müssen, muss Ihre App die Kontaktdaten speichern.
- Nicht auf Kontodaten verlassen: Zum Schutz der Privatsphäre der Nutzer und zur Vermeidung von Fingerprinting werden kontospezifische Metadaten aus den Ergebnissen entfernt.