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 a navegação 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 à sua 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 combinável que deve 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 de 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 tenha um link direto para uma conversa com ela. Consulte Fornecer destinos de compartilhamento direto para instruções detalhadas.
Oferecer suporte a tipos MIME
O ideal é que um app possa receber a maior variedade possível de tipos MIME.
Por exemplo, um app de mensagens projetado para enviar texto, imagens e vídeo oferece suporte ao recebimento de text/*, image/* e video/*. Confira alguns tipos MIME comuns para enviar e receber dados no Android.
| Os receptores se registram para | Os remetentes enviam |
|---|---|
text/* |
|
image/* |
|
video/* |
|
| Extensões de arquivo compatíveis | application/pdf |
Consulte o registro oficial de tipos de mídia MIME da IANA (em inglês).
Criar ótimos destinos de compartilhamento
Quando os usuários tocam 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
O recebimento de dados compartilhados em um app que usa o Compose envolve a declaração de filtros de intent no manifesto, o roteamento de intents recebidas para a tela adequada com links diretos e a extração do 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 Enviar
dados para outros apps, crie filtros de intent para receber
intents com essa ação. Você define um filtro de intent no manifesto usando o
<intent-filter> elemento. Por exemplo, se o app processar o recebimento de conteúdo de texto, um manifesto que inclua uma ou mais imagens de qualquer tipo será semelhante ao snippet a seguir:
<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 iniciará a atividade correspondente (.ui.MyActivity no exemplo anterior). Em seguida, você precisa 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 deve mostrar o conteúdo. Quando outro app compartilha dados que correspondem ao filtro de intent, a navegação do Compose direciona o usuário diretamente para esse 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 corresponde à ação e ao tipo MIME da intent recebida para navegar até a tela de destino correta. Depois de chegar a esse destino, o gerenciador inspeciona a intent para determinar qual payload foi recebido (como uma única imagem em vez de várias) e extrai os extras correspondentes.
Processar o conteúdo recebido
Para recuperar o conteúdo entregue por um Intent, leia a atividade atual de 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 inicializador), considere isso ao examinar a intent.
Tome cuidado extra 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 da linha de execução principal da interface.
@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) não parametrizado em favor de métodos de tipo seguro que usam o tipo de classe esperado.
A atualização da interface após o recebimento dos dados pode ser tão simples quanto atualizar
o estado para preencher um TextField ou tão complexa quanto aplicar um filtro
a uma imagem. Depende do seu app o que acontece em seguida.
Compartilhamento de URL de captura de tela
Ao fazer uma captura de tela, você pode compartilhar a captura e qualquer URL associado.
Isso proporciona uma experiência do usuário mais rica. Ao receber um URL, extraia 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 rótulo na Android Sharesheet e no resolvedor de intents. Ambos são definidos no manifesto. Você pode definir rótulos de atividade ou filtro de intent para fornecer mais contexto.
No Android 10 (nível 29 da API), a Sharesheet do Android usa apenas ícones definidos no manifesto na tag application. O Android ignora ícones definidos nas tags intent-filter e activity.
Receber conteúdo avançado
Embora as intents ACTION_SEND permitam o recebimento de dados da Android Sharesheet e do resolvedor de intents no nível de Activity ou Navigation, os apps também podem receber conteúdo avançado (como imagens, vídeos, arquivos de áudio e texto estilizado) por interações diretas da interface. Esses mecanismos incluem:
- Colar da área de transferência (menu de toque e retenção)
- 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 introduzem a
API OnReceiveContentListener unificada. 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 obter 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
Modifier.contentReceiver modificador ou
modificadores de arrastar e soltar.