In dieser Lektion wird gezeigt, wie du mit einem Intent einen neuen Kontakt einfügst oder die Daten eines Kontakts änderst. Anstatt direkt auf den Contacts Provider zuzugreifen, startet ein Intent die Kontakte App, die den entsprechenden Activity ausführt. Wenn Sie bei den in dieser Lektion beschriebenen Änderungsaktionen erweiterte Daten im Intent senden, werden diese in die Benutzeroberfläche des gestarteten Activity eingegeben.
Die Verwendung eines Intent zum Einfügen oder Aktualisieren eines einzelnen Kontakts ist aus folgenden Gründen die bevorzugte Methode zum Ändern des Contacts Providers:
- Sie sparen Zeit und Aufwand für die Entwicklung einer eigenen Benutzeroberfläche und von Code.
- Es werden keine Fehler durch Änderungen verursacht, die nicht den Regeln des Contacts Providers entsprechen.
- Die Anzahl der Berechtigungen, die Sie anfordern müssen, wird reduziert. Ihre App benötigt keine Berechtigung zum Schreiben in den Contacts Provider, da sie Änderungen an die Kontakte App delegiert, die diese Berechtigung bereits hat.
Neuen Kontakt mithilfe eines Intents einfügen
Häufig möchten Sie dem Nutzer erlauben, einen neuen Kontakt einzufügen, wenn Ihre App neue Daten empfängt. In einer App für Restaurantbewertungen können Nutzer beispielsweise das Restaurant als Kontakt hinzufügen, während sie es bewerten. Wenn du dazu einen Intent verwenden möchtest, erstelle ihn mit so vielen Daten wie möglich und sende ihn dann an die Kontakte App.
Wenn du einen Kontakt über die Kontakte App einfügst, wird ein neuer Rohkontakt in die Tabelle ContactsContract.RawContacts des Contacts Providers eingefügt. Falls erforderlich, werden Nutzer in der Kontakte App aufgefordert, den Kontotyp und das Konto anzugeben, die beim Erstellen des Rohkontakts verwendet werden sollen. Die Kontakte App benachrichtigt Nutzer auch, wenn der Rohkontakt bereits vorhanden ist. Nutzer haben dann die Möglichkeit, das Einfügen abzubrechen. In diesem Fall wird kein Kontakt erstellt. Weitere Informationen zu Rohkontakten finden Sie im API-Leitfaden zu Contacts Provider.
Intent erstellen
Erstellen Sie zuerst ein neues Intent-Objekt mit der Aktion Intents.Insert.ACTION.
Legen Sie den MIME-Typ auf RawContacts.CONTENT_TYPE fest. Beispiel:
Kotlin
... // Creates a new Intent to insert a contact val intent = Intent(ContactsContract.Intents.Insert.ACTION).apply { // Sets the MIME type to match the Contacts Provider type = ContactsContract.RawContacts.CONTENT_TYPE }
Java
... // Creates a new Intent to insert a contact Intent intent = new Intent(ContactsContract.Intents.Insert.ACTION); // Sets the MIME type to match the Contacts Provider intent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
Wenn du bereits Details zum Kontakt hast, z. B. eine Telefonnummer oder E-Mail-Adresse, kannst du diese als erweiterte Daten in den Intent einfügen. Verwenden Sie für einen Schlüsselwert die entsprechende Konstante aus Intents.Insert. Die Kontakte App zeigt die Daten auf dem Bildschirm zum Einfügen an, sodass Nutzer weitere Änderungen und Ergänzungen vornehmen können.
Kotlin
private var emailAddress: EditText? = null private var phoneNumber: EditText? = null ... /* Assumes EditText fields in your UI contain an email address * and a phone number. * */ emailAddress = findViewById(R.id.email) phoneNumber = findViewById(R.id.phone) ... /* * Inserts new data into the Intent. This data is passed to the * contacts app's Insert screen */ intent.apply { // Inserts an email address putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress?.text) /* * In this example, sets the email type to be a work email. * You can set other email types as necessary. */ putExtra( ContactsContract.Intents.Insert.EMAIL_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK ) // Inserts a phone number putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber?.text) /* * In this example, sets the phone type to be a work phone. * You can set other phone types as necessary. */ putExtra( ContactsContract.Intents.Insert.PHONE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK ) }
Java
private EditText emailAddress = null; private EditText phoneNumber = null; ... /* Assumes EditText fields in your UI contain an email address * and a phone number. * */ emailAddress = (EditText) findViewById(R.id.email); phoneNumber = (EditText) findViewById(R.id.phone); ... /* * Inserts new data into the Intent. This data is passed to the * contacts app's Insert screen */ // Inserts an email address intent.putExtra(ContactsContract.Intents.Insert.EMAIL, emailAddress.getText()) /* * In this example, sets the email type to be a work email. * You can set other email types as necessary. */ .putExtra(ContactsContract.Intents.Insert.EMAIL_TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK) // Inserts a phone number .putExtra(ContactsContract.Intents.Insert.PHONE, phoneNumber.getText()) /* * In this example, sets the phone type to be a work phone. * You can set other phone types as necessary. */ .putExtra(ContactsContract.Intents.Insert.PHONE_TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
Nachdem Sie die Intent erstellt haben, senden Sie sie durch Aufrufen von startActivity().
Kotlin
/* Sends the Intent */ startActivity(intent)
Java
/* Sends the Intent */ startActivity(intent);
Mit diesem Aufruf wird in der Kontakte App ein Bildschirm geöffnet, auf dem Nutzer einen neuen Kontakt eingeben können. Der Kontotyp und der Kontoname für den Kontakt werden oben auf dem Bildschirm angezeigt. Nachdem die Nutzer die Daten eingegeben und auf Fertig geklickt haben, wird die Kontaktliste der Kontakte App angezeigt. Nutzer kehren zu Ihrer App zurück, indem sie auf Zurück klicken.
Vorhandenen Kontakt mit einem Intent bearbeiten
Das Bearbeiten eines vorhandenen Kontakts mit einem Intent ist nützlich, wenn der Nutzer bereits einen Kontakt ausgewählt hat. Beispielsweise könnte eine App, die Kontakte mit Postanschriften, aber ohne Postleitzahl findet, Nutzern die Möglichkeit geben, die Postleitzahl zu suchen und dann dem Kontakt hinzuzufügen.
Wenn du einen vorhandenen Kontakt mithilfe eines Intents bearbeiten möchtest, gehe ähnlich vor wie beim Einfügen eines Kontakts. Erstelle einen Intent, wie im Abschnitt Neuen Kontakt mithilfe eines Intents einfügen beschrieben, füge dem Intent aber die Contacts.CONTENT_LOOKUP_URI des Kontakts und den MIME-Typ Contacts.CONTENT_ITEM_TYPE hinzu. Wenn du den Kontakt mit bereits vorhandenen Details bearbeiten möchtest, kannst du diese in die erweiterten Daten des Intents einfügen. Beachten Sie, dass einige Namensspalten nicht mit einem Intent bearbeitet werden können. Diese Spalten sind im Abschnitt „Zusammenfassung“ der API-Referenz für die Klasse ContactsContract.Contacts unter der Überschrift „Update“ aufgeführt.
Senden Sie schließlich den Intent. Daraufhin wird in der Kontakte App ein Bearbeitungsbildschirm angezeigt. Wenn der Nutzer die Bearbeitung abgeschlossen und die Änderungen gespeichert hat, wird in der Kontakte App eine Kontaktliste angezeigt. Wenn der Nutzer auf Zurück klickt, wird Ihre App angezeigt.
Intent erstellen
Wenn du einen Kontakt bearbeiten möchtest, rufe Intent(action) auf, um einen Intent mit der Aktion ACTION_EDIT zu erstellen. Rufe setDataAndType() auf, um den Datenwert für den Intent auf den Contacts.CONTENT_LOOKUP_URI des Kontakts und den MIME-Typ auf den MIME-Typ Contacts.CONTENT_ITEM_TYPE festzulegen. Da ein Aufruf von setType() den aktuellen Datenwert für den Intent überschreibt, musst du die Daten und den MIME-Typ gleichzeitig festlegen.
Wenn Sie die Contacts.CONTENT_LOOKUP_URI eines Kontakts abrufen möchten, rufen Sie Contacts.getLookupUri(id, lookupkey) mit den Werten Contacts._ID und Contacts.LOOKUP_KEY des Kontakts als Argumente auf.
Hinweis: Der LOOKUP_KEY-Wert eines Kontakts ist die Kennung, die Sie zum Abrufen eines Kontakts verwenden sollten. Sie bleibt konstant, auch wenn der Anbieter die Zeilen-ID des Kontakts ändert, um interne Vorgänge zu verarbeiten.
Das folgende Snippet zeigt, wie Sie einen Intent erstellen:
Kotlin
// The Cursor that contains the Contact row var mCursor: Cursor? = null // The index of the lookup key column in the cursor var lookupKeyIndex: Int = 0 // The index of the contact's _ID value var idIndex: Int = 0 // The lookup key from the Cursor var currentLookupKey: String? = null // The _ID value from the Cursor var currentId: Long = 0 // A content URI pointing to the contact var selectedContactUri: Uri? = null ... /* * Once the user has selected a contact to edit, * this gets the contact's lookup key and _ID values from the * cursor and creates the necessary URI. */ mCursor?.apply { // Gets the lookup key column index lookupKeyIndex = getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY) // Gets the lookup key value currentLookupKey = getString(lookupKeyIndex) // Gets the _ID column index idIndex = getColumnIndex(ContactsContract.Contacts._ID) currentId = getLong(idIndex) selectedContactUri = ContactsContract.Contacts.getLookupUri(currentId, mCurrentLookupKey) } // Creates a new Intent to edit a contact val editIntent = Intent(Intent.ACTION_EDIT).apply { /* * Sets the contact URI to edit, and the data type that the * Intent must match */ setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE) }
Java
// The Cursor that contains the Contact row public Cursor mCursor; // The index of the lookup key column in the cursor public int lookupKeyIndex; // The index of the contact's _ID value public int idIndex; // The lookup key from the Cursor public String currentLookupKey; // The _ID value from the Cursor public long currentId; // A content URI pointing to the contact Uri selectedContactUri; ... /* * Once the user has selected a contact to edit, * this gets the contact's lookup key and _ID values from the * cursor and creates the necessary URI. */ // Gets the lookup key column index lookupKeyIndex = mCursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY); // Gets the lookup key value currentLookupKey = mCursor.getString(lookupKeyIndex); // Gets the _ID column index idIndex = mCursor.getColumnIndex(ContactsContract.Contacts._ID); currentId = mCursor.getLong(idIndex); selectedContactUri = Contacts.getLookupUri(currentId, mCurrentLookupKey); ... // Creates a new Intent to edit a contact Intent editIntent = new Intent(Intent.ACTION_EDIT); /* * Sets the contact URI to edit, and the data type that the * Intent must match */ editIntent.setDataAndType(selectedContactUri, ContactsContract.Contacts.CONTENT_ITEM_TYPE);
Navigations-Flag hinzufügen
In Android 4.0 (API-Version 14) und höher führt ein Problem in der Kontakte App zu einer fehlerhaften Navigation. Wenn deine App einen Bearbeitungs-Intent an die Kontakte App sendet und Nutzer einen Kontakt bearbeiten und speichern, wird ihnen nach dem Klicken auf Zurück die Kontaktliste angezeigt. Um zu Ihrer App zurückzukehren, müssen sie auf Zuletzt verwendet klicken und Ihre App auswählen.
Um dieses Problem in Android 4.0.3 (API-Version 15) und höher zu umgehen, fügen Sie dem Intent den erweiterten Datenschlüssel finishActivityOnSaveCompleted mit dem Wert true hinzu.
Android-Versionen vor Android 4.0 akzeptieren diesen Schlüssel, er hat jedoch keine Auswirkungen. So legen Sie die erweiterten Daten fest:
Kotlin
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true)
Java
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true);
Weitere erweiterte Daten hinzufügen
Wenn Sie dem Intent zusätzliche erweiterte Daten hinzufügen möchten, rufen Sie bei Bedarf putExtra() auf.
Sie können erweiterte Daten für gängige Kontaktfelder hinzufügen, indem Sie die in Intents.Insert angegebenen Schlüsselwerte verwenden. Denken Sie daran, dass einige Spalten in der Tabelle ContactsContract.Contacts nicht geändert werden können.
Diese Spalten sind im Abschnitt „Zusammenfassung“ der API-Referenz für die Klasse ContactsContract.Contacts unter der Überschrift „Update“ aufgeführt.
Intent senden
Senden Sie schließlich den erstellten Intent. Beispiel:
Kotlin
// Sends the Intent startActivity(editIntent)
Java
// Sends the Intent startActivity(editIntent);
Nutzern die Möglichkeit geben, Inhalte per Intent einzufügen oder zu bearbeiten
Du kannst Nutzern die Möglichkeit geben, einen Kontakt einzufügen oder einen vorhandenen Kontakt zu bearbeiten, indem du einen Intent mit der Aktion ACTION_INSERT_OR_EDIT sendest. Beispielsweise könnte eine E-Mail-Client-App Nutzern ermöglichen, eine eingehende E-Mail-Adresse einem neuen Kontakt hinzuzufügen oder sie als zusätzliche Adresse für einen vorhandenen Kontakt hinzuzufügen. Legen Sie den MIME-Typ für diesen Intent auf Contacts.CONTENT_ITEM_TYPE fest, aber nicht den Daten-URI.
Wenn Sie diesen Intent senden, wird in der Kontakte App eine Liste der Kontakte angezeigt.
Nutzer können entweder einen neuen Kontakt einfügen oder einen vorhandenen Kontakt auswählen und bearbeiten.
Alle erweiterten Datenfelder, die Sie dem Intent hinzufügen, werden auf dem angezeigten Bildschirm ausgefüllt. Sie können einen beliebigen Schlüsselwert verwenden, der in Intents.Insert angegeben ist. Das folgende Code-Snippet zeigt, wie der Intent erstellt und gesendet wird:
Kotlin
// Creates a new Intent to insert or edit a contact val intentInsertEdit = Intent(Intent.ACTION_INSERT_OR_EDIT).apply { // Sets the MIME type type = ContactsContract.Contacts.CONTENT_ITEM_TYPE } // Add code here to insert extended data, if desired // Sends the Intent with an request ID startActivity(intentInsertEdit)
Java
// Creates a new Intent to insert or edit a contact Intent intentInsertEdit = new Intent(Intent.ACTION_INSERT_OR_EDIT); // Sets the MIME type intentInsertEdit.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE); // Add code here to insert extended data, if desired ... // Sends the Intent with an request ID startActivity(intentInsertEdit);