Como gerar resultados com uma Activity

Iniciar outra atividade não precisa ser algo unidirecional. Você também pode iniciar outra atividade e retornar um resultado. Para receber um resultado, chame startActivityForResult(), em vez de startActivity().

Por exemplo, o aplicativo pode iniciar um aplicativo de câmera e receber a foto capturada como resultado. Ou, ao iniciar o aplicativo Pessoas para que o usuário selecione um contato, você receberá os detalhes do contato como resultado.

Evidentemente, a atividade que responde precisa ser projetada para retornar um resultado. Quando isso acontecer, ela enviará o resultado como outro objeto Intent. A atividade recebe o resultado no callback onActivityResult().

Observação: você pode usar intents explícitos ou implícitos ao chamar startActivityForResult(). Ao iniciar uma das suas atividades para gerar um resultado, use um intent explícito para garantir que você receberá o resultado esperado.

Iniciar a Activity

Não há nada de especial no objeto Intent usado ao iniciar uma atividade para um resultado, mas é preciso passar um argumento de número inteiro adicional ao método startActivityForResult().

O argumento de número inteiro é um “código” que identifica a solicitação. Quando você recebe o resultado Intent, o callback fornece o mesmo código de solicitação para que o aplicativo possa identificar adequadamente o resultado e determinar como processá-lo.

Por exemplo, veja como iniciar uma atividade que permite ao usuário escolher um contato:

Kotlin

const val PICK_CONTACT_REQUEST = 1  // The request code
...
private fun pickContact() {
    Intent(Intent.ACTION_PICK, Uri.parse("content://contacts")).also { pickContactIntent ->
        pickContactIntent.type = Phone.CONTENT_TYPE // Show user only contacts w/ phone numbers
        startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST)
    }
}

Java

static final int PICK_CONTACT_REQUEST = 1;  // The request code
...
private void pickContact() {
    Intent pickContactIntent = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts"));
    pickContactIntent.setType(Phone.CONTENT_TYPE); // Show user only contacts w/ phone numbers
    startActivityForResult(pickContactIntent, PICK_CONTACT_REQUEST);
}

Receber o resultado

Quando o usuário termina a atividade subsequente e retorna, o sistema chama o método onActivityResult() da atividade. Esse método inclui três argumentos:

  • O código de solicitação passado para startActivityForResult().
  • Um código de resultado especificado pela segunda atividade. Se a operação for concluída, isso será RESULT_OK. E será RESULT_CANCELED se o usuário desistir ou a operação falhar por algum motivo.
  • Um Intent que transporta os dados do resultado.

Por exemplo, veja como você pode processar o resultado do intent “escolher um contato”:

Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    // Check which request we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == Activity.RESULT_OK) {
            // The user picked a contact.
            // The Intent's data Uri identifies which contact was selected.

            // Do something with the contact here (bigger example below)
        }
    }
}

Java

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // The user picked a contact.
            // The Intent's data Uri identifies which contact was selected.

            // Do something with the contact here (bigger example below)
        }
    }
}

Nesse exemplo, o resultado Intent retornado pelos aplicativos Contatos ou Pessoas do Android fornece um conteúdo Uri que identifica o contato escolhido pelo usuário.

Para que o resultado seja processado da maneira correta, é preciso saber o formato do resultado Intent. Isso é fácil quando umas das suas atividades retorna o resultado. Os aplicativos incluídos na plataforma Android oferecem as próprias APIs que podem ser usadas para dados de resultados específicos. Por exemplo, o aplicativo Pessoas sempre retorna um resultado com URI de conteúdo que identifica o contato escolhido, e o aplicativo Câmera retorna um Bitmap no "data" extra. Consulte a lição Como capturar fotos.

Bônus: ler os dados do contato

O código acima, que mostra como gerar um resultado do aplicativo Pessoas, não traz muitos detalhes sobre como exatamente ler os dados do resultado porque isso requer uma discussão mais avançada sobre provedores de conteúdo. No entanto, se você quiser saber mais, aqui estão alguns códigos que mostram como consultar os dados de resultado para receber o número de telefone do contato selecionado:

Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    // Check which request it is that we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == Activity.RESULT_OK) {
            // We only need the NUMBER column, because there will be only one row in the result
            val projection: Array<String> = arrayOf(Phone.NUMBER)

            // Get the URI that points to the selected contact
            data.data?.also { contactUri ->
                // Perform the query on the contact to get the NUMBER column
                // We don't need a selection or sort order (there's only one result for this URI)
                // CAUTION: The query() method should be called from a separate thread to avoid
                // blocking your app's UI thread. (For simplicity of the sample, this code doesn't
                // do that.)
                // Consider using <code><a href="/reference/android/content/CursorLoader.html">CursorLoader</a></code> to perform the query.
                contentResolver.query(contactUri, projection, null, null, null)?.apply {
                    moveToFirst()

                    // Retrieve the phone number from the NUMBER column
                    val column: Int = getColumnIndex(Phone.NUMBER)
                    val number: String? = getString(column)

                    // Do something with the phone number...
                }
            }
        }
    }
}

Java

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent resultIntent) {
    // Check which request it is that we're responding to
    if (requestCode == PICK_CONTACT_REQUEST) {
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            // Get the URI that points to the selected contact
            Uri contactUri = resultIntent.getData();
            // We only need the NUMBER column, because there will be only one row in the result
            String[] projection = {Phone.NUMBER};

            // Perform the query on the contact to get the NUMBER column
            // We don't need a selection or sort order (there's only one result for the given URI)
            // CAUTION: The query() method should be called from a separate thread to avoid blocking
            // your app's UI thread. (For simplicity of the sample, this code doesn't do that.)
            // Consider using <code><a href="/reference/android/content/CursorLoader.html">CursorLoader</a></code> to perform the query.
            Cursor cursor = getContentResolver()
                    .query(contactUri, projection, null, null, null);
            cursor.moveToFirst();

            // Retrieve the phone number from the NUMBER column
            int column = cursor.getColumnIndex(Phone.NUMBER);
            String number = cursor.getString(column);

            // Do something with the phone number...
        }
    }
}

Observação: se você usar uma versão anterior ao Android 2.3 (API de nível 9), executar uma consulta em Contacts Provider (como mostrado acima) exigirá que o aplicativo declare a permissão READ_CONTACTS. Consulte Segurança e permissões. Contudo, a partir do Android 2.3, o aplicativo Contatos/Pessoas oferece uma permissão temporária ao seu aplicativo para que ele possa ler do Provedor de contatos quando retornar um resultado. A permissão temporária se aplica apenas a pedidos de contatos específicos. Por isso, não é possível consultar um contato diferente daquele especificado pela Uri do intent a menos que você declare a permissão READ_CONTACTS.

Para informações adicionais sobre os tópicos desta página, consulte os recursos a seguir: