Receber dados de outros apps

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:

  1. Declare um <intent-filter> no manifesto: ainda é necessário adicionar um filtro de intent à atividade no arquivo AndroidManifest.xml. Isso informa ao SO Android que seu aplicativo pode receber ações específicas (como ACTION_SEND) e tipos MIME (como text/plain).

  2. Defina um navDeepLink no gráfico de navegação do Compose: anexe um navDeepLink que corresponda à ação e ao tipo MIME diretamente ao destino de composição que vai mostrar o conteúdo. O NavController intercepta automaticamente a intent recebida e direciona o usuário diretamente para essa tela.

  3. Extraia o payload de dados recebidos: na tela de destino, acesse os extras da intent (como EXTRA_TEXT ou EXTRA_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/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
image/*
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
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.

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:

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.