
Os usuários adoram imagens, vídeos e outros conteúdos expressivos, mas inserir e mover esses conteúdos em apps nem sempre é fácil. Para simplificar o recebimento de conteúdo avançado pelos apps, o Android 12 (API de nível 31) introduziu uma API unificada que permite que os apps aceitem conteúdo de qualquer fonte: área de transferência, teclado e recurso de arrastar e soltar.
É possível anexar uma interface, OnReceiveContentListener
,
aos componentes de IU e receber um callback quando o conteúdo for inserido usando
qualquer mecanismo. O callback passa a ser o único local em que o código processa
o recebimento de todos os conteúdos, desde textos simples e estilizados até marcações, imagens, vídeos,
arquivos de áudio e outros.
Para compatibilidade com versões anteriores do Android, essa API também está disponível no AndroidX (a partir do Core 1.7 e Appcompat 1.4) e recomendamos que você a use ao implementar essa funcionalidade.
Visão geral
Com as APIs existentes, cada mecanismo de IU tem uma API correspondente, como o menu exibido após tocar e manter pressionado ou o recurso arrastar e soltar. Isso significa que você precisa integrar cada API separadamente, adicionando um código semelhante para cada mecanismo que insere conteúdo:
A API OnReceiveContentListener
unificada consolida esses diferentes caminhos de código,
criando uma única API para implementação. Assim, você pode se concentrar na lógica
específica do app e deixar a plataforma cuidar do restante:
Essa abordagem também significa que, quando novas maneiras de inserir conteúdo forem adicionadas à plataforma, não será necessário fazer outras mudanças no código para oferecer compatibilidade no app. Caso seu app precise implementar uma personalização completa para um caso de uso específico, você ainda poderá usar as APIs existentes, que continuarão a funcionar da mesma maneira.
Implementação
A API é uma interface de listener com um único método, o
OnReceiveContentListener
.
Para oferecer compatibilidade com versões anteriores da plataforma Android, recomendamos o uso
da interface
OnReceiveContentListener
correspondente na biblioteca AndroidX Core.
Para usar a API, implemente o listener especificando os tipos de conteúdo que o app pode processar:
public class MyReceiver implements OnReceiveContentListener {
public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
// ...
Depois de especificar todos os tipos MIME de conteúdo compatíveis com o app, implemente o restante do listener:
public class MyReceiver implements OnReceiveContentListener {
public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
@Override
public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) {
Pair<ContentInfoCompat, ContentInfoCompat> split = contentInfo.partition(
item -> item.getUri() != null);
ContentInfo uriContent = split.first;
ContentInfo remaining = split.second;
if (uriContent != null) {
// App-specific logic to handle the URI(s) in uriContent...
}
// Return anything that your app didn't handle. This preserves the default platform
// behavior for text and anything else that you aren't implementing custom handling for.
return remaining;
}
}
Caso o app já seja compatível com o compartilhamento com intents, você pode reutilizar a lógica específica do app para processar URIs de conteúdo. Retorne todos os dados restantes para delegar o processamento desses dados à plataforma.
Depois de implementar o listener, defina-o nos elementos de IU adequados no app:
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
AppCompatEditText myInput = findViewById(R.id.my_input);
ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver());
}
}
Permissões de URI
As permissões de leitura são concedidas e liberadas automaticamente pela plataforma para todos os
URIs de conteúdo
no payload transmitidos ao OnReceiveContentListener
.
Geralmente, o app precisa processar URIs de conteúdo em um serviço ou uma atividade. Para um processamento de longa duração, use o WorkManager. Ao fazer essa implementação, estenda as permissões para o serviço ou a atividade de destino transmitindo o conteúdo com Intent.setClipData e configurando a sinalizaçãoFLAG_GRANT_READ_URI_PERMISSION.
Como alternativa, você pode usar uma linha de execução em segundo plano no contexto atual para
processar o conteúdo. Nesse caso, é necessário manter uma referência ao objeto
payload
recebido pelo listener para garantir que as permissões não sejam
revogadas prematuramente pela plataforma.
Visualizações padrão
Caso seu app use uma subclasse View
personalizada, verifique
se o OnReceiveContentListener
não é ignorado.
Se a classe View
substituir o método
onCreateInputConnection
,
use a API Jetpack
InputConnectionCompat.createWrapper
para configurar a InputConnection
.
Se a classe View
substituir o método
onTextContextMenuItem
,
delegue a Super quando o item do menu for
R.id.paste
ou
R.id.pasteAsPlainText
.
Comparação com a API de imagem de teclado
Pense na API OnReceiveContentListener
como a próxima versão da
API de imagem do teclado existente. Essa API
unificada é compatível com a funcionalidade da API de imagem do teclado e com alguns
outros recursos. A compatibilidade com dispositivos e recursos varia de acordo com o uso
da biblioteca do Jetpack ou das APIs nativas do SDK do Android.
Recursos compatíveis e níveis da API: Jetpack
Ação ou recurso | Compatível com a API de imagem do teclado | Compatível com a API unificada |
---|---|---|
Inserir conteúdo pelo teclado | Sim (nível 13 da API e versões mais recentes) | Sim (nível 13 da API e versões mais recentes) |
Inserir conteúdo colando-o do menu de tocar e manter pressionado | Não | Sim |
Inserir conteúdo usando o recurso de arrastar e soltar | Não | Sim (nível 24 da API e versões mais recentes) |
Recursos compatíveis e níveis da API: APIs nativas
Ação ou recurso | Compatível com a API de imagem do teclado | Compatível com a API unificada |
---|---|---|
Inserir conteúdo pelo teclado | Sim (nível 25 da API e versões mais recentes) | Sim (Android 12 ou versões mais recentes) |
Inserir conteúdo colando-o do menu de tocar e manter pressionado | Não | |
Inserir conteúdo usando o recurso de arrastar e soltar | Não |