Datenschutz und Nutzerkontrolle bleiben ein zentraler Bestandteil von Android. So wie die Bildauswahl das Teilen von Medien sicher und einfach gemacht hat, bieten wir jetzt auch bei der Auswahl von Kontakten ein hohes Maß an Datenschutz, Einfachheit und Nutzerfreundlichkeit.
Ein neuer Standard für den Datenschutz bei Kontakten
Bisher haben Anwendungen, die Zugriff auf die Kontakte eines bestimmten Nutzers benötigten, die umfassende Berechtigung READ_CONTACTS verwendet. Das hat zwar funktioniert, aber oft haben Apps dadurch mehr Daten erhalten als nötig. Die neue Android-Kontaktauswahl, die in Android 17 eingeführt wurde, ändert das. Sie bietet eine standardisierte, sichere und durchsuchbare Benutzeroberfläche für die Auswahl von Kontakten.
Mit dieser Funktion können Nutzer Apps nur Zugriff auf die von ihnen ausgewählten Kontakte gewähren. Das entspricht dem Android-Grundsatz der Datentransparenz und der Minimierung von Berechtigungen.
Funktionsweise
Entwickler können die Kontaktauswahl mit dem Intent Intent.ACTION_PICK_CONTACTS einbinden. Diese aktualisierte API bietet mehrere leistungsstarke Funktionen:
- Granulare Datenanfragen:Apps können genau angeben, welche Felder sie benötigen, z. B. Telefonnummern oder E-Mail-Adressen, anstatt den gesamten Kontaktdatensatz zu erhalten.
- Unterstützung für Mehrfachauswahl:Die Auswahl unterstützt sowohl die Auswahl einzelner als auch mehrerer Kontakte. So haben Entwickler mehr Flexibilität für Funktionen wie Gruppeneinladungen.
- Auswahlgrenzen:Entwickler können benutzerdefinierte Grenzwerte für die Anzahl der Kontakte festlegen, die ein Nutzer gleichzeitig auswählen kann.
- Temporärer Zugriff:Nach der Auswahl gibt das System einen Sitzungs-URI zurück, der temporären Lesezugriff auf die angeforderten Daten bietet. So wird sichergestellt, dass der Zugriff nicht länger als nötig besteht.
- Zugriff auf andere Profile : Wenn dieser neue Intent verwendet wird, können Nutzer auf der Benutzeroberfläche Inhalte aus anderen Nutzerprofilen auswählen, z. B. aus einem Arbeitsprofil, einem geklonten Profil oder einem privaten Bereich.
- Optimierte Leistung: Die Kontaktauswahl gibt einen einzelnen URI zurück, mit dem Ergebnisse gemeinsam abgefragt werden können. So ist es nicht mehr erforderlich, einzelne Kontakt-URIs separat abzufragen, wie es bei
ACTION_PICKder Fall ist. Diese Effizienz reduziert den Systemaufwand weiter, da nur eine einzigeBinder-Transaktion verwendet wird.
Abwärtskompatibilität und Implementierung
Auf Geräten mit Android 17 oder höher werden ältere ACTION_PICK-Intents, die Kontaktdatentypen angeben, automatisch auf die neue, sicherere Benutzeroberfläche aktualisiert. Um jedoch alle Vorteile der erweiterten Funktionen wie der Mehrfachauswahl nutzen zu können, sollten Entwickler ihren Implementierungscode aktualisieren und den ContentResolver verwenden, um den zurückgegebenen Sitzungs-URI abzufragen.
Kontaktauswahl einbindenEntwickler verwenden den Intent ACTION_PICK_CONTACTS, um die Kontaktauswahl einzubinden. Im folgenden Codebeispiel wird gezeigt, wie die Auswahl gestartet und bestimmte Datenfelder wie E-Mail-Adressen und Telefonnummern angefordert werden.
// 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)
Nachdem der Nutzer eine Auswahl getroffen hat, verarbeitet die App das Ergebnis, indem sie den zurückgegebenen Sitzungs-URI abfragt, um die angeforderten Kontaktinformationen zu extrahieren.
// 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 }
Die vollständige Dokumentation finden Sie hier.
Best Practices für Entwickler
Für eine optimale Nutzererfahrung und hohe Sicherheitsstandards empfehlen wir Folgendes:
- Datenminimierung:Fordern Sie nur die spezifischen Datenfelder an, die Ihre App benötigt (z.B. E-Mail-Adresse).
- Sofortige Speicherung:Speichern Sie ausgewählte Daten sofort, da der Zugriff über den Sitzungs-URI nur temporär ist.
-
ProduktneuheitenDie eingebettete Bildauswahl: Fotos und Videos in Ihrer App auf datenschutzfreundlichere Weise anfordern
Roxanna Aliabadi Walker, Yacine Rezgui • Lesezeit: 8 Minuten -
ProduktneuheitenIm März haben wir Android Bench eingeführt, unsere Bestenliste für LLMs für Android-Entwicklungsaufgaben in der Praxis. Seitdem haben wir den Benchmark anhand Ihres Feedbacks verbessert. Dazu gehört die Bewertung von Modellen mit offenen Gewichten sowie das Hinzufügen von Kosten- und Effizienzkriterien zur Bestenliste.
Zoe Lopez-Latorre • Lesezeit: 3 Minuten -
ProduktneuheitenBei Google Play ist es uns wichtig, Nutzerinnen und Nutzern die bestmögliche Nutzerfreundlichkeit zu bieten. Gleichzeitig möchten wir dafür sorgen, dass Entwicklerinnen und Entwickler die notwendigen Tools und die Flexibilität haben, um erfolgreich zu sein.
Paul Feng • Lesezeit: 3 Minuten
Lassen Sie sich Woche für Woche die neuesten Informationen zur Android-Entwicklung zusenden.