Melhorias de compartilhamento

O Android Q possui vários recursos novos relacionados a compartilhamento.

API de atalhos de compartilhamento

O ShareSheet foi alterado no Android Q. As APIs Direct Share foram substituídas pela nova API Sharing Shortcuts. O mecanismo de compartilhamento direto existente continuará funcionando, mas terá uma prioridade mais baixa do que os apps que usarem a nova API.

Em vez de recuperar os resultados de forma reativa sob demanda, a API de atalhos de compartilhamento permite que os apps publiquem alvos de compartilhamento direto com antecedência. É assim que o ShortcutManager funciona. Como as duas APIs são semelhantes, expandimos a API ShortcutInfo para facilitar o uso dos dois recursos. Com a nova API, é possível atribuir categorias ou pessoas diretamente a um alvo de compartilhamento. Os alvos de compartilhamento continuam no sistema até que o mesmo app os atualize ou que o app seja desinstalado.

Exemplo de código: SharingShortcuts

Publicar alvos de compartilhamento direto

Atualmente, apenas atalhos dinâmicos são compatíveis com a publicação de alvos de compartilhamento direto. Siga as etapas a seguir para publicá-los usando a nova API:

  1. Declare elementos de alvos de compartilhamento no arquivo de recurso XML do app. Para ver detalhes, consulte Declarar um alvo de compartilhamento abaixo.
  2. Publique atalhos dinâmicos com categorias correspondentes aos alvos de compartilhamento declarados. Os atalhos podem ser adicionados, acessados, atualizados e removidos usando o ShortcutManager ou o ShortcutManagerCompat no AndroidX. O método preferencial é usar a biblioteca de compatibilidade no AndroidX, porque ela oferece compatibilidade com versões anteriores do Android.

API DirectShare

A ShortcutInfo.Builder inclui métodos novos e aprimorados que oferecem mais informações sobre o alvo de compartilhamento:

setCategories()
Este não é um método novo, mas agora as categorias também são usadas para filtrar atalhos que podem manipular intents ou ações de compartilhamento. Consulte Declarar um alvo de compartilhamento abaixo para mais detalhes. Este campo é necessário para atalhos que precisam ser usados como alvos de compartilhamento.
setLongLived()
Especifica se um atalho é válido ou não quando o app cancelou a publicação dele ou o tornou invisível (como um atalho dinâmico ou fixado). Se um atalho é de longa duração, ele pode ser armazenado em cache por vários serviços do sistema, mesmo depois de ter tido a publicação cancelada como atalho dinâmico.
setPerson(), setPersons()

Associa um ou mais objetos Person ao atalho. Pode ser usado para entender melhor o comportamento do usuário em diferentes apps e para ajudar os serviços de previsão do framework a melhorar as sugestões em um ShareSheet. O acréscimo de informações de Person a um atalho é opcional, mas recomendável se o alvo de compartilhamento for associado a uma pessoa. Alguns alvos de compartilhamento, como nuvem, não podem ser associados a uma pessoa.

Para um app de mensagens típico, é necessário publicar um alvo de compartilhamento separado (atalho) para cada contato, e o campo Person precisa conter as informações do contato. Se o alvo puder ser associado a várias pessoas (como um bate-papo em grupo), adicione vários Persons a um único alvo de compartilhamento.

Declarar um alvo de compartilhamento

Os alvos de compartilhamento precisam ser declarados no arquivo de recursos do app, da mesma forma que as definições de atalhos estáticos. Adicione as definições de alvos de compartilhamento dentro do elemento raiz <shortcuts> no arquivo de recursos, junto com outras definições de atalhos estáticos. Cada elemento <share-target> contém informações sobre o tipo de dado compartilhado, as categorias correspondentes e a classe de alvo que manipulará o intent de compartilhamento. O código XML é semelhante a este:

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
      <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity">
        <data android:mimeType="text/plain" />
        <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" />
      </share-target>
    </shortcuts>
    

O elemento de dados em um alvo de compartilhamento é semelhante à especificação de dados em um filtro de intent. Cada alvo de compartilhamento pode ter várias categorias, que são usadas apenas para corresponder aos atalhos publicados de um app com as respectivas definições de alvo de compartilhamento. As categorias podem ter valores arbitrários definidos pelo app.

Caso o usuário selecione um alvo de compartilhamento direto (atalho) no ShareSheet que corresponda ao exemplo de alvo de compartilhamento acima, o app receberá o seguinte intent de compartilhamento:

Action: Intent.ACTION_SEND
    ComponentName: {com.example.android.sharingshortcuts /
                    com.example.android.sharingshortcuts.SendMessageActivity}
    Data: Uri to the shared content
    EXTRA_SHORTCUT_ID: <ID of the selected shortcut>
    

Se o usuário abrir o alvo de compartilhamento a partir dos atalhos da tela de início, o app receberá o intent criado durante a adição do atalho de compartilhamento a ShortcutManagerCompat. Por ser é um intent diferente, Intent.EXTRA_SHORTCUT_ID não estará disponível, e você terá que passar o código manualmente se precisar dele.

Compartilhamento direto no AndroidX

ShortcutManagerCompat é uma nova API do AndroidX que oferece compatibilidade com a antiga API DirectShare. Essa é a maneira preferencial de publicar alvos de compartilhamento.

Para trabalhar com a biblioteca de compatibilidade, o arquivo manifest do app precisa conter o conjunto de metadados de serviço seletor de alvo e de filtros de intent. Veja a API de compartilhamento direto atual.

Esse serviço já está declarado na biblioteca de compatibilidade, portanto, o usuário não precisa declarar o serviço no manifest do app. No entanto, o link da atividade de compartilhamento para o serviço precisa ser considerado como um provedor do seletor de alvo.

No exemplo a seguir, a implementação do ChooserTargetService é androidx.core.content.pm.ChooserTargetServiceCompat, que já está definido no AndroidX:

<activity
        android:name=".SendMessageActivity"
        android:label="@string/app_name"
        android:theme="@style/SharingShortcutsDialogTheme">
        <!-- This activity can respond to Intents of type SEND -->
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>
        <!-- Only needed if you import the sharetarget AndroidX library that
             provides backwards compatibility with the old DirectShare API.
             The activity that receives the Sharing Shortcut intent needs to be
             taken into account with this chooser target provider. -->
        <meta-data
            android:name="android.service.chooser.chooser_target_service"
            android:value="androidx.sharetarget.ChooserTargetServiceCompat" />
    </activity>
    

Visualização do conteúdo

Quando um app compartilha conteúdo, ele pode exibir uma visualização opcional do conteúdo na IU do Sharesheet.

A visualização pode ter um título, uma imagem ou ambos.

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.setClipData(contentUri);
    sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    // Start the chooser to show the Sharesheet
    startActivity(Intent.createChooser(sendIntent, null));
    

O URI do conteúdo da imagem precisa ser fornecido por um FileProvider, geralmente um <cache-path> configurado. Veja Compartilhamento de arquivos.

Veja um exemplo completo no app de exemplo.

Perguntas frequentes

Quais são as principais diferenças entre a API de compartilhamento direto nova e a antiga?

A nova API de compartilhamento direto usa um modelo push, e a antiga API, um modelo pull. Isso agiliza muito o processo de recuperação de alvos de compartilhamento durante a preparação do ShareSheet. Do ponto de vista do desenvolvedor do app, com o uso da nova API, o app precisa listar os alvos de compartilhamento direto com antecedência. Também pode ser necessário atualizar a lista de atalhos sempre que o estado interno do app for alterado (por exemplo, se um novo contato for adicionado a um app de mensagens).

O que pode acontecer se eu não migrar para as novas APIs?

No Android Q e versões posteriores, o ShareSheet priorizará os alvos de compartilhamento fornecidos pelo ShortcutManager (a nova API). Assim, seus alvos de compartilhamento publicados podem ser ocultados por alvos de compartilhamento de outros apps e podem nunca aparecer quando forem compartilhados.

Posso usar APIs de compartilhamento direto antigas e novas no meu app para ser compatível com versões anteriores?

Não faça isso. Em vez disso, use as APIs da biblioteca de suporte fornecidas (ShortcutManagerCompat). A mistura de dois conjuntos de APIs pode provocar um comportamento indesejado/inesperado ao recuperar os alvos de compartilhamento.

Qual é a diferença entre os atalhos publicados para os alvos de compartilhamento e os atalhos da tela de início (o uso normal de atalhos quando se toca e mantém pressionados os ícones de apps na tela de início)?

Todos os atalhos publicados com a função de "alvo de compartilhamento" também são atalhos da tela de início e serão exibidos no menu ao se tocar e manter pressionado o ícone do app. O limite máximo de atalhos por atividade também se aplica ao número total de atalhos que um app publica (alvos de compartilhamento e atalhos da tela de início herdados combinados).