Da mesma forma que um app envia dados a outros apps, ele também pode receber dados. Pense em como os usuários interagem com seu app e nos tipos de dados que você quer receber de outros apps. Por exemplo, para um app de rede social, pode ser interessante receber conteúdo de texto de outro app, como um URL da Web.
Muitas vezes os usuários enviam dados ao app por meio do Android Sharesheet ou do resolvedor de intents. Todos os dados recebidos têm um tipo MIME definido pelo app provedor. Seu app pode receber dados enviados por outro app de três formas:
- Uma
Activity
com uma tagintent-filter
correspondente no manifesto - Um ou mais objetos
ChooserTarget
retornados peloChooserTargetService
- Atalhos de compartilhamento publicados pelo seu app. Eles substituem os objetos
ChooserTarget
. Os atalhos de compartilhamento só estão disponíveis em apps para o Android 10 (API de nível 29)
Os atalhos de compartilhamento e os objetos ChooserTarget
são links diretos de compartilhamento direto para uma Activity
específica no seu app. Em geral, eles representam uma pessoa e são exibidos pelo Android Sharesheet.
Por exemplo, um app de mensagens de texto pode oferecer um atalho de compartilhamento para alguém que tem link direto para uma conversa com essa pessoa.
Como oferecer compatibilidade com tipos MIME
Seu app deve conseguir receber o maior número possível de tipos de MIME. Por exemplo, um app de mensagens usado para enviar texto, imagens e vídeos precisa ser compatível com o recebimento de text/*
, image/*
e video/*
. Veja alguns tipos MIME comuns para o envio de dados simples no Android.
text/*
: em, geral, o usuário remetente enviarátext/plain
,text/rtf
,text/html
,text/json
.image/*
: em, geral, o usuário remetente enviaráimage/jpg
,image/png
,image/gif
.video/*
: em, geral, o usuário remetente enviarávideo/mp4
,video/3gp
.- Os destinatários precisam se registrar para extensões de arquivo compatíveis: em geral, o usuário remetente enviará
application/pdf
.
Consulte o registro oficial IANA de tipos MIME de mídia. Você pode receber um tipo MIME de */*
, mas isso não é recomendável, a menos que você seja totalmente capaz de processar qualquer tipo de conteúdo recebido.
Como criar excelentes alvos de compartilhamento
Quando um usuário toca em um alvo de compartilhamento associado a uma atividade específica, ele deve poder confirmar e editar o conteúdo compartilhado antes de usá-lo. Isso é especialmente importante no caso de dados de mensagens de texto.
O toque em qualquer alvo de compartilhamento direto deve levar o usuário a uma interface onde uma ação possa ser diretamente realizada no assunto do alvo. Evite mostrar uma desambiguação ao usuário ou levá-lo a uma interface não relacionada ao alvo tocado. Principalmente, não leve o usuário a uma interface de desambiguação de contatos em que ele precise confirmar ou selecionar novamente o contato para o compartilhamento, uma vez que isso já foi feito ao tocar no alvo no Android Sharesheet. Por exemplo, em um app de mensagens de texto, o toque em um alvo de compartilhamento direto deve levar o usuário a uma visualização de conversas com a pessoa selecionada. O teclado deve estar visível, e a mensagem deve ser preenchida previamente com os dados compartilhados.
Como receber dados com uma atividade
Atualizar seu manifesto
Os filtros de intent dizem ao sistema quais intents um componente de app tende a aceitar.
Da mesma forma que você criou uma intent com a ação ACTION_SEND
na lição Como enviar dados simples para outros apps, crie filtros de intent para poder receber intent com essa ação. O filtro de intent é definido no manifesto usando o elemento <intent-filter>
. Por exemplo, se seu app processa conteúdo de mensagens de texto recebidas e uma única imagem, ou diversas imagens, de qualquer tipo, seu manifesto deve ser mais ou menos assim:
<activity android:name=".ui.MyActivity" > <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 tentar compartilhar qualquer um desses itens criando uma intent e transmitindo-a para startActivity()
, seu app será listado como uma opção no Android Sharesheet ou no resolvedor de intents. Se o usuário selecionar seu app, a atividade correspondente (.ui.MyActivity
no exemplo acima) será iniciada. Cabe a você processar o conteúdo corretamente no seu código e na IU.
Observação: para ver mais informações sobre filtros de intents e resolução de intents, leia Intents e filtros de intents
Processar o conteúdo recebido
Para processar o conteúdo enviado por um Intent
, chame getIntent()
para conseguir o objeto Intent
. Assim que você tiver o objeto, poderá analisar o conteúdo dele e determinar o que fazer em seguida. Se for possível iniciar essa atividade de outras partes do sistema, como a tela de início, essa característica precisará ser considerada durante a análise da intent.
Verifique os dados recebidos com muita atenção, porque nunca se sabe o que outro app pode enviar. Por exemplo, o tipo MIME incorreto pode estar definido ou a imagem enviada pode ser grande demais. Além disso, lembre-se de processar dados binários em uma linha de execução separada, não na linha de execução principal (IU).
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... when { intent?.action == Intent.ACTION_SEND -> { if ("text/plain" == intent.type) { handleSendText(intent) // Handle text being sent } else if (intent.type?.startsWith("image/") == true) { handleSendImage(intent) // Handle single image being sent } } intent?.action == Intent.ACTION_SEND_MULTIPLE && 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 to reflect text being shared } } private fun handleSendImage(intent: Intent) { (intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let { // Update UI to reflect image being shared } } private fun handleSendMultipleImages(intent: Intent) { intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let { // Update UI to reflect multiple images being shared } }
Java
void onCreate (Bundle savedInstanceState) { ... // Get intent, action and MIME type Intent intent = getIntent(); String action = intent.getAction(); String type = intent.getType(); if (Intent.ACTION_SEND.equals(action) && type != null) { if ("text/plain".equals(type)) { handleSendText(intent); // Handle text being sent } else if (type.startsWith("image/")) { handleSendImage(intent); // Handle single image being sent } } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) { if (type.startsWith("image/")) { handleSendMultipleImages(intent); // Handle multiple images being sent } } else { // Handle other intents, such as being started from the home screen } ... } void handleSendText(Intent intent) { String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); if (sharedText != null) { // Update UI to reflect text being shared } } void handleSendImage(Intent intent) { Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM); if (imageUri != null) { // Update UI to reflect image being shared } } void handleSendMultipleImages(Intent intent) { ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); if (imageUris != null) { // Update UI to reflect multiple images being shared } }
A atualização da IU após o recebimento dos dados pode ser tão simples quanto preencher um EditText
ou mais complexa, como aplicar um filtro de foto interessante a uma imagem. Cabe ao seu app determinar o que acontece em seguida.
Garantir que os usuários reconheçam seu app
Seu app é representado pelo ícone e etiqueta correspondentes no Android Sharesheet e no resolvedor de intents. Ambos são definidos no manifesto. Você pode definir etiquetas de atividade ou de filtro de intent para fornecer mais contexto.
A partir do Android 10 (API de nível 29), o Android Sharesheet usará apenas os ícones definidos no manifesto da tag application
. Os ícones configurados nas tags intent-filter
e activity
serão ignorados.
Observação: os melhores alvos de compartilhamento não precisam de uma etiqueta e um ícone na atividade ou no filtro de intents relacionados. Apenas o nome e o ícone do app de destino deve ser suficiente para que os usuários entendam o que acontecerá no momento de compartilhamento.
Como disponibilizar alvos de compartilhamento direto
O Compartilhamento direto foi introduzido no Android 6.0 (API de nível 23), permitindo aos apps disponibilizar objetos ChooserTarget
por meio de um ChooserTargetService
. Os resultados foram recuperados de forma reativa sob demanda, levando a um carregamento lento de alvos.
No Android 10 (API de nível 29), as APIs Direct Share de ChooserTargetService
foram substituídas pela nova API Sharing Shortcuts. Em vez de recuperar os resultados de forma reativa sob demanda, a API Sharing Shortcuts permite que os apps publiquem alvos de compartilhamento direto com antecedência.
O mecanismo de compartilhamento direto ChooserTargetService
continuará funcionando, mas os alvos fornecidos dessa forma serão classificadas com menor prioridade do que qualquer outro alvo que use a API Sharing Shortcuts.
ShortcutManagerCompat é uma API AndroidX que oferece atalhos de compartilhamento de compatibilidade com versões anteriores da API DirectShare de ChooserTargetService
. Essa é a maneira preferencial de publicar atalhos de compartilhamento e ChooserTargets
. Veja as instruções abaixo.
Publicar alvos de compartilhamento direto
Você só pode usar atalhos dinâmicos para publicar alvos de compartilhamento direto. Siga as etapas abaixo para publicar alvos de compartilhamento direto usando a nova API.
- Declare elementos de alvos de compartilhamento no arquivo de recurso XML do app. Para ver detalhes, consulte Declarar um alvo de compartilhamento abaixo.
- 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 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 Sharing Shortcuts
ShortcutInfo.Builder
inclui métodos novos e aprimorados que oferecem mais informações sobre o alvo de compartilhamento:
setCategories()
- Esse não é um método novo, mas agora as categorias também são usadas para filtrar atalhos que podem processar intents ou ações de compartilhamento. Consulte Declarar um alvo de compartilhamento para ver mais detalhes. Esse campo é obrigatório para atalhos que se destinam ao uso 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.
Fazer com que um atalho seja de longa duração pode melhorar a classificação dele. Consulte Como conseguir a melhor qualificação para ver mais detalhes.
-
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 oferecidas em um ShareSheet. O acréscimo de informações de Person a um atalho é opcional, mas altamente recomendável se o alvo de compartilhamento for associado a uma pessoa. Alguns alvos de compartilhamento, como nuvens, não podem ser associados a uma pessoa.A inclusão de um objeto
Person
específico com uma chave exclusiva em um alvo de compartilhamento e notificações relacionadas pode melhorar sua classificação. Consulte Como conseguir a melhor qualificação para ver mais detalhes.Para um app de mensagens típico, é necessário publicar um atalho separado para cada contato, e o campo
Person
precisa conter as informações do contato. Se o alvo for associado a várias pessoas (como um bate-papo em grupo), adicione vários objetosPerson
a um único alvo de compartilhamento.Ao publicar um atalho para uma única pessoa, inclua o nome completo dela em
setLongLabel()
e qualquer abreviação do nome, como apelido ou primeiro nome, emsetShortLabel()
Para ver um exemplo de como publicar atalhos de compartilhamento, consulte o Exemplos de código de atalhos de compartilhamento (em inglês).
Como conseguir a melhor classificação
O Android Sharesheet mostra um número fixo de alvos de compartilhamento direto. Essas sugestões são ordenadas por classificação. É possível melhorar a classificação dos seus atalhos fazendo o seguinte:
- Verifique se todos os atalhos são únicos e nunca são reutilizados por alvos diferentes.
- Verifique se o atalho é de longa duração chamando
setLongLived(true)
. - Ofereça uma classificação que possa ser usada para comparar atalhos do seu app na ausência de dados de treinamento. Consulte
setRank()
. Uma classificação mais baixa significa que o atalho é mais importante.
Para melhorar ainda mais a classificação, é altamente recomendável que apps sociais realizem todos os procedimentos acima e:
- Forneçam objetos
Person
relevantes com uma chave configurada no seu atalho (consultesetPerson()
,setPersons()
esetKey()
). - Vinculem seu atalho a notificações relevantes da mesma pessoa ou grupo de pessoas (consulte
setShortcutId().
). O shortcutId pode ser atribuído a qualquer atalho publicado anteriormente comsetLongLived(true)
.
Para conseguir a melhor classificação possível, os apps sociais podem realizar todos os procedimentos acima e:
- nos objetos
Person
definidos, fornecer um URI válido para um contato associado no dispositivo. ConsultesetUri()
Veja um exemplo de atalho com todas as melhorias de classificação possíveis.
Kotlin
val person = Person.Builder() ... .setName(fullName) .setKey(staticPersonIdentifier) .setUri("tel:$phoneNumber") // alternatively "mailto:$email" or CONTENT_LOOKUP_URI .build() val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticPersonIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setPerson(person) .setLongLived(true) .setRank(personRank) .build()
Java
Person person = Person.Builder() ... .setName(fullName) .setKey(staticPersonIdentifier) .setUri("tel:"+phoneNumber) // alternatively "mailto:"+email or CONTENT_LOOKUP_URI .build(); ShortcutInfoCompat shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticPersonIdentifier) ... .setShortLabel(firstName) .setLongLabel(fullName) .setPerson(person) .setLongLived(true) .setRank(personRank) .build();
Kotlin
val notif = NotificationCompat.Builder(myContext, channelId) ... .setShortcutId(staticPersonIdentifier) .build()
Java
Notification notif = NotificationCompat.Builder(myContext, channelId) ... .setShortcutId(staticPersonIdentifier) .build();
Como oferecer imagens de atalhos
Para criar um atalho de compartilhamento, é necessário adicionar uma imagem por meio do setIcon()
.
Os atalhos de compartilhamento podem aparecer em todas as superfícies do sistema e ser remodelados. Para garantir que seu atalho tenha a aparência pretendida, providencie um bitmap adaptável por meio de IconCompat.createWithAdaptiveBitmap()
.
Bitmaps adaptáveis devem seguir as mesmas diretrizes e dimensões estabelecidas para ícones adaptáveis. A forma mais comum de conseguir isso é dimensionar o bitmap quadrado pretendido para 72 x 72 dp e centralizá-lo em uma tela transparente de 108 x 108 dp.
Não ofereça imagens mascaradas para uma forma específica. Por exemplo, antes do Android 10 (API de nível 29), era comum oferecer avatares de usuário para ChooserTarget
s de compartilhamento direto mascarados na forma de um círculo. Agora, o Android Sharesheet e outras superfícies de sistema no Android 10 definem a forma e o tema de imagens de atalho. O método preferido para fornecer atalhos de compartilhamento, por meio do ShortcutManagerCompat, moldará automaticamente ChooserTarget
s de compartilhamento direto de versões anteriores em um círculo.
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-targets>
contém informações sobre o tipo de dados compartilhados, as categorias correspondentes e a classe de alvo que processarão a 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 intents. 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 o atalho de compartilhamento no Android ShareSheet que corresponda ao exemplo de alvo de compartilhamento acima, o app receberá a 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á a intent criada durante o acréscimo do atalho de compartilhamento a ShortcutManagerCompat.
Por ser uma intent diferente, Intent.EXTRA_SHORTCUT_ID
não estará disponível, e você terá que transmitir o ID manualmente se precisar dele.
Como usar o AndroidX para oferecer atalhos de compartilhamento e ChooserTargets
Para trabalhar com a biblioteca de compatibilidade do AndroidX, o manifesto do app precisa conter o conjunto de metadados de serviço seletor de alvo e de filtros de intent.
Veja a API Direct Share atual ChooserTargetService
.
Como esse serviço já está declarado na biblioteca de compatibilidade, o usuário não precisa declará-lo no manifesto 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 de 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>
Perguntas frequentes sobre atalhos de compartilhamento
Quais são as principais diferenças entre a API Sharing Shortcuts atual e a API Direct Share ChooserTargetService
antiga?
A API Sharing Shortcuts usa um modelo push, enquanto a antiga API Direct Share usa o modelo pull. Isso torna o processo de recuperação de alvos de compartilhamento muito mais rápido 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 mudar (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 Sharing Shortcuts?
No Android 10 (API de nível 29) e versões mais recentes, o Android Sharesheet priorizará os alvos de compartilhamento fornecidos por meio do ShortcutManager usando a API Sharing Shortcuts. Assim, seus alvos de compartilhamento publicados podem ser ocultados por alvos de compartilhamento de outros apps e nunca aparecer quando forem compartilhados.
Posso usar ChooserTargetService
e as APIs Sharing Shortcuts e Direct Share 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 ShortcutManagerCompat
fornecidas.
A combinação de dois conjuntos de APIs pode provocar um comportamento indesejado/inesperado durante a recuperação de alvos de compartilhamento.
Qual é a diferença entre os atalhos publicados para alvos de compartilhamento e os atalhos da tela de início (uso normal de atalhos ao tocar em ícones de apps e mantê-los pressionados 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 quando o ícone do app for tocado e mantido pressionado. 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).