lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Intents e filtros de intents

A Intent é um objeto de mensagem que pode ser usado para solicitar uma ação de outro componente de aplicativo. Embora os intents facilitem a comunicação entre componentes de diversos modos, há três casos de uso fundamentais:

  • Para iniciar uma atividade:

    Uma Activity representa uma única tela em um aplicativo. É possível iniciar uma nova instância de uma Activity passando uma Intent para startActivity(). A Intent descreve a atividade a iniciar e carrega todos os dados necessários.

    Se você deseja receber um resultado da atividade quando ela finalizar, chame startActivityForResult(). Sua atividade recebe o resultado como um objeto Intent separado no retorno de chamada de onActivityResult() da atividade. Para saber mais, consulte o guia Atividades.

  • Para iniciar um serviço:

    O Service é um componente que realiza operações em segundo plano sem interface do usuário. É possível iniciar um serviço para realizar uma operação que acontece uma vez (como baixar um arquivo) passando uma Intent a startService(). A Intent descreve o serviço a iniciar e carrega todos os dados necessários.

    Se o serviço for projetado com uma interface servidor-cliente, é possível vincular ao serviço em outro componente passando uma Intent a bindService(). Para obter mais informações, consulte o guia Serviços.

  • Para fornecer uma transmissão:

    Transmissão é uma mensagem que qualquer aplicativo pode receber. O sistema fornece diversas transmissões para eventos do sistema, como quando o sistema inicializa ou o dispositivo inicia o carregamento. Você pode fornecer uma transmissão a outros aplicativos passando um Intent a sendBroadcast(), sendOrderedBroadcast() ou sendStickyBroadcast().

Tipos de intents

Há dois tipos de intents:

  • Os intents explícitos especificam o componente a iniciar pelo nome (o nome de classe totalmente qualificado). Normalmente, usa-se um intent explícito para iniciar um componente no próprio aplicativo porque se sabe o nome de classe da atividade ou serviço que se deseja iniciar. Por exemplo, iniciar uma nova atividade em resposta a uma ação do usuário ou iniciar um serviço para baixar um arquivo em segundo plano.
  • Os intents implícitos não nomeiam nenhum componente específico, mas declaram uma ação geral a realizar, o que permite que um componente de outro aplicativo a processe. Por exemplo, se você deseja exibir ao usuário uma localização em um mapa, pode usar um intent implícito para solicitar que outro aplicativo capaz exiba uma localização especificada no mapa.

Ao criar um intent explícito para iniciar uma atividade ou serviço, o sistema inicia imediatamente o componente do aplicativo especificado no objeto Intent.

Figura 1. Ilustração de como um intent implícito é fornecida pelo sistema para iniciar outra atividade: [1] A atividade A cria uma Intent com uma descrição de ação e passa-a para startActivity(). [2] O sistema Android busca, em todos os aplicativos, um filtro de intents que corresponda ao intent. Ao encontrar uma correspondência, [3] o sistema inicia a atividade correspondente (atividade B) chamando seu método onCreate() e passando-lhe a Intent.

Ao criar um intent implícito, o sistema Android encontra o componente adequado para iniciar, comparando o conteúdo do intent aos filtros de intents declarados no arquivo de manifesto de outros aplicativos no dispositivo. Se o intent corresponder a um filtro de intents, o sistema iniciará esse componente e entregará o objeto Intent. Se diversos filtros de intents corresponderem, o sistema exibirá uma caixa de diálogo para que o usuário selecione o aplicativo que deseja usar.

O filtro de intents é uma expressão em um arquivo de manifesto do aplicativo que especifica o tipo de intents que o componente gostaria de receber. Por exemplo, ao declarar um filtro de intents para uma atividade, outros aplicativos se tornam capazes de iniciar diretamente sua atividade com o determinado tipo de intent. Do mesmo modo, se você não declarar nenhum filtro de intents para uma atividade, ela poderá ser iniciada somente com um intent explícito.

Atenção: Para garantir a segurança do seu aplicativo, sempre use um intent explícito ao iniciar um Service e não declare filtros de intents para os serviços. O uso de um intent implícito para iniciar um serviço representa um risco de segurança porque não é possível determinar qual serviço responderá ao intent e o usuário não poderá ver que serviço é iniciado. Iniciando no Android 5.0 (API de nível 21), o sistema lança uma exceção ao chamar bindService() com um intent implícito.

Criação de um intent

Um objeto Intent carrega informações que o sistema Android usa para determinar o componente a iniciar (como o nome exato do componente ou categoria do componente que deve receber o intent), além de informações que o componente receptor usa para realizar a ação adequadamente (como a ação a tomar e os dados a usar).

As informações principais contidas em uma Intent são as seguintes:

Nome do componente
O nome do componente a iniciar.

É opcional, mas é a informação fundamental que torna um intent explícito, o que significa que o intent deve ser entregue somente ao componente do aplicativo definido pelo nome do componente. Sem nome de componente, o intent será implícito e o sistema decidirá qual componente deve receber o intent com base nas informações de outro intent (como a ação, os dados e a categoria — descritos abaixo). Portanto, se for necessário iniciar um componente específico no seu aplicativo, você deverá especificar o nome do componente.

Observação: Ao iniciar um Service, deve-se sempre especificar o nome do componente. Caso contrário, não será possível determinar qual serviço responderá ao intent e o usuário não poderá ver que serviço é iniciado.

Esse campo da Intent é um objeto ComponentName que pode ser especificado usando um nome de classe totalmente qualificado do componente-alvo, inclusive o nome do pacote do aplicativo. Por exemplo: com.example.ExampleActivity. É possível definir o nome do componente com setComponent(), setClass(), setClassName() ou com o construtor de Intent.

Ação
String que especifica a ação genérica a realizar (como exibir ou selecionar).

No caso de um intent de transmissão, essa é a ação que entrou em vigor e que está sendo relatada. A ação determina amplamente como o resto do intent é estruturado — especificamente, o que está contido nos dados e em extras.

É possível especificar as ações para uso por intents dentro do aplicativo (ou para uso por outros aplicativos para chamar componentes no seu aplicativo), mas normalmente são usadas constantes de ação definidas pela classe Intent ou por outras classes de estrutura. Eis algumas ações comuns para iniciar uma atividade:

ACTION_VIEW
Use essa ação em um intent com startActivity() quando houver informações que uma atividade possa exibir ao usuário, como uma foto para exibição em um aplicativo de galeria ou um endereço para exibição em um aplicativo de mapa.
ACTION_SEND
Também conhecida como o intent de "compartilhamento", deve ser usada em um intent com startActivity() quando houver alguns dados que o usuário possa compartilhar por meio de outro aplicativo, como um aplicativo de e-mail ou de compartilhamento social.

Consulte a referência da classe Intent para obter mais constantes que definem ações genéricas. Outras ações são definidas em outros locais na estrutura do Android, como nas Settings para ações que abrem telas específicas no aplicativo de Configurações do sistema.

É possível especificar a ação para um intent com setAction() ou com um construtor de Intent.

Se você definir as próprias ações, certifique-se de incluir o nome do pacote do seu aplicativo como prefixo. Por exemplo:

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
Dados
A URI (um objeto Uri) que referencia os dados a serem aproveitados e/ou o tipo MIME desses dados. O tipo dos dados fornecidos geralmente é determinado pela ação do intent. Por exemplo, se a ação for ACTION_EDIT, os dados deverão conter a URI do documento a editar.

Ao criar um intent, em geral, é importante especificar o tipo de dados (seu tipo MIME) em adição à URI. Por exemplo: uma atividade capaz de exibir imagens provavelmente não será capaz de reproduzir um arquivo de áudio, mesmo que os formatos da URI sejam similares. Portanto, especificar o tipo MIME dos dados ajuda o sistema Android a encontrar o melhor componente para receber o intent. Contudo, o tipo MIME, às vezes, pode ser inferido a partir da URI — especificamente quando os dados são uma URI de content:, indicando que os dados se localizam no dispositivo e são controlados por um ContentProvider, que torna o tipo MIME dos dados visíveis para o sistema.

Para definir somente a URI de dados, chame setData(). Para definir somente o tipo MIME, chame setType(). Se necessário, é possível definir ambos explicitamente com setDataAndType().

Atenção: Se você deseja definir a URI e o tipo MIME, não chame setData() e setType(), pois um anula o do outro. Sempre use setDataAndType() para definir a URI e o tipo MIME juntos.

Categoria
String que contém informações adicionais sobre o tipo de componente que deve processar intent. Qualquer número de descrições de categoria pode ser inserido em um intent, mas a maioria dos intents não requer nenhuma categoria. Eis algumas categorias comuns:
CATEGORY_BROWSABLE
A atividade-alvo permite ser iniciada por um navegador da Web para exibir dados referenciados por um link — como uma imagem ou uma mensagem de e-mail.
CATEGORY_LAUNCHER
A atividade é a atividade inicial de uma tarefa e é listada no inicializador do aplicativo do sistema.

Consulte a descrição da classe Intent para obter a lista completa de categorias.

É possível especificar uma categoria com addCategory().

As propriedades listadas abaixo (nome do componente, ação, dados e categoria) representam as características de definição de um intent. Ao ler estas propriedades, o sistema Android será capaz de definir o componente de aplicativo que ele deve iniciar.

Contudo, um intent pode carregar informações adicionais que não afetam o modo com que é tratada para um componente do aplicativo. Os intents também podem fornecer:

Extras
Pares de valor-chave que carregam informações adicionais necessárias para realizar a ação solicitada. Assim, como algumas ações usam determinados tipos de URIs de dados, outras também usam determinados extras.

É possível adicionar dados extras com diversos métodos putExtra(), cada um aceitando dois parâmetros: o nome principal e o valor. Também é possível criar um objeto Bundle com todos os dados extras e, em seguida, inserir o Bundle na Intent com putExtras().

Por exemplo, ao criar um intent para enviar um e-mail com ACTION_SEND, é possível especificar o recipiente "para" com a chave EXTRA_EMAIL e especificar o "assunto" com a chave EXTRA_SUBJECT.

A classe Intent especifica diversas constantes EXTRA_* para tipos de dados padronizados. Se for necessário declarar chaves extras (para intents que seu aplicativo receba), certifique-se de incluir o nome do pacote do aplicativo como prefixo. Por exemplo:

static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
Sinalizadores
Sinalizadores definidos na classe Intent que funcionam como metadados para o intent. Os sinalizadores podem instruir o sistema Android a inicializar uma atividade (por exemplo, a qual tarefa a atividade deve pertencer) e como tratá-la após a inicialização (por exemplo, se ela pertence a uma lista de atividades recentes).

Para obter mais informações, consulte o método setFlags().

Exemplo de intent explícito

O intent explícito é usada para inicializar um componente específico de um aplicativo, como uma atividade ou serviço em particular, no seu aplicativo. Para criar um intent explícito, defina o nome do componente para o objeto Intent — todas as outras propriedades do intent são opcionais.

Por exemplo, se você criar um serviço no aplicativo, chamado DownloadService, projetado para baixar um arquivo da Web, poderá iniciá-lo com o código a seguir:

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

O construtor Intent(Context, Class) fornece Context ao aplicativo e um objeto Class ao componente. Assim, esse intent inicia explicitamente a classe DownloadService no aplicativo.

Para obter mais informações sobre a criação e inicialização de um serviço, consulte o guia Serviços.

Exemplo de intent implícito

O intent implícito especifica uma ação que possa chamar qualquer aplicativo no dispositivo capaz de realizar a ação. O intent implícito é útil quando o aplicativo não pode realizar a ação, mas outros aplicativos provavelmente podem e o usuário seleciona que aplicativo usar.

Por exemplo, se você tem o conteúdo que deseja que o usuário compartilhe com outras pessoas, crie um intent com a ação ACTION_SEND e adicione extras que especifiquem o conteúdo a compartilhar. Ao chamar startActivity() com esse intent, o usuário poderá selecionar um aplicativo pelo qual deseja compartilhar o conteúdo.

Atenção: É possível que um usuário não tenha nenhum aplicativo que processe o intent implícito enviado a startActivity(). Se isso acontecer, a chamada e seu aplicativo falharão. Para verificar se uma atividade receberá o intent, chame resolveActivity() no objeto Intent. Se o resultado não for nulo, há pelo menos um aplicativo que pode processar o intent e será seguro chamar startActivity(). Se o resultado for nulo, você não deve usar o intent e, se possível, deve desativar o recurso que emite o intent.

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

Observação: Nesse caso, não será usada nenhuma URI, mas o tipo de dados do intent será declarado para especificar o conteúdo carregado pelos extras.

Quando startActivity() é chamada, o sistema avalia todos os aplicativos instalados para determinar quais deles podem processar esse tipo de intent (um intent com a ação ACTION_SEND e que carrega dados de "texto/simples". Se houver somente um aplicativo que possa tratar, o aplicativo abre imediatamente e recebe o intent. Se diversas atividades aceitarem o intent, o sistema exibirá uma caixa de diálogo para que o usuário selecione que aplicativo usar.

Figura 2. Caixa de diálogo seletora.

Para forçar um seletor de aplicativo

Quando há mais de um aplicativo que responde ao intent implícito, o usuário pode selecionar o aplicativo que deseja usar e tornar esse aplicativo a escolha padrão para a ação. Isso é positivo ao executar uma ação para a qual o usuário deseja usar o mesmo aplicativo todas as vezes, como quando abre uma página da Web (os usuários geralmente usam apenas um navegador).

Contudo, se diversos aplicativos podem responder ao intent e o usuário deve ficar livre para usar um aplicativo diferente em cada vez, é preciso exibir uma caixa de diálogo seletora explicitamente. A caixa de diálogo seletora pede que o usuário selecione o aplicativo desejado para a ação todas as vezes (o usuário não pode selecionar um aplicativo padrão para a ação). Por exemplo: quando o aplicativo realiza "compartilhar" com a ação ACTION_SEND, os usuários podem querer compartilhar usando um aplicativo diferente conforme a situação, portanto, deve-se sempre usar a caixa de diálogo seletora, como ilustrado na figura 2.

Para mostrar o seletor, crie uma Intent usando createChooser() e passe-a para startActivity(). Por exemplo:

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

Isso exibe um diálogo com uma lista de aplicativos que respondem ao intent passada ao método createChooser() e usa o texto fornecido como título da caixa de diálogo.

Recebimento de um intent implícito

Para anunciar quais intents implícitos o aplicativo pode receber, declare um ou mais filtros de intents para cada um dos componentes do aplicativo com um elemento <intent-filter> no arquivo de manifesto. Cada filtro de intents especifica o tipo de intents aceito com base na ação nos dados e na categoria do intent. O sistema fornecerá um intent implícito ao componente do seu aplicativo somente se ela puder passar por um dos filtros de intents.

Observação: O intent explícito é sempre entregue ao alvo independentemente dos filtros de intents que o componente declare.

Os componentes de um aplicativo devem declarar filtros separados para cada trabalho exclusivo que podem fazer. Por exemplo, uma atividade em um aplicativo de galeria de imagens pode ter dois filtros: um filtro para visualizar uma imagem e outro para editar uma imagem. Quando a atividade inicia, ela inspeciona a Intent e decide como se comportar com base nas informações na Intent (como para exibir ou não os controles do editor).

Cada filtro de intents é definido por um elemento <intent-filter> no arquivo de manifesto do aplicativo, aninhado no componente correspondente do aplicativo (como um elemento <activity>). Dentro de <intent-filter>, é possível especificar o tipo de intents aceitos usando um ou mais dos três elementos a seguir:

<action>
Declara a ação do intent aceito, no atributo name. O valor deve ser o valor literal da string de uma ação, e não a constante da classe.
<data>
Declara o tipo de dados aceitos usando um ou mais atributos que especificam diversos aspectos da URI de dados (scheme, host, port, path etc.) e do tipo MIME.
<category>
Declara a categoria do intent aceito, no atributo name. O valor deve ser o valor literal da string de uma ação, e não a constante da classe.

Observação: Para receber intents implícitos, é preciso incluir 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 filtro de intents, nenhum intent implícito retomará sua atividade.

Por exemplo, abaixo há uma declaração de atividade com um filtro de intents para receber um intent ACTION_SEND quando o tipo de dados for texto:

<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"/>
    </intent-filter>
</activity>

Não há problemas em criar um filtro que inclua mais de uma instância de <action>, <data> ou <category>. Se você o fizer, basta se certificar de que o componente possa processar todas e quaisquer combinações daqueles elementos do filtro.

Para processar diversos tipos de intents, mas somente em combinações específicas de ações, dados e tipos de categoria, será necessário criar diversos filtros de intents.

Os intents implícitos são testados em relação a um filtro por meio da comparação do intent com cada um dos três elementos. Para ser entregue ao componente, o intent deve passar por todos os três testes. Se ela falhar em algum deles, o sistema Android não entregará o intent ao componente. No entanto, como um componente pode ter diversos filtros de intents, um intent que não passe por um dos filtros de um componente pode passar por outro filtro. Veja mais informações sobre como o sistema resolve intents na seção abaixo sobre Resolução de intents.

Atenção: Para evitar a execução involuntária de um Service diferente do aplicativo, sempre use um intent explícito para iniciar o próprio serviço e não declare filtros de intents para ele.

Observação: para todas as atividades, é necessário declarar os filtros de intents no arquivo de manifesto. Contudo, os filtros para receptores de transmissão podem ser registrados dinamicamente chamando registerReceiver(). Assim, será possível cancelar o registro do receptor com unregisterReceiver(). Isso permitirá que o aplicativo receba transmissões específicas durante um período de tempo especificado apenas quando o aplicativo estiver em execução.

Exemplos de filtros

Para compreender melhor alguns dos comportamentos do filtro de intents, veja o snippet a seguir do arquivo de manifesto de um aplicativo de compartilhamento social.

<activity android:name="MainActivity">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

A primeira atividade, MainActivity, é o ponto de entrada principal do aplicativo — a atividade que abre quando o usuário inicializa o aplicativo pela primeira vez com o ícone de inicialização:

  • A ação ACTION_MAIN indica que esse é o ponto de entrada principal e não espera nenhum dado de intent.
  • A categoria CATEGORY_LAUNCHER indica que esse ícone da atividade deve ser colocado no inicializador de aplicativo do sistema. Se o elemento <activity> não especificar nenhum ícone com icon, o sistema usará o ícone do elemento <application> .

Esses dois devem ser pareados para que a atividade apareça no inicializador do aplicativo.

A segunda atividade, ShareActivity, destina-se a facilitar o compartilhamento de conteúdo de texto e mídia. Apesar de os usuários poderem acessar essa atividade pela MainActivity, eles também podem acessar ShareActivity diretamente de outro aplicativo que emita um intent implícito que corresponda a um dos dois filtros de intents.

Observação: O tipo MIME, application/vnd.google.panorama360+jpg, é um tipo de dados especial que especifica fotos panorâmicas que podem ser processadas com as APIs do Google Panorama.

Uso de um intent pendente

Um objeto PendingIntent é um agrupador em torno de um objeto Intent. A principal finalidade de uma PendingIntent é conceder permissão a um aplicativo externo para usar a Intent contida como se ela fosse executada a partir do processo do próprio aplicativo.

Os principais casos de uso de um intent pendente são:

  • Declarar um intent a ser executada quando o usuário realiza uma ação com a Notificação (o NotificationManager do sistema Android executa a Intent).
  • Declarar um intent a ser executada quando o usuário realiza uma ação com o Widget do aplicativo (o aplicativo de tela inicial executa a Intent).
  • Declarar um intent a ser executada em um momento específico no futuro (o AlarmManager do sistema Android executa a Intent).

Como cada objeto Intent é projetado para ser processado por um tipo específico de componentes do aplicativo (uma Activity, um Service ou um BroadcastReceiver), uma PendingIntent deve ser criada com a mesma consideração. Ao usar um intent pendente, o aplicativo não executará o intent com uma chamada como de startActivity(). Em vez disso, deve-se declarar o tipo do componente pretendido ao criar a PendingIntent chamando o respectivo método criador:

A menos que o aplicativo esteja recebendo intents pendentes de outros aplicativos, os métodos acima para criar uma PendingIntent são provavelmente os únicos métodos de PendingIntent necessários.

Cada método toma o Context do aplicativo atual, a Intent que você deseja agrupar e um ou mais sinalizadores que especificam como o intent deve ser usado (como se o intent pode ser usada mais de uma vez).

Veja mais informações sobre o uso de intents pendentes na documentação dos respectivos casos de uso, como nos guias das APIs de Notificações e Widget do aplicativo.

Resolução de intents

Quando o sistema recebe um intent implícito para iniciar uma atividade, ele busca as melhores atividades para o intent comparando-o com os filtros de intents com base em três aspectos:

  • A ação do intent
  • Os dados do intent (URI e tipo de dados)
  • A categoria do intent

As seções a seguir descrevem como intents são combinados com os componentes apropriados em termos de como o filtro de intents é declarado no arquivo de manifesto de um aplicativo.

Teste de ação

Para especificar ações de intents aceitos, um filtro de intents pode declarar zero ou mais elementos <action>. Por exemplo:

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

Para passar por esse filtro, a ação especificada na Intent deve corresponder a uma das ações listadas no filtro.

Se o filtro não lista nenhuma ação, não há nada a que um intent corresponda, portanto, todos os intents falharão no teste. Contudo, se uma Intent não especificar nenhuma ação, ela passará no teste (desde que o filtro contenha pelo menos uma ação).

Teste de categoria

Para especificar as categorias de intent aceitos, um filtro de intents pode declarar zero ou mais elementos <category>. Por exemplo:

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

Para que um intent passe no teste de categoria, cada categoria na Intent deve corresponder a uma categoria no filtro. O inverso não é necessário — o filtro de intents pode declarar mais categorias das especificadas na Intent e a Intent ainda passará no teste. Portanto, um intent sem categorias sempre passará nesse teste independentemente das categorias declaradas no filtro.

Observação: o Android aplica automaticamente a categoria CATEGORY_DEFAULT para todos os intents implícitos passadas a startActivity() e startActivityForResult(). Por isso, para que a atividade receba intents implícitos, ela deve conter uma categoria de "android.intent.category.DEFAULT" nos filtros de intents (como é exibido no exemplo de <intent-filter> anterior).

Teste de dados

Para especificar dados de intents aceitos, um filtro de intents pode declarar zero ou mais elementos <data>. Por exemplo:

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

Cada elemento <data> pode especificar uma estrutura de URI e um tipo de dados (tipo de mídia MIME). Há atributos separados — scheme, host, port e path— para cada parte da URI:

<scheme>://<host>:<port>/<path>

Por exemplo:

content://com.example.project:200/folder/subfolder/etc

Nessa URI, o esquema é content, o host é com.example.project, a porta é 200 e o caminho é folder/subfolder/etc.

Cada um desses atributos é opcional em um elemento <data>, mas há dependências lineares:

  • Se não houver esquema especificado, o host será ignorado.
  • Se não houver host especificado, a porta será ignorada.
  • Se não houver esquema nem host especificado, o caminho será ignorado.

Quando a URI em um intent é comparada a uma especificação de URI em um filtro, a comparação é feita somente com as partes da URI incluídas no filtro. Por exemplo:

  • Se um filtro especificar somente um esquema, todas as URIs com esse esquema atenderão ao filtro.
  • Se um filtro especificar um esquema e uma autoridade, mas não um caminho, todas as URIs com o mesmo esquema e autoridade passarão pelo filtro independentemente dos caminhos.
  • Se um filtro especificar um esquema, uma autoridade e um caminho, somente URIs com o mesmo esquema, autoridade e caminho passarão pelo filtro.

Observação: A especificação de caminho pode conter um asterisco especial (*) para exigir somente uma correspondência parcial do nome do caminho.

O teste de dados compara a URI e o tipo MIME do intent com uma URI e um tipo MIME especificados no filtro. As regras são as seguintes:

  1. O intent que não contiver URI nem tipo MIME passará no teste somente se o filtro não especificar nenhuma URI nem tipo MIME.
  2. O intent que contiver URI, mas nenhum tipo MIME (nem explícito, nem inferível a partir da URI), passará no teste somente se a URI corresponder ao formato de URI do filtro e se o filtro, igualmente, não especificar um tipo MIME.
  3. O intent que contiver tipo MIME, mas nenhuma URI, passará no teste somente se o filtro listar o mesmo tipo MIME e não especificar nenhum formato de URI.
  4. O intent que contiver URI e tipo MIME (explícito ou inferível a partir da URI) passará na parte do tipo MIME do teste somente se esse tipo corresponder a um tipo listado no filtro. Ele passará na parte da URI do teste se corresponder a uma URI no filtro ou se tiver uma URI de content: ou file: e se o filtro não especificar nenhuma URI. Em outras palavras, presume-se que um componente seja compatível com dados de content: e de file: se o filtro listar somente um tipo MIME.

Essa última regra (d) reflete a expectativa de que os componentes sejam capazes de obter dados de local de um arquivo ou provedor de conteúdo. Portanto, os filtros podem listar somente um tipo de dados e não precisam nomear explicitamente os esquemas content: e file:. Esse é um caso típico. Um elemento <data> como o seguinte, por exemplo, informa ao Android que o componente pode obter dados de imagem de um provedor de conteúdo e exibi-los:

<intent-filter>
    <data android:mimeType="image/*" />
    ...
</intent-filter>

Como a maioria dos dados disponíveis é dispensada pelos provedores de conteúdo, os filtros que especificam um tipo de dados, mas não uma URI, são, talvez, os mais comuns.

Outra configuração comum é de filtros com um esquema e um tipo de dados. Por exemplo, um elemento <data>, como o seguinte, informa ao Android que o componente pode recuperar dados de vídeo da rede para realizar a ação:

<intent-filter>
    <data android:scheme="http" android:type="video/*" />
    ...
</intent-filter>

Correspondência de intents

Intents são correspondidas a filtros de intents não somente para descobrir um componente-alvo a ativar, mas também para descobrir algo sobre o conjunto de componentes do dispositivo. Por exemplo, o aplicativo Home preenche o inicializador do aplicativo encontrando todas as atividades com filtros de intents que especifiquem a ação ACTION_MAIN e a categoria CATEGORY_LAUNCHER.

O aplicativo pode usar a correspondência de intents de modo similar. O PackageManager tem um conjunto de métodosquery...() , que retornam todos os componentes que podem aceitar um determinado intent e uma série de métodos resolve...() similares, que determinam o melhor componente para responder a um intent. Por exemplo: queryIntentActivities() retorna uma lista de todas as atividades que podem realizar o intent passado como um argumento e {@linkandroid.content.pm.PackageManager#queryIntentServices queryIntentServices()} retorna uma lista de serviços semelhantes. Nenhum dos métodos ativa os componentes — eles só listam aqueles que podem responder. Há um método semelhante para receptores de transmissão — o queryBroadcastReceivers().