Como gerar resultados com uma Activity

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

Por exemplo, o aplicativo pode iniciar um app de câmera e receber a foto capturada como resultado. Ou você pode iniciar o app Pessoas para que o usuário selecione um contato e 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. Sua atividade a recebe no callback onActivityResult().

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

Iniciar a atividade

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

O argumento de número inteiro é um "código de solicitação" que identifica sua solicitação. Quando você recebe o resultado Intent, o callback fornece o mesmo código de solicitação para que seu app possa identificar corretamente o resultado e determinar como lidar com ele.

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 transmitido para startActivityForResult().
  • Um código de resultado especificado pela segunda atividade. Se a operação for bem-sucedida, isso será RESULT_OK, ou será RESULT_CANCELED se o usuário tiver desistido ou se a operação tiver falhado por algum motivo.
  • Um Intent que carrega 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 apps Contatos ou Pessoas do Android fornece um Uri de conteúdo que identifica o contato escolhido pelo usuário.

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

Bônus: ler os dados de contato

O código acima, que mostra como receber um resultado do app Pessoas, não traz muitos detalhes sobre como exatamente ler os dados do resultado porque é exige 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: antes do Android 2.3 (API de nível 9), realizar uma consulta no Contacts Provider (como o mostrado acima) exige que seu app declare a permissão READ_CONTACTS (consulte Segurança e permissões). Contudo, a partir do Android 2.3, o app Contatos/Pessoas dá ao seu aplicativo permissão temporária para ler a partir do Provedor de contatos quando ele retorna um resultado. A permissão temporária se aplica apenas ao contato específico solicitado, então não é possível consultar um contato diferente daquele especificado pelo Uri do intent, a menos que você declare a permissão READ_CONTACTS.

Para mais informações sobre os tópicos desta página, consulte os seguintes recursos: