Como enviar dados simples para outros apps

O Android usa intents e extras associados para permitir que os usuários compartilhem informações de maneira rápida e fácil, usando os apps favoritos.

O Android oferece duas maneiras para os usuários compartilharem dados entre apps:

  • O Android Sharesheet foi projetado principalmente para enviar conteúdo fora do app e/ou diretamente para outro usuário. Por exemplo, compartilhar um URL com um amigo.
  • O resolvedor de intents do Android é mais adequado para transmitir dados para o próximo estágio de uma tarefa bem definida. Por exemplo, abrir um PDF a partir do seu app e permitir que os usuários escolham o visualizador favorito.

Ao criar uma intent, é preciso especificar a ação a ser executada por ela. O Android usa a ação ACTION_SEND para enviar dados de uma atividade a outra, mesmo entre limites de processos. É necessário especificar os dados e o tipo relacionado. O sistema identifica automaticamente as atividades compatíveis que podem receber os dados e as exibe para o usuário. No caso do resolvedor de intents, se apenas uma atividade puder lidar com a intent, essa atividade será iniciada imediatamente.

Por que usar o Android Sharesheet

É altamente recomendado usar o Android Sharesheet para criar consistência para seus usuários nos apps. Os apps não devem exibir a própria lista de destinos de compartilhamento ou criar as próprias variações do Sharesheet.

O Android Sharesheet oferece aos usuários a capacidade de compartilhar informações com a pessoa certa, incluindo sugestões de app relevantes, tudo em um único toque. O Sharesheet pode sugerir destinos indisponíveis para soluções personalizadas e com classificação consistente. Isso ocorre porque o Sharesheet pode levar em conta informações sobre o app e a atividade do usuário que estão disponíveis apenas para o sistema.

O Android Sharesheet também conta com muitos recursos úteis para desenvolvedores. Por exemplo, você pode:

Usar o Android Sharesheet

Para todos os tipos de compartilhamento, crie uma intent e defina a ação como Intent.ACTION_SEND. Para exibir o Android Sharesheet, é necessário chamar Intent.createChooser(), transmitindo a ele seu objeto Intent. Ele retornará uma versão da sua intent que sempre exibirá o Android Sharesheet.

Enviar conteúdo de texto

O uso mais direto e comum do Android Sharesheet é enviar conteúdo de texto de uma atividade para outra. Por exemplo, a maioria dos navegadores pode compartilhar o URL da página exibida no momento como texto com outro app. Essa opção é muito usada para compartilhar um artigo ou site com amigos por e-mail ou redes sociais. Veja como fazer isso a seguir:

Kotlin

    val sendIntent: Intent = Intent().apply {
        action = Intent.ACTION_SEND
        putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
        type = "text/plain"
    }

    val shareIntent = Intent.createChooser(sendIntent, null)
    startActivity(shareIntent)
    

Java

    Intent sendIntent = new Intent();
    sendIntent.setAction(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
    sendIntent.setType("text/plain");

    Intent shareIntent = Intent.createChooser(sendIntent, null);
    startActivity(shareIntent);
    

Opcionalmente, você pode adicionar outros elementos para incluir mais informações, como destinatários de e-mail (EXTRA_EMAIL, EXTRA_CC, EXTRA_BCC), assunto do e-mail (EXTRA_SUBJECT) e assim por diante.

Observação: alguns apps de e-mail, como o Gmail, esperam uma String[] para elementos extras, como EXTRA_EMAIL e EXTRA_CC, use putExtra(String, String[]) para adicioná-los à sua intent.

Enviar conteúdo binário

Compartilhe dados binários usando a ação ACTION_SEND. Defina o tipo MIME apropriado e coloque um URI para os dados no elemento extra EXTRA_STREAM. Em geral, essa opção é usada para compartilhar imagens, mas pode ser usada para compartilhar qualquer tipo de conteúdo binário:

Kotlin

    val shareIntent: Intent = Intent().apply {
        action = Intent.ACTION_SEND
        putExtra(Intent.EXTRA_STREAM, uriToImage)
        type = "image/jpeg"
    }
    startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
    

Java

    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
    shareIntent.setType("image/jpeg");
    startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
    

O aplicativo receptor precisa de permissão para acessar os dados que o Uri indica. As maneiras recomendadas para fazer isso são as seguintes:

  • Armazene os dados no próprio ContentProvider, garantindo que outros apps tenham a permissão correta para acessar seu provedor. O mecanismo preferencial para conceder acesso é usar permissões por URI, que são temporárias e só concedem acesso ao aplicativo receptor. Uma maneira fácil de criar um ContentProvider como esse é usar a classe auxiliar FileProvider.
  • Use o sistema MediaStore. O MediaStore é destinado principalmente a tipos MIME de vídeo, áudio e imagem. No entanto, a partir do Android 3.0 (nível 11 da API), ele também pode armazenar tipos que não são de mídia (consulte MediaStore.Files para saber mais). É possível inserir arquivos no MediaStore usando scanFile(), seguido de um content:// de estilo Uri adequado para compartilhamento, que é transmitido para o callback onScanCompleted() fornecido. Depois de adicionado ao MediaStore do sistema, o conteúdo pode ser acessado por qualquer app no dispositivo.

Usar o tipo MIME correto

Informe o tipo MIME mais específico para os dados que você está enviando. Por exemplo, use text/plain ao compartilhar texto simples. Aqui estão alguns tipos MIME comuns para o envio de dados simples no Android.

  • text/plain, text/rtf, text/html, text/json: os receptores têm que ser registrados para text/*
  • image/jpg, image/png, image/gif: os receptores têm que ser registrados para image/*
  • video/mp4, video/3gp: os receptores têm que ser registrados para video/*
  • application/pdf: os receptores têm que ser registrados para as extensões de arquivo compatíveis
  • Você pode usar o tipo MIME */*, mas isso não é recomendado e só haverá correspondência para as atividades capazes de lidar com fluxos de dados genéricos.

O Android Sharesheet pode mostrar uma visualização de conteúdo com base no tipo MIME informado. Alguns recursos de visualização estão disponíveis apenas para tipos específicos.

Consulte o registro oficial da IANA dos tipos de mídia MIME.

Compartilhar várias partes de conteúdo

Para compartilhar várias partes do conteúdo, use a ação ACTION_SEND_MULTIPLE junto com uma lista de URIs que apontam para o conteúdo. O tipo MIME varia de acordo com a combinação de conteúdos que você está compartilhando. Por exemplo, se você compartilhar três imagens JPEG, o tipo ainda será "image/jpg". Para uma mistura de tipos de imagem, o tipo precisará ser "image/*" para corresponder a uma atividade que lida com qualquer tipo de imagem. Embora seja possível compartilhar uma mistura de tipos, isso não é recomendado, uma vez que não fica claro para o receptor o que deve ser enviado. Se for necessário enviar vários tipos, use "*/*". Cabe ao aplicativo receptor analisar e processar seus dados. Veja um exemplo:

Kotlin

    val imageUris: ArrayList<Uri> = arrayListOf(
            // Add your image URIs here
            imageUri1,
            imageUri2
    )

    val shareIntent = Intent().apply {
        action = Intent.ACTION_SEND_MULTIPLE
        putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris)
        type = "image/*"
    }
    startActivity(Intent.createChooser(shareIntent, "Share images to.."))
    

Java

    ArrayList<Uri> imageUris = new ArrayList<Uri>();
    imageUris.add(imageUri1); // Add your image URIs here
    imageUris.add(imageUri2);

    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE);
    shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris);
    shareIntent.setType("image/*");
    startActivity(Intent.createChooser(shareIntent, "Share images to.."));
    

Verifique se o ponto de URIs informado aponta para dados que podem ser acessados por um app receptor.

Adicionar conteúdo avançado a visualizações de texto

A partir do Android 10 (API nível 29), o Android Sharesheet mostra uma visualização do texto que está sendo compartilhado. Em alguns casos, o texto compartilhado pode ser difícil de entender. Imagine um caso de compartilhamento de um URL complicado, como https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4. Uma visualização mais avançada pode tranquilizar os usuários com relação ao que está sendo compartilhado.

Se você estiver visualizando o texto, poderá definir um título, uma imagem em miniatura ou ambos. Adicione uma descrição a Intent.EXTRA_TITLE antes de chamar Intent.createChooser(). Adicione uma miniatura relevante por meio do ClipData.

Observação: o URI do conteúdo da imagem precisa ser fornecido de um FileProvider, geralmente um <cache-path> configurado. Consulte Compartilhar arquivos. O Sharesheet precisa ter as permissões corretas para ler qualquer imagem que você queira usar como miniatura. Consulte Intent.FLAG_GRANT_READ_URI_PERMISSION.

Veja um exemplo:

Kotlin

     val share = Intent.createChooser(Intent().apply {
          action = Intent.ACTION_SEND
          putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/")

          // (Optional) Here we're setting the title of the content
          putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

          // (Optional) Here we're passing a content URI to an image to be displayed
          data = contentUri
          flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
      }, null)
      startActivity(share)
    

Java

    Intent sendIntent = new Intent(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT, "Hello!");

    // (Optional) Here we're setting the title of the content
    sendIntent.putExtra(Intent.EXTRA_TITLE, "Send message");

    // (Optional) Here we're passing a content URI to an image to be displayed
    sendIntent.setData(contentUri);
    sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    // Show the Sharesheet
    startActivity(Intent.createChooser(sendIntent, null));
    

A visualização é semelhante a esta:

Adicionar destinos personalizados

O Android Sharesheet permite especificar um número limitado de objetos ChooserTarget que são mostrados antes dos atalhos de compartilhamento e dos ChooserTargets carregados de ChooserTargetServices. Você também pode especificar um número limitado de intents que apontam para atividades listadas antes das sugestões do app.

Adicione Intent.EXTRA_CHOOSER_TARGETS e Intent.EXTRA_INITIAL_INTENTS à intent de compartilhamento depois de chamar Intent.createChooser().

Kotlin

    val share = Intent.createChooser(myShareIntent, null).apply {
        putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray)
        putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray)
    }
    

Java

    val share = Intent.createChooser(myShareIntent, null)
    share.putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray);
    share.putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray);
    

Use esse recurso com cuidado. Cada Intent e ChooserTarget personalizados que você adiciona reduz o número sugerido pelo sistema. A adição de destinos personalizados não é recomendada. Um exemplo comum da adição de Intent.EXTRA_INITIAL_INTENTS é disponibilizar outras ações que os usuários podem realizar em conteúdos compartilhados. Por exemplo, o usuário compartilha imagens, e Intent.EXTRA_INITIAL_INTENTS é usado para oferecer a capacidade de enviar um link. Um exemplo comum da adição de Intent.EXTRA_CHOOSER_TARGETS é mostrar pessoas ou dispositivos relevantes para os quais seu app é oferecido.

Excluir destinos específicos por componente

Você pode excluir destinos específicos fornecendo Intent.EXTRA_EXCLUDE_COMPONENTS.. Essa opção só tem que ser usada para remover os destinos que você controla. Um caso de uso comum é ocultar os destinos de compartilhamento do app quando seus usuários compartilham de dentro dele, uma vez que a intent tende a compartilhar fora dele.

Adicione Intent.EXTRA_EXCLUDE_COMPONENTS à intent depois de chamar Intent.createChooser().

Kotlin

    val share = Intent.createChooser(myShareIntent, null).apply {
      // Only use components you have control over
      share.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, myComponentArray)
    }
    

Java

    share = Intent.createChooser(myShareIntent, null);
    // Only use components you have control over
    share.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, myComponentArray);
    

Receber informações sobre compartilhamento

Pode ser útil saber quando seus usuários estão compartilhando e qual é o destino selecionado. O Android Sharesheet torna isso possível fornecendo o ComponentName de destinos em que os usuários clicam por meio de um IntentSender.

Primeiro, crie um PendingIntent para um BroadcastReceiver e forneça o IntentSender dele em Intent.createChooser().

Kotlin

    var share = new Intent(Intent.ACTION_SEND);
    ...
    val pi = PendingIntent.getBroadcast(myContext, requestCode, Intent(myContext, MyBroadcastReceiver.class),
    Intent.FLAG_UPDATE_CURRENT)
    share = Intent.createChooser(share, null, pi.intentSender);
    

Java

    Intent share = new Intent(ACTION_SEND);
    ...
    PendingIntent pi = PendingIntent.getBroadcast(myContext, requestCode,
                    new Intent(myContext, MyBroadcastReceiver.class),
                    FLAG_UPDATE_CURRENT);
    share = Intent.createChooser(share, null, pi.getIntentSender());
    

Receba o callback em MyBroadcastReceiver e procure em Intent.EXTRA_CHOSEN_COMPONENT.

Kotlin

    override fun onReceive(context: Context, intent: Intent) {
      ...
      val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
    }
    

Java

    @Override public void onReceive(Context context, Intent intent) {
      ...
      ComponentName clickedComponent = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT);
    }
    

Usar o resolvedor de intents do Android

Captura de tela do resolvedor de intents ACTION_SEND.

O resolvedor de intents do Android é mais adequado para enviar dados para outro app como parte de um fluxo de tarefas bem definido.

Para usar o resolvedor de intents do Android, crie uma intent e adicione elementos extras como você faria se chamasse o Android Sharesheet. No entanto, não chame Intent.createChooser().

Se houver vários aplicativos instalados com filtros que correspondem a ACTION_SEND e ao tipo MIME, o sistema exibirá uma caixa de diálogo de desambiguação denominada resolvedor de intents, que permite que o usuário escolha um destino de compartilhamento. Se um único aplicativo for correspondente, ele será executado.

Veja um exemplo de como usar o resolvedor de intents do Android para enviar texto:

Kotlin

    val sendIntent: Intent = Intent().apply {
        action = Intent.ACTION_SEND
        putExtra(Intent.EXTRA_TEXT, "This is my text to send.")
        type = "text/plain"
    }
    startActivity(sendIntent)
    

Java

    Intent sendIntent = new Intent();
    sendIntent.setAction(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
    sendIntent.setType("text/plain");
    startActivity(sendIntent);
    

Saiba mais

Para mais informações sobre o envio de dados, consulte Intents e filtros de intents.