Z tej lekcji dowiesz się, jak używać Intent do wstawiania nowego kontaktu lub modyfikowania danych kontaktu. Zamiast uzyskiwać dostęp bezpośrednio do dostawcy kontaktów, Intent uruchamia aplikację Kontakty, która wykonuje odpowiednie działanie Activity. W przypadku działań modyfikacji opisanych w tej lekcji, jeśli wysyłasz rozszerzone dane w Intent, są one wprowadzane do interfejsu uruchamianego Activity.
Używanie Intent do wstawiania lub aktualizowania pojedynczego kontaktu jest preferowanym sposobem modyfikowania dostawcy kontaktów z tych powodów:
- Dzięki temu oszczędzasz czas i wysiłek związany z tworzeniem własnego interfejsu i kodu.
- Pozwala to uniknąć błędów spowodowanych modyfikacjami, które nie są zgodne z zasadami dostawcy kontaktów.
- Zmniejsza liczbę uprawnień, o które musisz poprosić. Twoja aplikacja nie potrzebuje uprawnień do zapisu u dostawcy kontaktów, ponieważ przekazuje modyfikacje do aplikacji Kontakty, która ma już te uprawnienia.
Wstawianie nowego kontaktu za pomocą intencji
Często chcesz zezwolić użytkownikowi na wstawienie nowego kontaktu, gdy aplikacja otrzyma nowe dane. Na przykład aplikacja do oceniania restauracji może umożliwiać użytkownikom dodawanie restauracji jako kontaktu podczas jej oceniania. Aby to zrobić za pomocą intencji, utwórz intencję, używając jak największej ilości dostępnych danych, a następnie wyślij ją do aplikacji Kontakty.
Wstawienie kontaktu za pomocą aplikacji Kontakty powoduje wstawienie nowego bazowego kontaktu do tabeli ContactsContract.RawContacts dostawcy kontaktów. W razie potrzeby aplikacja do obsługi kontaktów prosi użytkowników o podanie rodzaju konta i konta, którego należy użyć podczas tworzenia kontaktu bazowego. Aplikacja Kontakty powiadamia też użytkowników, jeśli kontakt bazowy już istnieje. Użytkownicy mogą wtedy anulować wstawianie, co spowoduje, że kontakt nie zostanie utworzony. Więcej informacji o kontaktach bazowych znajdziesz w przewodniku po interfejsie API Dostawca kontaktów.
Tworzenie intencji
Najpierw utwórz nowy obiekt Intent z działaniem Intents.Insert.ACTION.
Ustaw typ MIME na RawContacts.CONTENT_TYPE. Na przykład:
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);
Jeśli masz już dane kontaktu, takie jak numer telefonu lub adres e-mail, możesz je wstawić do intencji jako dane rozszerzone. W przypadku wartości klucza użyj odpowiedniej stałej z Intents.Insert. Aplikacja do obsługi kontaktów wyświetla dane na ekranie wstawiania, umożliwiając użytkownikom dalsze edytowanie i dodawanie.
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);
Po utworzeniu obiektu Intent wyślij go, wywołując startActivity().
Kotlin
/* Sends the Intent */ startActivity(intent)
Java
/* Sends the Intent */ startActivity(intent);
To wywołanie otwiera ekran w aplikacji Kontakty, który umożliwia użytkownikom wpisanie nowego kontaktu. U góry ekranu wyświetlany jest rodzaj konta i nazwa konta kontaktu. Gdy użytkownicy wpiszą dane i klikną Gotowe, pojawi się lista kontaktów w aplikacji do obsługi kontaktów. Użytkownicy wracają do aplikacji, klikając Wstecz.
Edytowanie istniejącego kontaktu za pomocą intencji
Edytowanie istniejącego kontaktu za pomocą Intent jest przydatne, jeśli użytkownik wybrał już interesujący go kontakt. Na przykład aplikacja, która znajduje kontakty z adresami pocztowymi, ale bez kodów pocztowych, może dać użytkownikom możliwość wyszukania kodu i dodania go do kontaktu.
Aby edytować istniejący kontakt za pomocą intencji, użyj procedury podobnej do wstawiania kontaktu. Utwórz intencję zgodnie z opisem w sekcji Wstawianie nowego kontaktu za pomocą intencji, ale dodaj do niej Contacts.CONTENT_LOOKUP_URI kontaktu i typ MIME Contacts.CONTENT_ITEM_TYPE. Jeśli chcesz edytować kontakt, podając informacje, które już masz, możesz je umieścić w rozszerzonych danych intencji. Zwróć uwagę, że niektórych kolumn nazw nie można edytować za pomocą intencji. Te kolumny są wymienione w sekcji podsumowania dokumentacji interfejsu API dla klasy ContactsContract.Contacts pod nagłówkiem „Aktualizacja”.
Na koniec wyślij intencję. W odpowiedzi aplikacja do obsługi kontaktów wyświetli ekran edycji. Gdy użytkownik zakończy edytowanie i zapisze zmiany, aplikacja Kontakty wyświetli listę kontaktów. Gdy użytkownik kliknie Wstecz, wyświetli się Twoja aplikacja.
Tworzenie intencji
Aby edytować kontakt, wywołaj Intent(action), aby utworzyć intencję z działaniem ACTION_EDIT. Wywołaj setDataAndType(), aby ustawić wartość danych intencji na Contacts.CONTENT_LOOKUP_URI kontaktu, a typ MIME na Contacts.CONTENT_ITEM_TYPE. Wywołanie setType() zastępuje bieżącą wartość danych Intent, dlatego musisz ustawić dane i typ MIME jednocześnie.
Aby uzyskać Contacts.CONTENT_LOOKUP_URI kontaktu, wywołaj Contacts.getLookupUri(id, lookupkey) z wartościami Contacts._ID i Contacts.LOOKUP_KEY kontaktu jako argumentami.
Uwaga: wartość LOOKUP_KEY kontaktu to identyfikator, którego należy użyć do pobrania kontaktu. Pozostaje on niezmienny, nawet jeśli dostawca zmieni identyfikator wiersza kontaktu, aby obsłużyć operacje wewnętrzne.
Poniższy fragment kodu pokazuje, jak utworzyć intencję:
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);
Dodawanie flagi nawigacji
W Androidzie 4.0 (API w wersji 14) i nowszych problem w aplikacji Kontakty powoduje nieprawidłową nawigację. Gdy aplikacja wysyła intencję edycji do aplikacji Kontakty, a użytkownicy edytują i zapisują kontakt, po kliknięciu Wstecz widzą ekran listy kontaktów. Aby wrócić do aplikacji, musi kliknąć Ostatnie i wybrać aplikację.
Aby obejść ten problem w Androidzie 4.0.3 (interfejs API w wersji 15) i nowszych, dodaj do intencji klucz danych rozszerzonych finishActivityOnSaveCompleted z wartością true.
Wersje Androida starsze niż Android 4.0 akceptują ten klucz, ale nie ma on żadnego wpływu. Aby ustawić rozszerzone dane, wykonaj te czynności:
Kotlin
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true)
Java
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true);
Dodawanie innych danych rozszerzonych
Aby dodać do Intent dodatkowe rozszerzone dane, wywołaj putExtra().
Możesz dodać rozszerzone dane do typowych pól kontaktów, używając wartości kluczy określonych w Intents.Insert. Pamiętaj, że niektórych kolumn w tabeli ContactsContract.Contacts nie można modyfikować.
Te kolumny są wymienione w sekcji podsumowania dokumentacji API dla klasy ContactsContract.Contacts pod nagłówkiem „Update” (Aktualizacja).
Wysyłanie intencji
Na koniec wyślij utworzoną intencję. Na przykład:
Kotlin
// Sends the Intent startActivity(editIntent)
Java
// Sends the Intent startActivity(editIntent);
Zezwalanie użytkownikom na wstawianie lub edytowanie za pomocą intencji
Możesz pozwolić użytkownikom wybrać, czy chcą wstawić kontakt, czy edytować istniejący, wysyłając obiekt Intent z działaniem ACTION_INSERT_OR_EDIT. Na przykład aplikacja klienta poczty e-mail może umożliwiać użytkownikom dodawanie adresu e-mail nadawcy do nowego kontaktu lub jako dodatkowego adresu istniejącego kontaktu. Ustaw typ MIME dla tej intencji na Contacts.CONTENT_ITEM_TYPE, ale nie ustawiaj identyfikatora URI danych.
Gdy wyślesz tę intencję, aplikacja do obsługi kontaktów wyświetli listę kontaktów.
Użytkownicy mogą wstawić nowy kontakt lub wybrać istniejący i go edytować.
Wszystkie rozszerzone pola danych dodane do intencji wypełniają wyświetlany ekran. Możesz użyć dowolnej wartości klucza określonej w Intents.Insert. Poniższy fragment kodu pokazuje, jak utworzyć i wysłać intencję:
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);