Esta lição mostra como usar uma Intent para inserir um novo contato ou
modificar os dados de um contato. Em vez de acessar o Provedor de contatos diretamente, uma
Intent inicia o app Contatos, que executa a
Activity adequada. Para as ações de modificação descritas nesta lição,
se você enviar dados estendidos no Intent, eles serão inseridos na IU do
Activity iniciado.
Usar um Intent para inserir ou atualizar um único contato é a maneira preferida
de modificar o Provedor de contatos, pelos seguintes motivos:
- Isso economiza o tempo e o esforço necessários para desenvolver sua IU e o código.
- Isso evita erros causados por modificações que não seguem as regras do Provedor de contatos.
- Ele reduz o número de permissões que você precisa solicitar. Seu app não precisa de permissão para gravar no Provedor de contatos, porque ele delega modificações ao app Contatos, que já tem essa permissão.
Inserir um novo contato usando uma intent
Em geral, você permite que o usuário insira um novo contato quando seu app recebe novos dados. Por exemplo, um app de avaliação de restaurantes pode permitir que os usuários adicionem o restaurante como um contato enquanto fazem a avaliação. Para fazer isso usando uma intent, crie-a com o máximo de dados disponíveis e envie-a para o app Contatos.
A inserção de um contato usando o app Contatos insere um novo contato bruto na tabela ContactsContract.RawContacts do Provedor de contatos. Se necessário,
o app Contatos solicita que os usuários informem o tipo de conta e a conta que será usada ao criar o contato
bruto. O app de contatos também notifica os usuários se o contato bruto já existe. Os usuários têm
a opção de cancelar a inserção. Nesse caso, nenhum contato é criado. Para saber
mais sobre contatos brutos, consulte o guia da API
Provedor de contatos.
Como criar uma intent
Para começar, crie um novo objeto Intent com a ação
Intents.Insert.ACTION.
Defina o tipo MIME como RawContacts.CONTENT_TYPE. Exemplo:
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);
Se você já tiver detalhes do contato, como um número de telefone ou endereço de e-mail, poderá
inseri-los na intent como dados estendidos. Para um valor de chave, use a constante apropriada de
Intents.Insert. O app Contatos
mostra os dados na tela de inserção, permitindo que os usuários façam outras edições e adições.
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);
Depois de criar o Intent, envie-o chamando
startActivity().
Kotlin
/* Sends the Intent */ startActivity(intent)
Java
/* Sends the Intent */ startActivity(intent);
Essa chamada abre uma tela no app de contatos que permite que os usuários insiram um novo contato. O tipo de conta e o nome da conta do contato são listados na parte de cima da tela. Depois que os usuários inserirem os dados e clicarem em Concluído, a lista de contatos do app Contatos vai aparecer. Os usuários voltam para o app clicando em Voltar.
Editar um contato já existente usando uma intent
Editar um contato usando uma Intent é útil se o usuário
já tiver escolhido um contato de interesse. Por exemplo, um app que encontra contatos que têm
endereços postais, mas não têm um código postal, pode dar aos usuários a opção de procurar o código e
adicioná-lo ao contato.
Para editar um contato usando uma intent, use um procedimento semelhante ao de
inserir um contato. Crie uma intent conforme descrito na seção
Inserir um novo contato usando uma intent, mas adicione o Contacts.CONTENT_LOOKUP_URI do contato
e o tipo MIME
Contacts.CONTENT_ITEM_TYPE à intent. Se você quiser editar o contato com detalhes que
já tem, coloque-os nos dados extras da intent. Algumas
colunas de nome não podem ser editadas usando uma intent. Elas estão listadas na seção de resumo
da referência da API para a classe ContactsContract.Contacts
no cabeçalho "Update".
Por fim, envie a intent. Como resposta, o app de contatos exibe uma tela de edição. Quando o usuário termina de editar e salva as mudanças, o app Contatos mostra uma lista de contatos. Quando o usuário clica em Voltar, o app é exibido.
Criar a intent
Para editar um contato, chame Intent(action) para
criar uma intent com a ação ACTION_EDIT. Chame
setDataAndType() para definir o valor de dados da
intent como o Contacts.CONTENT_LOOKUP_URI do contato e o tipo MIME como
Contacts.CONTENT_ITEM_TYPE. Como uma chamada para
setType() substitui o valor de dados atual da
Intent, é necessário definir os dados e o tipo MIME ao mesmo tempo.
Para receber o Contacts.CONTENT_LOOKUP_URI de um contato, chame
Contacts.getLookupUri(id, lookupkey) com os valores
Contacts._ID e
Contacts.LOOKUP_KEY do contato como
argumentos.
Observação: o valor LOOKUP_KEY de um contato é o identificador que você deve usar para recuperar um contato. Ele permanece constante,
mesmo que o provedor mude o ID da linha do contato para processar operações internas.
O seguinte snippet mostra como criar um intent:
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);
Adicionar a sinalização de navegação
No Android 4.0 (API versão 14) e versões mais recentes, um problema no app Contatos causa uma navegação incorreta. Quando o app envia uma intent de edição para o app Contatos, os usuários editam e salvam um contato e, ao clicar em Voltar, a tela da lista de contatos é mostrada. Para voltar ao app, ele precisa clicar em Recentes e escolher o app.
Para contornar esse problema no Android 4.0.3 (API versão 15) e versões mais recentes, adicione a chave de dados
estendida finishActivityOnSaveCompleted à intent, com um valor de true.
As versões do Android anteriores ao Android 4.0 aceitam essa chave, mas ela não tem efeito. Para definir os
dados estendidos, faça o seguinte:
Kotlin
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true)
Java
// Sets the special extended data for navigation editIntent.putExtra("finishActivityOnSaveCompleted", true);
Adicionar outros dados estendidos
Para adicionar mais dados estendidos ao Intent, chame
putExtra() conforme necessário.
É possível adicionar dados estendidos para campos de contato comuns usando os valores de chave especificados em
Intents.Insert. Lembre-se de que algumas
colunas na tabela ContactsContract.Contacts não podem ser modificadas.
Essas colunas estão listadas na seção de resumo da referência da API para a classe
ContactsContract.Contacts no cabeçalho "Atualizar".
Enviar a intent
Por fim, envie a intent que você construiu. Exemplo:
Kotlin
// Sends the Intent startActivity(editIntent)
Java
// Sends the Intent startActivity(editIntent);
Permitir que os usuários optem por inserir ou editar usando uma intent
Você pode permitir que os usuários escolham entre inserir um contato ou editar um contato existente enviando
uma Intent com a ação
ACTION_INSERT_OR_EDIT. Por exemplo, um app cliente de e-mail pode
permitir que os usuários adicionem um endereço de e-mail recebido a um novo contato ou como um endereço
adicional para um contato atual. Defina o tipo MIME para essa intent como
Contacts.CONTENT_ITEM_TYPE,
mas não defina o URI de dados.
Quando você enviar essa intent, o app Contatos exibirá uma lista de contatos.
Os usuários podem inserir um novo contato ou escolher um já existente e editá-lo.
Todos os campos de dados estendidos adicionados à intent preenchem a tela exibida. É possível usar
qualquer um dos valores de chave especificados em Intents.Insert. O seguinte snippet de código mostra como construir e enviar a intent:
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);