Assim como um app pode enviar dados para outros apps, ele também pode receber dados de outros apps. Pense em como os usuários interagem com seu aplicativo e quais tipos de dados você quer receber de outros aplicativos. Por exemplo, um aplicativo de rede social pode ter interesse em receber conteúdo de texto, como um URL da Web interessante, de outro app.
Em um app que usa o Navigation do Compose, o recebimento de dados enviados por outro app é um processo de três etapas:
Declare um
<intent-filter>no manifesto: ainda é necessário adicionar um filtro de intent à atividade no arquivoAndroidManifest.xml. Isso informa ao SO Android que seu aplicativo pode receber ações específicas (comoACTION_SEND) e tipos MIME (comotext/plain).Defina um
navDeepLinkno gráfico de navegação do Compose: anexe umnavDeepLinkque corresponda à ação e ao tipo MIME diretamente ao destino de composição que vai mostrar o conteúdo. ONavControllerintercepta automaticamente a intent recebida e direciona o usuário diretamente para essa tela.Extraia o payload de dados recebidos: na tela de destino, acesse os extras da intent (como
EXTRA_TEXTouEXTRA_STREAM) para recuperar o conteúdo compartilhado e atualizar o estado da interface.
Os destinos de compartilhamento direto são links diretos para uma Activity específica no seu app. Eles geralmente representam uma pessoa ou um grupo, e a Android Sharesheet os mostra. Por exemplo, um app de mensagens pode fornecer um destino de Compartilhamento Direto para uma pessoa que direciona diretamente para uma conversa com ela. Consulte Fornecer destinos de Compartilhamento direto para ver instruções detalhadas.
Tipos MIME compatíveis
O ideal é que um app seja capaz de receber a maior variedade possível de tipos MIME.
Por exemplo, um app de mensagens projetado para enviar texto, imagens e vídeos
precisa oferecer suporte ao recebimento de text/*, image/* e video/*. Confira alguns
tipos MIME comuns para enviar e receber dados no Android.
| Os destinatários se registram para | Os remetentes enviam |
|---|---|
text/* |
|
image/* |
|
video/* |
|
| Extensões de arquivo compatíveis | application/pdf |
Consulte o registro oficial da IANA de tipos de mídia MIME.
Criar ótimos destinos de compartilhamento
Quando os usuários tocarem em um destino de compartilhamento associado a uma atividade específica, permita que eles confirmem e editem o conteúdo compartilhado antes que o app o use. Isso é especialmente importante para dados de texto.
Receber dados no app
Para receber dados pessoais compartilhados em um app que usa o Compose, é necessário declarar filtros de intent no manifesto, encaminhar intents recebidas para a tela adequada com links diretos e extrair o payload da intent para atualizar a interface.
Atualizar seu manifesto
Os filtros de intent informam ao sistema quais intents um componente do app aceita. Assim como você criou uma intent com uma ação ACTION_SEND na lição Como enviar dados para outros apps, você cria filtros de intent para receber intents com essa ação. Defina um filtro de intent no manifesto usando o elemento
<intent-filter>. Por exemplo, se o app processa o recebimento de conteúdo de texto, um manifesto que inclui uma ou mais imagens de qualquer tipo seria semelhante
ao snippet abaixo:
<activity android:name=".ui.MyActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
Quando outro app tenta compartilhar qualquer um desses itens criando uma intent
e transmitindo-a para startActivity(), seu aplicativo é listado
como uma opção na Android Sharesheet ou no resolvedor de intents. Se o usuário selecionar
seu app, isso vai iniciar a atividade correspondente (.ui.MyActivity no
exemplo anterior). Em seguida, cabe a você processar o conteúdo adequadamente
no código e na interface.
Definir um link direto no gráfico de navegação
Na navegação do Compose, anexe um navDeepLink diretamente ao destino combinável
que vai mostrar o conteúdo. Quando outro app compartilha dados que
correspondem ao seu filtro de intent, o Compose Navigation encaminha o usuário diretamente para este
destino:
composable( route = "incoming_share", deepLinks = listOf( navDeepLink { action = Intent.ACTION_SEND mimeType = "text/plain" }, navDeepLink { action = Intent.ACTION_SEND mimeType = "image/*" }, navDeepLink { action = Intent.ACTION_SEND_MULTIPLE mimeType = "image/*" } ) ) { SharesheetHandler() }
O navDeepLink faz a correspondência com a ação e o tipo MIME da intent recebida para
navegar até a tela de destino correta. Nesse destino, o
gerenciador inspeciona a intent para determinar qual payload foi recebido (por exemplo, uma
única imagem ou várias) e extrai os extras correspondentes.
Processar o conteúdo recebido
Para recuperar o envio de conteúdo por um Intent, leia a atividade atual em LocalActivity.current no elemento combinável e examine a intent para determinar o que fazer em seguida. Se essa atividade puder ser
iniciada em outras partes do sistema (como o acesso rápido), considere isso
ao examinar a intent.
Tenha cuidado ao verificar os dados recebidos: o tipo MIME errado pode ser definido ou uma
imagem enviada pode ser extremamente grande. Processe dados binários ou operações de E/S
pesadas (como decodificar imagens grandes ou gravar arquivos) de forma assíncrona usando
corrotinas (como Dispatchers.IO) em vez de usar a linha de execução de interface principal.
@Composable fun SharesheetHandler() { val activity = LocalActivity.current val intent = activity?.intent when (intent?.action) { Intent.ACTION_SEND -> { if (intent.type == "text/plain") { handleSendText(intent) // Handle text being sent } else if (intent.type?.startsWith("image/") == true) { handleSendImage(intent) // Handle single image being sent } } Intent.ACTION_SEND_MULTIPLE -> { if (intent.type?.startsWith("image/") == true) { handleSendMultipleImages(intent) // Handle multiple images being sent } } else -> { // Handle other intents, such as being started from the home screen } } } private fun handleSendText(intent: Intent) { intent.getStringExtra(Intent.EXTRA_TEXT)?.let { // Update UI state with the shared text } } private fun handleSendImage(intent: Intent) { val imageUri = IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java) imageUri?.let { // Update UI state with the shared image } } private fun handleSendMultipleImages(intent: Intent) { val imageUris = IntentCompat.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM, Uri::class.java) imageUris?.let { // Update UI state with the shared images } }
Ao extrair dados binários ou URIs de extras de intent (como EXTRA_STREAM),
use IntentCompat.getParcelableExtra() ou
IntentCompat.getParcelableArrayListExtra()
da biblioteca AndroidX Core, conforme mostrado nas funções handleSendImage e
handleSendMultipleImages anteriores. O Android 13 (nível 33 da API) descontinua o método
Intent.getParcelableExtra(String) sem parâmetros em favor de métodos com segurança de tipos
que usam o tipo de classe esperado.
Atualizar a interface após receber os dados pode ser tão simples quanto atualizar
o estado para preencher um TextField ou tão complexo quanto aplicar um filtro
a uma imagem. O que acontece em seguida depende do seu app.
Compartilhamento de URL de captura de tela
Ao fazer uma captura de tela, você pode compartilhar a imagem e qualquer URL associado.
Isso oferece uma experiência do usuário mais sofisticada. Ao receber um URL, verifique se você recebeu
o campo EXTRA_TEXT da intent, conforme mostrado no exemplo a seguir:
IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let { // Handle the EXTRA_TEXT as well val extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT) // Update UI state with the shared image and the EXTRA_TEXT if available }
Garantir que os usuários reconheçam seu app
O app é representado pelo ícone e pelo rótulo no Android Sharesheet e no resolvedor de intents. Ambos são definidos no manifesto. É possível definir rótulos de filtro de atividade ou filtro de intent para fornecer mais contexto.
No Android 10 (nível 29 da API) e versões mais recentes, a página de compartilhamento do Android usa apenas ícones definidos no
manifesto na tag application. O Android ignora os ícones definidos nas tags intent-filter
e activity.
Receber conteúdo avançado
Embora as intents ACTION_SEND permitam receber dados do Android Sharesheet
e do resolvedor de intents no nível da atividade ou da navegação, os apps também podem receber
conteúdo avançado (como imagens, vídeos, arquivos de áudio e texto estilizado) por meio de
interações diretas com a interface. Esses mecanismos incluem:
- Colar da área de transferência (menu de tocar e manter pressionado)
- Inserir mídia diretamente do teclado de software (IME), como adesivos ou GIFs.
- Arrastar e soltar conteúdo de outro app no modo de várias janelas ou tela dividida
Em interfaces baseadas em visualização, o Android 12 (nível 31 da API) e o AndroidX Core 1.7 apresentam a
API unificada OnReceiveContentListener. Esse
listener consolida o processamento de conteúdo da área de transferência, do teclado e
de arrastar e soltar em um único callback. Para instruções detalhadas sobre como implementar
isso em visualizações, consulte Receber conteúdo avançado.
No Jetpack Compose, é possível processar o recebimento de conteúdo avançado inserido em componentes
da interface (como campos de texto) usando o modificador
Modifier.contentReceiver ou
modificadores de arrastar e soltar.