Uma Intent
é um objeto de mensagem que pode ser usado para solicitar uma ação
de outro componente do app.
Embora as intents facilitem a comunicação entre componentes de várias maneiras, há três
casos de uso fundamentais:
- Como iniciar uma atividade
Um
Activity
representa uma única tela em um app. Você pode iniciar um novo instância de umActivity
transmitindo um objetoIntent
parastartActivity()
. OIntent
descreve a atividade a ser iniciada e carrega todos os dados necessários.Se você quiser receber um resultado da atividade quando ela terminar, chame
startActivityForResult()
. Sua atividade recebe o resultado como um objetoIntent
separado no callbackonActivityResult()
da atividade. Para mais informações, consulte o guia Atividades. - Como iniciar um serviço
Um
Service
é um componente que executa operações em segundo plano. sem uma interface do usuário. Com o Android 5.0 (API de nível 21) e versões mais recentes, você pode iniciar um serviço comJobScheduler
. Para mais informações sobreJobScheduler
, consulteAPI-reference documentation
.Para versões anteriores ao Android 5.0 (nível 21 da API), é possível iniciar um serviço usando métodos da classe
Service
. É possível iniciar um serviço para executar uma operação única (como fazer o download de um arquivo) transmitindo umIntent
. parastartService()
. OIntent
descreve o serviço a ser iniciado e carrega todos os dados necessários.Se o serviço foi projetado com uma interface cliente-servidor, é possível fazer a vinculação ao serviço de outro componente transmitindo um
Intent
parabindService()
. Para mais informações, consulte o guia Serviços. - Como fazer uma transmissão
Transmissão é uma mensagem que qualquer aplicativo pode receber. O sistema oferece várias Transmissões para eventos do sistema, como quando o sistema é inicializado ou o dispositivo começa a carregar. É possível transmitir uma transmissão a outros apps transmitindo um
Intent
. parasendBroadcast()
ousendOrderedBroadcast()
O restante desta página explica como os intents funcionam e como usá-los. Para informações relacionadas, consulte Como interagir com outros apps e Compartilhamento de conteúdo.
Tipos de intents
Há dois tipos de intents:
- As intents explícitas especificam qual componente vai atender à intent, especificando um
ComponentName
completo. Você vai normalmente usam uma intent explícita para iniciar um componente em seu próprio app, porque você sabe o nome da classe da atividade ou serviço que quer iniciar. Para exemplo, você pode iniciar uma nova atividade no aplicativo em resposta a uma ação do usuário ou um serviço para fazer o download de um arquivo em segundo plano. - As intents implícitas não nomeiam nenhum componente específico, mas declaram uma ação geral. que permite que um componente de outro app a execute. Por exemplo, se você quiser para mostrar ao usuário uma localização em um mapa, você pode usar uma intent implícita para solicitar que outro usuário mostram um local específico em um mapa.
A figura 1 mostra como um intent é usado ao iniciar uma atividade. Quando o
O objeto Intent
nomeia um componente de atividade específico de forma explícita, o sistema
inicia esse componente imediatamente.
![](https://developer.android.com/static/images/components/intent-filters_2x.png?authuser=9&hl=pt)
Figura 1. Como uma intent implícita é
entregue pelo sistema para iniciar outra atividade: [1] a atividade A cria uma
Intent
com uma descrição da ação e a transmite para startActivity()
. [2] O sistema Android pesquisa todos
para um filtro de intent que corresponda à intent. Quando uma correspondência for encontrada, [3] o sistema
inicia a atividade correspondente (atividade B) invocando o método onCreate()
e transmitindo a Intent
.
Quando você usa uma intent implícita, o sistema Android encontra o componente adequado para iniciar
comparando o conteúdo da intent com os filtros de intent declarados no arquivo de manifesto de outros apps no
dispositivo. Se a intent corresponder a um filtro de intents, o sistema iniciará esse componente e o entregará
o objeto Intent
. Se vários filtros de intents forem compatíveis, o sistema
exibe uma caixa de diálogo para que o usuário possa escolher qual aplicativo usar.
Um filtro de intents é uma expressão no arquivo de manifesto de um app que especifica o tipo de intents que o componente gostaria de receber. Por exemplo, ao declarar um filtro de intents para uma atividade, você possibilita que outros apps iniciem diretamente sua atividade com um determinado tipo de intent. Da mesma forma, se você não declarar nenhum filtro de intent para uma atividade, ela poderá ser iniciada apenas com uma intent explícita.
Cuidado:para garantir a segurança do seu app, sempre
usar uma linguagem
ao iniciar uma Service
e não
declarar filtros de intent para seus serviços. O uso de uma intent implícita para iniciar um serviço representa um
risco de segurança, porque não é possível determinar qual serviço responderá à intent,
e o usuário não poderá ver qual serviço será iniciado. A partir do Android 5.0 (API de nível 21), o sistema
gera uma exceção se você chamar bindService()
.
com uma intent implícita.
Criação de um intent
Um objeto Intent
carrega informações que o sistema Android usa
para determinar qual componente iniciar (como o nome exato do componente ou
categoria que deve receber a intenção), além das informações que o componente destinatário usa em
para realizar adequadamente a ação (como a ação a ser tomada e os dados a serem seguidos).
As principais informações contidas em um Intent
são as seguintes:
- Nome do componente
- O nome do componente a ser iniciado.
Isso é opcional, mas é a informação fundamental que faz uma intenção explicit, o que significa que a intent precisa ser entregue somente ao componente do app; definido pelo nome do componente. Sem um nome de componente, o intent será implícito e o o sistema decide qual componente deve receber a intent com base nas outras informações da intent (como a ação, os dados e a categoria descritos abaixo). Se você precisar iniciar um componente em seu aplicativo, você deve especificar o nome do componente.
Observação:ao iniciar uma
Service
, sempre especifique o nome do componente. Caso contrário, não é possível determinar qual serviço responderá à intent, e o usuário não poderá ver qual serviço é iniciado.Este campo do
Intent
é um objetoComponentName
, que pode ser especificado usando um argumento nome de classe qualificado do componente de destino, incluindo o nome do pacote do aplicativo, por exemplo,com.example.ExampleActivity
É possível definir o nome do componente comsetComponent()
,setClass()
,setClassName()
ou com o construtorIntent
. - Ação
- Uma string que especifica a ação genérica a ser realizada (como view ou pick).
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 em grande parte como o restante da intent é estruturado, especialmente as informações contidas nos dados e extras.
É possível especificar suas próprias ações para uso por intents dentro do seu aplicativo (ou para uso por outros invoquem componentes no app), mas você geralmente especifica constantes de ação definido pela classe
Intent
ou outras classes de framework. Confira alguns ações comuns para iniciar uma atividade:ACTION_VIEW
- Use esta ação em uma intent com
startActivity()
quando você tiver algumas informações que uma atividade pode ser mostrada ao usuário, como uma foto para visualizar em um app de galeria ou um endereço para em um app de mapa. ACTION_SEND
- Também conhecida como intent de compartilhamento, use-a em uma intent com
startActivity()
quando houver alguns dados que o usuário possa compartilhar usando outro app, como um app de e-mail ou de compartilhamento em redes sociais.
Consulte a referência da classe
Intent
para mais constantes que definem ações genéricas. Outras ações foram definidas em outros lugares no framework do Android, como emSettings
para ações. que abrem telas específicas no app Configurações do sistema.Você pode especificar a ação para uma intent com
setAction()
ou com um construtorIntent
.Se você definir suas próprias ações, inclua o nome do pacote do app como um prefixo, conforme mostrado neste exemplo:
Kotlin
const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"
Java
static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
- Dados
- O URI (um objeto
Uri
) que referencia os dados ao ser executadas e/ou tipo MIME desses dados. O tipo de dados fornecido geralmente é determinado pela ação da intent. Para Por exemplo, se a ação forACTION_EDIT
, os dados deverão conter o URI do documento a ser editado.Ao criar uma intent, muitas vezes é importante especificar o tipo de dados (seu tipo MIME) em conjunto com o URI. Por exemplo, uma atividade capaz de exibir imagens provavelmente não será capaz reproduzir um arquivo de áudio, mesmo que os formatos de URI possam ser semelhantes. Especificar o tipo MIME dos dados ajuda o sistema encontrar o melhor componente para receber a intent. No entanto, o tipo MIME às vezes pode ser inferido a partir do URI, especialmente quando os dados são um URI
content:
. Um URIcontent:
indica que os dados estão localizados no dispositivo. e controladas por umaContentProvider
, que torna o tipo MIME de dados visível para o sistema.Para definir apenas o URI de dados, chame
setData()
. Para definir apenas o tipo MIME, chamesetType()
. Se necessário, pode definir ambos explicitamente comsetDataAndType()
.Cuidado:se você quiser definir o URI e o tipo MIME, não chame
setData()
esetType()
porque cada um anula o valor do outro. Sempre usesetDataAndType()
para definir URI e tipo MIME. - Categorias
- Uma string contendo informações adicionais sobre o tipo de componente
que vai processar a intent. Qualquer número de descrições de categoria pode ser
colocado em uma intent, mas a maioria das intents não requer uma categoria.
Aqui estão algumas categorias comuns:
CATEGORY_BROWSABLE
- A atividade de destino pode ser iniciada por um navegador da Web para mostrar dados referenciada por um link, como uma imagem ou uma mensagem de e-mail.
CATEGORY_LAUNCHER
- A atividade é a atividade inicial de uma tarefa e está listada em ao inicializador de aplicativos do sistema.
Consulte a descrição da classe
Intent
para ver a lista completa categorias.É possível especificar uma categoria com
addCategory()
.
As propriedades listadas acima (nome do componente, ação, dados e categoria) representam que definem as características de uma intent. Ao ler essas propriedades, o sistema Android é capaz de resolver qual componente do aplicativo deve iniciar. No entanto, uma intent pode ter informações adicionais que não afetem como isso é resolvido em um componente do app. Os intents também podem fornecer o seguinte:
- Extras
- Pares de chave-valor 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 mais dados com vários métodos
putExtra()
, cada um aceita dois parâmetros: o nome da chave e o valor. Você também pode criar um objetoBundle
com todos os dados extras e, em seguida, inserir oBundle
naIntent
computExtras()
.Por exemplo, ao criar uma intent para enviar um e-mail com
ACTION_SEND
, é possível especificar o destinatário to com oEXTRA_EMAIL
e especifique o subject com oEXTRA_SUBJECT
.A classe
Intent
especifica muitas constantesEXTRA_*
. para tipos de dados padronizados. Se você precisa declarar chaves extras (para intents que seu app recebe), inclua o nome do pacote do app como um prefixo, conforme mostrado neste exemplo:Kotlin
const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"
Java
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
Cuidado: não use
Parcelable
ouSerializable
de dados ao enviar uma intent esperada outro app para receber. Se um app tenta acessar dados em um objetoBundle
, mas não têm acesso à classe parcelada ou serializada, o sistema geraRuntimeException
. - Sinalizações
- Sinalizações são definidas na classe
Intent
que funcionam como metadados para o intenção. As sinalizações podem instruir o sistema Android a iniciar uma atividade (por exemplo, qual tarefa a atividade deve pertencer e como tratá-lo após o lançamento (por exemplo, se ele pertence à lista de serviços atividades).Para mais informações, consulte o método
setFlags()
.
Exemplo de intent explícito
Uma intent explícita é usada para iniciar um componente específico do app, como
uma atividade ou serviço específico no seu app. Para criar uma intent explícita, defina
o nome do componente para o objeto Intent
: todos
outras propriedades da intent são opcionais.
Por exemplo, se você criar um serviço chamado DownloadService
no app,
projetado para fazer download de um arquivo da web, você pode iniciá-lo com o seguinte código:
Kotlin
// Executed in an Activity, so 'this' is theContext
// The fileUrl is a string URL, such as "http://www.example.com/image.png" val downloadIntent = Intent(this, DownloadService::class.java).apply { data =Uri.parse
(fileUrl) } startService(downloadIntent)
Java
// Executed in an Activity, so 'this' is theContext
// 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 Intent(Context, Class)
o construtor fornece o Context
do app e o
um objeto Class
. Assim,
essa intent inicia explicitamente a classe DownloadService
no app.
Para obter mais informações sobre como criar e iniciar um serviço, consulte a Serviços.
Exemplo de intent implícito
Uma intent implícita especifica uma ação que pode invocar qualquer app no dispositivo que para realizar a ação. O uso de uma intent implícita é útil quando o app não pode realizar a ação, mas outros aplicativos provavelmente podem, e você gostaria que o usuário escolhesse qual aplicativo usar.
Por exemplo, se você tem conteúdo que deseja que o usuário compartilhe com outras pessoas,
criar uma intent
com a ação ACTION_SEND
e adiciona extras que especificam o conteúdo a ser compartilhado. Quando você ligar
startActivity()
com essa intent, o usuário pode
escolha um aplicativo pelo qual deseja compartilhar o conteúdo.
Kotlin
// Create the text message with a string. val sendIntent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, textMessage) type = "text/plain" } // Try to invoke the intent. try { startActivity(sendIntent) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
// 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"); // Try to invoke the intent. try { startActivity(sendIntent); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
Quando startActivity()
é chamado, o sistema
examina todos os aplicativos instalados para determinar quais podem processar esse tipo de intent (uma
com a ação ACTION_SEND
e que carrega "text/plain"
dados). Se houver apenas um app que possa lidar com isso, ele será aberto imediatamente e receberá o
intenção. Se nenhum outro app puder lidar com isso, seu app poderá capturar a
ActivityNotFoundException
que isso ocorre. Se várias atividades aceitarem a intent, o sistema
exibe uma caixa de diálogo como a mostrada na Figura 2, para que o usuário possa escolher qual app usar.
O guia também oferece mais informações sobre como iniciar outros apps sobre enviar o usuário para outro app.
![](https://developer.android.com/static/images/training/basics/intent-chooser.png?authuser=9&hl=pt)
Figura 2. Caixa de diálogo seletora.
Como forçar um seletor de aplicativo
Quando há mais de um app que responde à intent implícita, o usuário pode selecionar qual aplicativo usar e tornar esse aplicativo a escolha padrão para o à ação. A capacidade de selecionar um padrão é útil ao realizar uma ação para a qual o usuário provavelmente quer usar o mesmo aplicativo todas as vezes, como ao abrir uma página da Web (usuários geralmente preferem apenas um navegador da Web).
No entanto, se vários aplicativos puderem responder à intent e o usuário talvez queira usar
app todas as vezes, é necessário mostrar explicitamente uma caixa de diálogo seletora. A caixa de diálogo seletora
o usuário selecione qual aplicativo usar para a ação (o usuário não pode selecionar um aplicativo padrão para
a ação). Por exemplo, quando o app executa a ação "compartilhar" com a ação ACTION_SEND
, os usuários podem querer compartilhar usando um app diferente, dependendo
na situação atual, então use sempre a caixa de diálogo seletora, como mostrado na Figura 2.
Para mostrar o seletor, crie uma Intent
usando createChooser()
e transmita-a para startActivity()
, conforme mostrado no exemplo abaixo.
Esse exemplo mostra uma caixa de diálogo com uma lista de apps que respondem à intent transmitida ao método createChooser()
e usa o texto fornecido como o
título da caixa de diálogo.
Kotlin
val sendIntent = Intent(Intent.ACTION_SEND) ... // Always use string resources for UI text. // This says something like "Share this photo with" val title: String = resources.getString(R.string.chooser_title) // Create intent to show the chooser dialog val chooser: Intent = Intent.createChooser(sendIntent, title) // Verify the original intent will resolve to at least one activity if (sendIntent.resolveActivity(packageManager) != null) { startActivity(chooser) }
Java
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); }
Detectar inicializações de intents não seguras
O app pode iniciar intents para navegar entre componentes dentro dele, ou para realizar uma ação em nome de outro app. Para melhorar a segurança da plataforma, O Android 12 (nível 31 da API) e versões mais recentes oferecem um recurso de depuração que avisa se o app executar uma inicialização não segura de uma intent. Por exemplo, seu app pode executar uma inicialização não segura de uma intent aninhada, que é uma intent transmitida como um extra em outra intent.
Se o app realizar as duas ações a seguir, o sistema detectará uma ameaça lançamento de intent e uma violação de StrictMode ocorre:
- O app separa as intents aninhadas das outras intents enviadas.
- O app imediatamente inicia um componente
do app usando essa intent aninhada,
como ao transmitir a intent para
startActivity()
,startService()
oubindService()
.
Para mais detalhes sobre como identificar essa situação e fazer alterações no seu app, leia a postagem do blog sobre o Android Nesting Intents no Medium.
Verificar se há inicializações de intents não seguras
Para verificar se há inicializações de intents não seguras no app, chame
detectUnsafeIntentLaunch()
ao configurar o VmPolicy
, conforme mostrado no snippet de código a seguir. Caso
o app detecte uma violação de StrictMode, é recomendado interromper a execução
para proteger informações possivelmente confidenciais.
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() // Other StrictMode checks that you've previously added. // ... .detectUnsafeIntentLaunch() .penaltyLog() // Consider also adding penaltyDeath() .build()) }
Java
protected void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() // Other StrictMode checks that you've previously added. // ... .detectUnsafeIntentLaunch() .penaltyLog() // Consider also adding penaltyDeath() .build()); }
Usar intents de forma mais responsável
Para minimizar a chance de inicialização de uma intent não segura e de uma violação do StrictMode, seguir estas práticas recomendadas.
Copie apenas os extras essenciais nas intents e execute todas as limpezas
e validações necessárias. O app pode copiar os extras de uma intent para
outra usada para iniciar um novo componente. Isso ocorre quando o
app chama
putExtras(Intent)
ou
putExtras(Bundle)
.
Se o app executar uma dessas operações, copie apenas os extras esperados
pelo componente de recebimento. Se a outra intent (que recebe a cópia)
iniciar um componente que não foi
exportado, limpe e
valide os extras antes de copiá-los para a intent que inicia
o componente.
Não exporte os componentes do app desnecessariamente. Por exemplo, se você
pretende iniciar um componente de aplicativo usando uma intent aninhada interna, defina que
atributo android:exported
do componente para false
.
Use uma PendingIntent
em vez de uma
intent aninhada. Dessa forma, quando outro app descompactar o PendingIntent
do
contendo Intent
, o outro app poderá iniciar a PendingIntent
usando a
a identidade do seu app. Esta configuração permite que o outro app seja iniciado com segurança
qualquer componente no seu app, incluindo um componente não exportado.
O diagrama na figura 2 mostra como o sistema passa o controle do cliente para outro app (serviço) e de volta para seu app:
- O app cria uma intent que invoca uma atividade em outro app. Dentro de
essa intent, adicione um objeto
PendingIntent
como um extra. Essa intent pendente invoca um componente no seu app; esse componente não será exportado. - Ao receber a intent do seu app, o outro app extrai a
PendingIntent
. - O outro app invoca o método
send()
no objetoPendingIntent
. - Depois de retornar o controle ao aplicativo, o sistema invoca o servidor usando o contexto do seu app.
Figura 2. Diagrama de comunicação entre apps ao usar uma pendência aninhada intenção.
Como receber um intent implícito
Para anunciar quais intents implícitas seu app pode receber, declare um ou mais filtros de intent
cada um dos componentes do app por um <intent-filter>
no seu arquivo de manifesto.
Cada filtro de intents especifica o tipo de intents aceitos com base na ação,
dados e categoria. O sistema entrega uma intent implícita ao componente do app somente se o
pode passar por um de seus filtros de intents.
Observação:uma intent explícita é sempre entregue ao próprio destino, independentemente dos filtros de intent declarados pelo componente.
Um componente de aplicativo deve declarar filtros separados para cada job exclusivo que pode fazer.
Por exemplo, uma atividade em um app de galeria de imagens pode ter dois filtros: um filtro.
para visualizar uma imagem e outro filtro para editar uma imagem. Quando a atividade começar,
ele inspeciona o Intent
e decide como se comportar com base nas informações.
no Intent
(por exemplo, para mostrar ou não os controles do editor).
Cada filtro de intent é definido por um <intent-filter>
.
no arquivo de manifesto do aplicativo, aninhado no componente de aplicativo correspondente (como
como um <activity>
).
Em cada componente do app que inclui um elemento <intent-filter>
,
defina explicitamente um valor para
android:exported
.
Esse atributo indica se o componente do app pode ser acessado por outros apps. Em alguns
situações, como atividades cujos filtros de intent incluem o
LAUNCHER
é útil definir esse atributo como true
. Caso contrário,
é mais seguro definir esse atributo como false
.
Aviso:se uma atividade, um serviço ou uma transmissão
receptor no seu app usa filtros de intent e não define explicitamente o valor
para android:exported
, o app não poderá ser instalado em um dispositivo que
execute o Android 12 ou versões mais recentes.
No <intent-filter>
,
é possível especificar os tipos de intents aceitos usando um ou mais
desses três elementos:
<action>
- Declara a ação da intent aceita no atributo
name
. O valor precisa ser o valor literal da string de uma ação, não a constante da classe. <data>
- Declara o tipo de dados aceito, usando um ou mais atributos que especificam diversos
do URI de dados (
scheme
,host
,port
,path
) e o tipo MIME. <category>
- Declara a categoria da intent aceita no atributo
name
. O valor precisa ser o valor literal da string de uma ação, não a constante da classe.Observação: para receber intents implícitas, faça o seguinte: deve incluir o
CATEGORY_DEFAULT
no filtro de intents. MétodosstartActivity()
estartActivityForResult()
tratam todas as intents como se ele declarasse a categoriaCATEGORY_DEFAULT
. Se você não declarar essa categoria em seu filtro de intents, nenhuma intent implícita será resolvida para sua atividade.
Por exemplo, aqui está uma declaração de atividade com um filtro de intent para receber uma
ACTION_SEND
quando o tipo de dado for texto:
<activity android:name="ShareActivity" android:exported="false"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
É possível criar um filtro que inclua mais de uma instância de
<action>
,
<data>
ou
<category>
.
Se fizer isso, você precisa ter certeza de que o componente pode lidar com todo e qualquer
e combinações desses elementos de filtro.
Quando você quer processar vários tipos de intents, mas somente em combinações específicas de ação, dados e tipo de categoria, será preciso criar vários filtros de intents.
Uma intent implícita é testada em relação a um filtro por meio da comparação da intent com cada um dos três elementos. Para ser entregue ao componente, o intent deve passar por todos os três testes. Se não houver correspondência com nenhum deles, o sistema Android não entregará a intent ao componente. No entanto, como um componente pode ter vários filtros de intents, uma intent que não não passar por um dos filtros de um componente pode passar por outro filtro. Mais informações sobre como o sistema resolve intents são fornecidas na seção abaixo sobre Resolução de intents.
Cuidado : o uso de um filtro de intent não é uma maneira segura de impedir que outros apps sejam iniciados.
seus componentes. Embora os filtros de intent restrinjam um componente a responder
certos tipos de intents implícitas, outro aplicativo pode iniciar o componente do seu aplicativo
usando uma intent explícita se o desenvolvedor determinar os nomes dos componentes.
Se for importante que somente seu próprio app inicie um dos componentes, faça o seguinte:
não declare filtros de intent no seu manifesto. Em vez disso, defina
Atributo exported
como "false"
para esse componente.
Da mesma forma, para evitar a execução acidental da função
Service
, sempre use uma intent explícita para iniciar seu próprio serviço.
Observação:
Para todas as atividades, é necessário declarar os filtros de intents no arquivo de manifesto.
No entanto, filtros para broadcast receivers podem ser registrados de forma dinâmica chamando
registerReceiver()
: É possível cancelar o registro do destinatário com unregisterReceiver()
. Isso permite que o app
para detectar transmissões específicas durante apenas um período específico enquanto o app
está em execução.
Exemplos de filtros
Para demonstrar alguns dos comportamentos dos filtros de intents, veja um exemplo do arquivo de manifesto de um app de compartilhamento social:
<activity android:name="MainActivity" android:exported="true"> <!-- 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" android:exported="false"> <!-- 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 app, ou seja, a atividade que
é aberto quando o usuário inicia o app pela primeira vez com o ícone na tela de início:
- 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 o deve ser colocado no inicializador de aplicativos do sistema. Se o elemento<activity>
não especificar um ícone comicon
, o sistema usará o ícone do<application>
.
Esses dois devem ser pareados para que a atividade apareça no inicializador do aplicativo.
A segunda atividade, ShareActivity
, visa facilitar o compartilhamento de texto e mídia.
conteúdo. Embora os usuários possam acessar essa atividade acessando-a em MainActivity
,
ele também pode inserir ShareActivity
diretamente de outro app que emite uma solicitação
que correspondam a um dos dois filtros de intents.
Observação:o tipo MIME,
application/vnd.google.panorama360+jpg
é um tipo de dado especial que especifica
fotos panorâmicas, que você pode manipular com o Google
panorama.
Corresponder intents a outros apps filtros de intent
Se outro app for direcionado ao Android 13 (nível 33 da API) ou versões mais recentes, ele vai poder processar
intent do app somente se ela corresponder às ações e categorias de um
<intent-filter>
nesse outro app. Se o sistema não encontrar uma
correspondente, ele lança uma
ActivityNotFoundException
.
O app de envio precisa processar
essa exceção.
Da mesma forma, se você atualizar o app para que ele seja destinado ao Android 13
ou superior, todas as intents originadas de aplicativos externos serão entregues a uma
componente exportado do seu app somente se essa intent corresponder às ações e
categorias de um elemento <intent-filter>
declarado pelo app. Esse comportamento
ocorre independentemente da versão do SDK de destino do app de envio.
Nos casos a seguir, a correspondência de intent não é aplicada:
- Intents entregues a componentes que não declaram filtros de intent.
- Intents originadas de um mesmo app.
- Intents do sistema, ou seja, as intents enviadas do
UID do sistema (uid=1000). Apps do sistema incluem
system_server
e apps que definemandroid:sharedUserId
comoandroid.uid.system
. - Intents originadas de uma raiz.
Saiba mais sobre a correspondência de intent.
Uso de um intent pendente
Um objeto PendingIntent
é um wrapper em torno de um objeto Intent
. O objetivo principal de um PendingIntent
é conceder permissão a um aplicativo externo
para usar o Intent
contido como se ele fosse executado do seu
processo do próprio app.
Os principais casos de uso de um intent pendente são os seguintes:
- declarar uma intent que será executada quando o usuário realizar uma ação com sua notificação;
(o parâmetro
NotificationManager
do sistema Android executa oIntent
). - Declarar uma intent que será executada quando o usuário realizar uma ação com a
Widget de app
O app de tela inicial executa o
Intent
. - Declarar uma intent a ser executada em um momento futuro especificado (a API Android
o
AlarmManager
do sistema executa oIntent
).
Assim como cada objeto Intent
é projetado para ser processado por uma
tipo de componente do app (Activity
, Service
ou
como BroadcastReceiver
). Um PendingIntent
também precisa ser
criados com a mesma consideração. Ao usar uma intent pendente, o app não
execute a intent com uma chamada como startActivity()
. Em vez disso, você precisa declarar o tipo de componente pretendido ao criar o
PendingIntent
chamando o respectivo método criador:
PendingIntent.getActivity()
para umIntent
que inicia umaActivity
.PendingIntent.getService()
para umIntent
que inicia umaService
.PendingIntent.getBroadcast()
para umIntent
que inicia umaBroadcastReceiver
.
A menos que o app esteja recebendo intents pendentes de outros apps,
os métodos acima para criar um PendingIntent
provavelmente são os únicos
PendingIntent
métodos que você vai precisar.
Cada método usa a Context
atual do app, a
Intent
que você quer unir e uma ou mais sinalizações que especificam
como a intent precisa ser usada (por exemplo, se a intent pode ser usada mais de uma vez).
Para mais informações sobre o uso de intents pendentes, consulte a documentação de cada dos respectivos casos de uso, como em Notificações e App Widgets.
Especificar a mutabilidade
Caso seu app seja destinado ao Android 12 ou versões mais recentes, especifique a
a mutabilidade de cada objeto PendingIntent
criado pelo app. Para declarar que
um determinado objeto PendingIntent
for mutável ou imutável, use o
PendingIntent.FLAG_MUTABLE
ou
PendingIntent.FLAG_IMMUTABLE
respectivamente.
Se o app tentar criar um objeto PendingIntent
sem definir nenhuma sinalização de mutabilidade, o sistema gera uma
IllegalArgumentException
e
esta mensagem aparece no Logcat:
PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.
Criar intents pendentes imutáveis sempre que possível
Na maioria dos casos, o app precisa criar objetos PendingIntent
imutáveis, conforme
mostrado no snippet de código a seguir. Se um objeto PendingIntent
for imutável,
outros aplicativos não poderão modificar a intenção para ajustar o resultado da invocação do
intenção.
Kotlin
val pendingIntent = PendingIntent.getActivity(applicationContext, REQUEST_CODE, intent, /* flags */ PendingIntent.FLAG_IMMUTABLE)
Java
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), REQUEST_CODE, intent, /* flags */ PendingIntent.FLAG_IMMUTABLE);
No entanto, alguns casos de uso exigem objetos PendingIntent
mutáveis:
- Oferecer suporte a ações de resposta direta em
notificações. A
a resposta direta exige uma mudança nos dados de clipe no objeto PendingIntent
que está associado à resposta. Normalmente, você solicita essa alteração transmitindo
FILL_IN_CLIP_DATA
como uma flag para afillIn()
. - Associar notificações ao framework do Android Auto usando instâncias do
CarAppExtender
- Como colocar conversas em balões usando instâncias
de
PendingIntent
. Um objetoPendingIntent
mutável permite que o sistema aplique as sinalizações corretas, comoFLAG_ACTIVITY_MULTIPLE_TASK
eFLAG_ACTIVITY_NEW_DOCUMENT
- Solicitar informações de localização do dispositivo ligando para
requestLocationUpdates()
ou APIs semelhantes. O objetoPendingIntent
mutável permite que o sistema adicione extras da intent que representam eventos de ciclo de vida do local. Esses eventos incluem mudança na localização e a disponibilização de um provedor. - Agendar alarmes usando
AlarmManager
. O objetoPendingIntent
mutável permite que o sistema adicione oEXTRA_ALARM_COUNT
de intent extra. Esse extra representa o número de vezes que um alarme recorrente for acionado. Ao conter esse extra, a intent pode notificar com precisão em um app para saber se um alarme recorrente foi acionado várias vezes, por exemplo, quando o dispositivo estava suspenso.
Caso o app crie um objeto PendingIntent
mutável, é altamente recomendado
usar uma intent explícita e preencher o
ComponentName
Dessa forma, todas as vezes que
outro app invocar PendingIntent
e devolver o controle para o app, o
mesmo componente será iniciado.
Usar intents explícitas em intents pendentes
Para definir melhor como outros apps podem usar as intents pendentes do seu app, sempre encapsular uma intent pendente em uma intent explícita. Para ajudar a seguir essa prática recomendada, faça o seguinte:
- Verificar se os campos de ação, pacote e componente da intent de base estão definidos.
-
Use
FLAG_IMMUTABLE
, adicionado no Android 6.0 (API de nível 23), para criar intents pendentes. Esta sinalização impede que apps que recebem umaPendingIntent
sejam preenchidos não preenchidas. Se ominSdkVersion
do seu app for22
ou anterior, vocês podem oferecer segurança e compatibilidade em conjunto usando o seguinte código:if (Build.VERSION.SDK_INT >= 23) { // Create a PendingIntent using FLAG_IMMUTABLE. } else { // Existing code that creates a PendingIntent. }
Resolução de intents
Quando o sistema recebe uma intent implícita para iniciar uma atividade, ele procura o melhor atividade para a intent comparando-a aos filtros de intents com base em três aspectos:
- Ação
- Dados (URI e tipo de dados)
- Categoria
As seções a seguir descrevem como as intents são correspondidas aos componentes apropriados de acordo com a declaração do filtro de intent no arquivo de manifesto do app.
Teste de ação
Para especificar ações de intent aceitas, um filtro de intent pode declarar zero ou mais
Elementos <action>
, conforme mostrado no exemplo a seguir:
<intent-filter> <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.VIEW" /> ... </intent-filter>
Para transmitir esse filtro, a ação especificada no Intent
precisa corresponder a uma das ações listadas no filtro.
Se o filtro não listar ações, não haverá nada para uma
para que haja correspondência, todas as intents falharão no teste. No entanto, se uma Intent
não especificar uma ação, ele será aprovado no teste, desde que o filtro
contém pelo menos uma ação.
Teste de categoria
Para especificar as categorias de intent aceitas, um filtro de intent pode declarar zero ou mais
Elementos <category>
, conforme mostrado no exemplo a seguir:
<intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> ... </intent-filter>
Para que uma intent seja aprovada no teste de categoria, todas as categorias em Intent
precisa corresponder a uma categoria no filtro. O contrário não é necessário. O filtro de intenção pode
declarar mais categorias do que o especificado nos Intent
e no
Intent
ainda passa. Portanto, uma intent sem categorias
sempre passará nesse teste, independentemente das categorias declaradas no filtro.
Observação:
O Android aplica automaticamente a categoria CATEGORY_DEFAULT
para todas as intents implícitas transmitidas para startActivity()
e startActivityForResult()
.
Se você quiser que a atividade receba intents implícitas, ela precisa
incluir uma categoria para "android.intent.category.DEFAULT"
nos filtros de intent, conforme
mostrado no exemplo anterior de <intent-filter>
.
Teste de dados
Para especificar dados de intents aceitos, um filtro de intents pode declarar zero ou mais
Elementos <data>
, conforme mostrado no exemplo a seguir:
<intent-filter> <data android:mimeType="video/mpeg" android:scheme="http" ... /> <data android:mimeType="audio/mpeg" android:scheme="http" ... /> ... </intent-filter>
Cada <data>
pode especificar uma estrutura de URI e um tipo de dados (tipo de mídia MIME).
Cada parte do URI é um elemento
atributo: scheme
, host
, port
,
e path
:
<scheme>://<host>:<port>/<path>
O exemplo abaixo mostra possíveis valores para esses atributos:
content://com.example.project:200/folder/subfolder/etc
Nesse 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 o URI em uma intent é comparado a uma especificação de URI em um filtro, ele é comparado apenas com as partes do URI incluídas no filtro. Exemplo:
- Se um filtro especificar apenas um esquema, todos os URIs com esse esquema corresponderão o filtro.
- Se um filtro especificar um esquema e uma autoridade, mas nenhum caminho, todos os URIs com o mesmo esquema e autoridade, passam pelo filtro, independentemente dos caminhos.
- Se um filtro especificar um esquema, uma autoridade e um caminho, somente URIs com o mesmo esquema, e o caminho passam pelo filtro.
Observação:uma especificação de caminho pode conter um caractere curinga asterisco (*) para exigir apenas uma correspondência parcial do nome do caminho.
O teste de dados compara o URI e o tipo MIME da intent com um URI e o tipo MIME especificado no filtro. As regras são as seguintes:
- O intent que não contiver URI nem tipo MIME passa o testar somente se o filtro não especificar nenhum URI ou tipo MIME.
- Uma intent que contém um URI, mas nenhum tipo MIME (nem explícito nem inferido do URI) será aprovado no teste somente se o URI corresponder ao formato de URI do filtro e o filtro, da mesma forma, não especifica um tipo MIME.
- O intent que contiver um tipo MIME, mas não tiver um URI, passar no teste. somente se o filtro listar o mesmo tipo MIME e não especificar um formato de URI.
- Uma intent que contém um URI e um tipo MIME (explícito ou inferido pelo
URI) passará na parte do tipo MIME do teste somente se esse
tipo corresponde a um dos listados no filtro. Ele é aprovado na parte de URI do teste.
se o URI corresponder a um URI no filtro ou se tiver um
content:
oufile:
e o filtro não especificar nenhum URI. Em outras palavras, Presume-se que um componente seja compatível com dadoscontent:
efile:
se o filtro lista apenas um tipo MIME.
Observação:se uma intent especificar um URI ou um tipo MIME, o teste de dados
vão falhar se não houver elementos <data>
no <intent-filter>
.
A última regra, a regra (d), reflete a expectativa
para que os componentes possam receber dados locais de um arquivo ou provedor de conteúdo.
Portanto, os filtros podem listar apenas um tipo de dados e não precisam
Nomeie os esquemas content:
e file:
.
O exemplo a seguir mostra um caso típico em que um elemento <data>
informa ao Android que o componente pode receber dados de imagem de um conteúdo
provedor e o exiba:
<intent-filter> <data android:mimeType="image/*" /> ... </intent-filter>
Filtros que especificar um tipo de dados, mas não um URI, talvez sejam os mais comuns, porque a maioria os dados são dispensados pelos provedores de conteúdo.
Outra configuração comum é de filtros com um esquema e um tipo de dados. Para
exemplo, um <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:mimeType="video/*" /> ... </intent-filter>
Correspondência de intents
As intents são correspondidas a filtros de intents não apenas para descobrir um alvo
componente seja ativado, mas também para descobrir algo sobre o conjunto de
no dispositivo. Por exemplo, o app Home preenche o Acesso rápido aos apps
encontrando todas as atividades com filtros de intents que especificam o
ACTION_MAIN
e
CATEGORY_LAUNCHER
categoria.
A correspondência só é bem-sucedida se as ações e as categorias da intenção corresponderem.
ao filtro, conforme descrito na documentação do IntentFilter
.
O aplicativo pode usar a correspondência de intents de modo semelhante ao feito pelo aplicativo Home.
O PackageManager
tem um conjunto de query...()
.
métodos que retornam todos os componentes que podem aceitar uma determinada intent e
uma série semelhante de métodos resolve...()
que determinam o melhor
para responder a uma intent. Por exemplo:
queryIntentActivities()
retorna uma lista de todas as atividades que podem realizar
a intent transmitida como um argumento, e queryIntentServices()
retorna uma lista semelhante de serviços.
Nenhum dos métodos ativa os componentes. ele apenas lista os que
consegue responder. Existe um método parecido,
queryBroadcastReceivers()
, para broadcast receivers.