Register now for Android Dev Summit 2019!

Como permitir que outros aplicativos iniciem sua Activity

Caso seu aplicativo possa executar uma ação que talvez seja útil para outro aplicativo, ele deverá estar preparado para responder a solicitações de ação especificando o filtro de intents apropriado na sua atividade.

Por exemplo, se você criar um aplicativo social que possa compartilhar mensagens ou fotos com os amigos do usuário, ele precisará ser compatível com o intent ACTION_SEND. Em seguida, quando os usuários iniciam uma ação de “compartilhamento” de outro aplicativo, seu aplicativo aparece como uma opção na caixa de diálogo do seletor (também conhecida como “diálogo de desambiguação”), conforme mostrado na figura 1.

Figura 1. A caixa de diálogo do seletor

Para permitir que outros aplicativos iniciem sua atividade dessa maneira, é preciso adicionar um elemento <intent-filter> ao seu arquivo de manifesto para o elemento <activity> correspondente.

Quando o aplicativo é instalado em um dispositivo, o sistema identifica seus filtros de intents e adiciona as informações a um catálogo interno de intents compatíveis com todos os aplicativos instalados. Quando seu aplicativo chamar startActivity() ou startActivityForResult() com um intent implícito, o sistema descobrirá qual atividade (ou atividades) pode responder a ele.

Adicionar um filtro de intents

Para definir adequadamente os intents que sua atividade poderá processar, cada filtro de intents adicionado deverá ser o mais específico possível em termos de tipo de ação e dados aceitos pela atividade.

O sistema pode enviar um Intent para uma atividade se ela tiver um filtro de intents que atenda aos seguintes critérios do objeto Intent:

Ação
A string que dá nome à ação a ser executada. Geralmente, um dos valores definidos pela plataforma, como ACTION_SEND ou ACTION_VIEW.

Especifique-a em seu filtro de intents com o elemento <action>. O valor especificado nesse elemento precisa ser o nome completo da string para a ação, em vez da constante da API (veja os exemplos abaixo).

Dados
A descrição dos dados associados ao intent.

Especifique-a em seu filtro de intents com o elemento <data>. Usando um ou mais atributos nesse elemento, você pode especificar apenas o tipo MIME, somente um prefixo de URI e um esquema de URI ou uma combinação desses e de outros elementos que indicam o tipo de dados aceito.

Observação: se não for necessário especificar os dados Uri (como quando a atividade processa outros tipos de dados “extras”, em vez de um URI), informe apenas o atributo android:mimeType para declarar o tipo de dado que a atividade processa, como text/plain ou image/jpeg.

Categoria
Oferece uma forma adicional de caracterizar a atividade que processa o intent, geralmente relacionada ao gesto do usuário ou ao local onde ela foi iniciada. Há diversas categorias compatíveis com o sistema, mas a maioria raramente é usada. No entanto, todos os intents implícitos são definidos com CATEGORY_DEFAULT por padrão.

Especifique-a em seu filtro de intents com o elemento <category>.

No filtro de intents, informe quais critérios serão aceitos pela atividade declarando cada um deles com elementos XML correspondentes aninhados no elemento <intent-filter>.

Este é um exemplo de atividade com filtro de intents que processa o intent ACTION_SEND quando o tipo de dado é texto ou imagem:

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

Dica: se você quiser que o ícone na caixa de diálogo do seletor seja diferente do padrão da sua atividade, adicione android:icon ao elemento <intent-filter>.

Cada intent recebido especifica apenas uma ação e um tipo de dado, mas é possível declarar várias instâncias dos elementos <action>, <category> e <data> em cada <intent-filter>.

Se dois pares de ação e dados forem mutuamente exclusivos no comportamento, crie filtros de intents separados para especificar as ações que são aceitáveis quando pareadas com que tipo de dado.

Suponha que a atividade processe texto e imagens para os intents ACTION_SEND e ACTION_SENDTO. Nesse caso, é preciso definir dois filtros de intents para as duas ações porque um intent ACTION_SENDTO deve usar os dados de Uri para especificar o endereço do destinatário usando o esquema de URI send ou sendto. Por exemplo:

<activity android:name="ShareActivity">
    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

Observação: para receber intents implícitos, inclua a categoria CATEGORY_DEFAULT no filtro de intents. Os métodos startActivity() e startActivityForResult() tratam de todos os intents como se eles declarassem a categoria CATEGORY_DEFAULT. Se você não a declarar no seu filtro de intents, nenhum intent implícito será resolvido para sua atividade.

Para mais informações sobre o envio e o recebimento de intents ACTION_SEND que realizam comportamentos de compartilhamento social, consulte a lição Recebimento de dados simples de outros aplicativos. Você também pode encontrar informações úteis sobre o compartilhamento de dados em Compartilhamento de dados simples e Compartilhamento de arquivos.

Processar o intent na sua Activity

Para decidir qual ação tomar em sua atividade, leia o Intent usado para iniciá-la.

Quando a atividade iniciar, chame getIntent() para recuperar o Intent que iniciou a atividade. Você pode fazer isso a qualquer momento durante o ciclo de vida da atividade, mas é recomendável usar o recurso em retornos de chamada iniciais, como onCreate() ou onStart().

Por exemplo:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main)

    val data: Uri? = intent?.data

    // Figure out what to do based on the intent type
    if (intent?.type?.startsWith("image/") == true) {
        // Handle intents with image data ...
    } else if (intent?.type == "text/plain") {
        // Handle intents with text ...
    }
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();

    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data ...
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text ...
    }
}

Retornar um resultado

Se você quiser retornar um resultado para a atividade que invocou a sua, basta chamar setResult() para especificar o código do resultado e o Intent de resultado. Quando a operação estiver concluída e o usuário precisar retornar à atividade original, chame finish() para fechar (e destruir) a atividade. Por exemplo:

Kotlin

// Create intent to deliver some kind of result data
Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result ->
    setResult(Activity.RESULT_OK, result)
}
finish()

Java

// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();

Sempre especifique um código de resultado com o resultado. Geralmente, é RESULT_OK ou RESULT_CANCELED. É possível fornecer dados adicionais com um Intent, caso seja necessário.

Observação: o resultado é definido como RESULT_CANCELED por padrão. Portanto, se o usuário pressionar o botão Back antes de concluir a ação e de você definir o resultado, a atividade original receberá o resultado “cancelado”.

Se precisar simplesmente retornar um número inteiro que indica uma das várias opções de resultado, você poderá definir o código de resultado como qualquer valor maior que 0. Se usar o código de resultado para entregar um número inteiro e não tiver necessidade de incluir o Intent, você poderá chamar setResult() e passar apenas um código de resultado. Por exemplo:

Kotlin

setResult(RESULT_COLOR_RED)
finish()

Java

setResult(RESULT_COLOR_RED);
finish();

Nesse caso, talvez existam apenas alguns poucos resultados possíveis. Portanto, o código do resultado é um número inteiro definido localmente (maior que 0). Isso funciona bem ao retornar um resultado para uma atividade no seu aplicativo porque a atividade que recebe o resultado pode fazer uma referência à constante pública para determinar o valor do código de resultado.

Observação: não há necessidade de verificar se a atividade foi iniciada com startActivity() ou startActivityForResult(). Simplesmente chame setResult() se o intent que iniciou sua atividade estiver esperando um resultado. Se a atividade inicial tivesse chamado startActivityForResult(), o sistema forneceria o resultado para setResult(). Caso contrário, o resultado seria ignorado.