Kontaktauswahl: Datenschutzorientierte Freigabe von Kontakten
Lesezeit: 4 Minuten
Datenschutz und Nutzerkontrolle bleiben ein zentrales Anliegen von Android. So wie die Bildauswahl das Teilen von Medien sicher und einfach zu implementieren gemacht hat, bieten wir jetzt das gleiche Maß an Datenschutz, Einfachheit und Nutzerfreundlichkeit bei der Auswahl von Kontakten.
Ein neuer Standard für den Datenschutz bei Kontakten
Bisher haben Anwendungen, die Zugriff auf die Kontakte eines bestimmten Nutzers benötigten, auf die umfassende Berechtigung READ_CONTACTS zurückgegriffen. Dieser Ansatz war zwar funktional, gewährte Apps aber oft mehr Daten als nötig. Die neue Android-Kontaktauswahl, die in Android 17 eingeführt wurde, ändert dies, indem sie eine standardisierte, sichere und durchsuchbare Oberfläche für die Auswahl von Kontakten bietet.
Mit dieser Funktion können Nutzer Apps nur Zugriff auf die von ihnen ausgewählten Kontakte gewähren. Dies entspricht dem Bestreben von Android, Datentransparenz zu fördern und die Berechtigungen zu minimieren.
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 der Mehrfachauswahl:Die Auswahl unterstützt sowohl die Auswahl einzelner als auch mehrerer Kontakte, was Entwicklern mehr Flexibilität für Funktionen wie Gruppeneinladungen bietet.
- Auswahlbeschränkungen:Entwickler können benutzerdefinierte Beschränkungen für die Anzahl der Kontakte festlegen, die ein Nutzer gleichzeitig auswählen kann.
- Temporärer Zugriff:Nach der Auswahl gibt das System eine Sitzungs-URI zurück, die 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 Nutzer diesen neuen Intent verwenden, können sie in der Benutzeroberfläche Inhalte aus anderen Nutzerprofilen wie einem Arbeitsprofil, einem geklonten Profil oder einem vertraulichen Profil auswählen.
- Optimierte Leistung : Die Kontaktauswahl gibt einen einzelnen URI zurück, der das Abfragen von Ergebnissen in Gruppen ermöglicht. Dadurch entfällt die Notwendigkeit, einzelne Kontakt-URIs separat abzufragen, wie es bei
ACTION_PICKerforderlich ist. Diese Effizienz reduziert den Systemaufwand weiter, da nur eine einzigeBinder-Transaktion verwendet wird.
Abwärtskompatibilität und Implementierung
Bei Geräten mit Android 17 oder höher werden Legacy-ACTION_PICK-Intents, in denen Kontaktdatentypen angegeben sind, automatisch auf die neue, sicherere Schnittstelle aktualisiert. Um jedoch erweiterte Funktionen wie die Mehrfachauswahl optimal nutzen zu können, sollten Entwickler ihren Implementierungscode aktualisieren und den zurückgegebenen Sitzungs-URI mit ContentResolver abfragen.
Kontaktauswahl integrierenEntwickler verwenden den Intent ACTION_PICK_CONTACTS, um die Kontaktauswahl zu integrieren. Unten sehen Sie ein Codebeispiel, das zeigt, wie Sie die Auswahl starten und bestimmte Datenfelder wie E-Mail-Adressen und Telefonnummern anfordern.
// 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 Kontaktdaten 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
Damit Nutzer die bestmögliche Erfahrung machen und hohe Sicherheitsstandards eingehalten werden, empfehlen wir Folgendes:
- Datenminimierung:Fordern Sie nur die spezifischen Datenfelder (z.B. E-Mail-Adresse) an, die Ihre App benötigt.
- Sofortige Persistenz:Ausgewählte Daten werden sofort gespeichert, da der Zugriff auf den Sitzungs-URI nur vorübergehend ist.
-
ProduktneuigkeitenEingebettete Bildauswahl: Eine nahtlosere Möglichkeit, in Ihrer App privat Fotos und Videos anzufordern.
Roxanna Aliabadi Walker, Yacine Rezgui • Lesezeit: 8 Minuten -
ProduktneuigkeitenWir erweitern unsere Abo-Plattform auf Google Play kontinuierlich, damit Sie Ihren Umsatz steigern, sich an neue Geschäftsmodelle anpassen und Ihre Nutzer dort erreichen können, wo sie sich gerade befinden.
Sheenam Mittal • Lesezeit: 4 Minuten -
ProduktneuigkeitenLetztes Jahr wurde Android Studio für alle KI-Modelle geöffnet. Heute gehen wir den nächsten Schritt und führen Unterstützung für Coding-Agents Ihrer Wahl ein.
Matthew Warner • Lesezeit: 3 Minuten
Lassen Sie sich Woche für Woche die neuesten Informationen zur Android-Entwicklung zusenden.