Inserção de conteúdo avançado

Figura 1. A API unificada oferece um único local para processar o conteúdo recebido, independentemente do mecanismo de IU específico, como conteúdo originado da ação de colar após tocar e manter pressionado ou usando o recurso de arrastar e soltar.

Os usuários gostam de 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údos avançados pelos apps, estamos lançando uma nova API unificada, que permite aceitar conteúdos de qualquer fonte: área de transferência, teclado ou recurso de arrastar e soltar.

É possível anexar uma nova 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 oferecer compatibilidade com versões anteriores do Android, também adicionamos a nova API para o AndroidX (disponível no Core 1.5.0-beta1 e no Appcompat 1.3.0-beta-01), cujo uso é recomendado ao implementar esse recurso.

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:

Figura 2. Anteriormente, o app precisava implementar uma API diferente para cada mecanismo de IU para a inserção de conteúdo.

A API 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 aplicativo e deixar a plataforma cuidar do restante:

Figura 3. A nova API unificada permite implementar uma única API compatível com todos os mecanismos de IU.

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 nova API é uma interface de listener com um único método, OnReceiveContentListener. Para oferecer compatibilidade com versões anteriores da plataforma Android, recomendamos usar a interface OnReceiveContentListener correspondente da 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) {
             ClipData clip = uriContent.getClip();
             for (int i = 0; i < clip.getItemCount(); i++) {
                 Uri uri = clip.getItemAt(i).getUri();
                 // App-specific logic to handle the URI ...
             }
         }
         // 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 no construtor do elemento da IU do 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());
     }
}

Comparação com a API de imagem de teclado

Imagine a API de conteúdo unificado como a próxima versão da API de imagem do teclado existente. A nova API é 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