Suporte para emojis modernos

Testar o Compose
O Jetpack Compose é o kit de ferramentas de interface recomendado para Android. Aprenda a oferecer suporte a emojis no Compose.

O conjunto padrão de emojis é atualizado anualmente pelo Unicode, já que o uso de emojis está aumentando rapidamente para todos os tipos de apps.

Caso seu app mostre conteúdo da Internet ou ofereça entrada de texto, recomendamos que você ofereça suporte às fontes de emojis mais recentes. Caso contrário, emojis mais recentes poderão ser mostrados como um pequeno quadrado chamado de tofu (☐) ou outras sequências de emojis renderizadas incorretamente.

O Android 11 (nível 30 da API) e versões anteriores não podem atualizar a fonte de emojis. Portanto, os apps que as exibem nessas versões precisam ser atualizados manualmente.

Confira a seguir alguns exemplos de emojis modernos.

Exemplos Versão
🫠 🫱🏼‍🫲🏿 🫰🏽 14.0 (setembro de 2021)
😶‍🌫️ 🧔🏻‍♀️ 🧑🏿‍❤️‍🧑🏾 13.1 (setembro de 2020)
🥲 🥷🏿 🐻‍❄️ 13.0 (março de 2020)
🧑🏻‍🦰 🧑🏿‍🦯 👩🏻‍🤝‍👩🏼 12.1 (outubro de 2019)
🦩 🦻🏿 👩🏼‍🤝‍👩🏻 12.0 (fevereiro de 2019)

A biblioteca androidx.emoji2:emoji2 fornece compatibilidade mais simples com versões anteriores do Android. A biblioteca emoji2 é uma dependência da biblioteca AppCompat e não requer outra configuração para funcionar.

Suporte a emojis no Compose

A BOM de março de 2023 (Compose UI 1.4) oferece suporte à versão mais recente de emojis, incluindo compatibilidade com versões mais antigas do Android até a API 21. Esta página mostra como configurar emojis modernos no sistema de visualização. Consulte a página Emojis no Compose para saber mais.

Pré-requisitos

Para confirmar se o app mostra corretamente os novos emojis, inicie-o em um dispositivo com o Android 10 (nível 29 da API) ou versões anteriores. Esta página inclui emojis modernos que podem ser usados para testes.

Usar a AppCompat para oferecer suporte aos emojis mais recentes

A AppCompat 1.4 inclui suporte a emojis.

Para usar AppCompat com suporte a emojis, faça o seguinte:

  1. Confira se o módulo depende da biblioteca AppCompat versão 1.4.0-alpha01 ou mais recente.

    build.gradle
    
    // Ensure version is 1.4.0-alpha01 or higher.
    implementation "androidx.appcompat:appcompat.$appcompatVersion"
    
  2. Garanta que todas as atividades que mostram texto estendam a classe AppCompatActivity.

    Kotlin

    MyActivity.kt
    
    class MyActivity: AppCompatActivity {
    ...
    }

    Java

    MyActivity.java
    
    class MyActivity extends AppCompatActivity {
    ...
    }
  3. Teste sua integração iniciando o app em um dispositivo com o Android 10 ou versão anterior e mostrando a string de teste abaixo. Confira se todos os caracteres são renderizados corretamente.

    • 14.0: 🫠, 🫱🏼‍🫲🏿, 🫰🏽
    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Seu app mostra automaticamente os emojis compatíveis com versões anteriores em todos os dispositivos que oferecem um provedor de fontes para download compatível com emoji2, como dispositivos com tecnologia do Google Play Services.

Se o app usa a AppCompat, mas mostra um tofu (☐)

Em alguns casos, o app pode mostrar um tofu em vez do emoji adequado, mesmo que você adicione a biblioteca AppCompat. Veja a seguir as possíveis explicações e soluções.

Você está executando o app em um dispositivo atualizado recentemente ou em um novo emulador.

Limpe os dados do Google Play Services do app para limpar o armazenamento em cache de fontes que possa ocorrer durante a inicialização. Isso geralmente resolve o problema após algumas horas.

Para limpar os dados do app, faça o seguinte:

  1. Abra as Configurações no seu dispositivo Android.

  2. Toque em Apps e notificações.

  3. Toque em Mostrar todos os apps ou em Informações do app.

  4. Role pelos apps e toque em Google Play Services.

  5. Toque em Armazenamento e cache.

  6. Toque em Limpar cache.

Seu app não está usando uma classe da AppCompat relacionada a texto

Isso poderá acontecer se você não estender a AppCompatActivity ou se instanciar uma visualização em código, como TextView. Verifique o seguinte:

  • A atividade precisa estender a AppCompatActivity.
  • Se estiver criando a visualização em código, use a subclasse AppCompat correta.

Ao inflar o XML, a AppCompatActivity infla a AppCompatTextView automaticamente em vez da TextView, então você não precisa atualizar o XML.

O smartphone de teste não tem suporte a fontes para download

Verifique se DefaultEmojiCompatConfig.create retorna uma configuração não nula.

Um emulador em um nível de API anterior ainda não fez upgrade do Google Play Services

Ao usar um emulador em um nível de API anterior, talvez seja necessário atualizar o pacote do Google Play Services para que a emoji2 encontre o provedor de fontes. Para isso, faça login na Google Play Store no emulador.

Para verificar se uma versão compatível está instalada, faça o seguinte:

  1. Execute este comando:

    adb shell dumpsys package com.google.android.gms | grep version
    
  2. Confira se o versionCode é maior que 211200000.

Oferecer suporte a emojis sem a AppCompat

Se o app não puder incluir a AppCompat, a emoji2 poderá ser usada diretamente. Isso requer mais trabalho. Portanto, só use esse método se o app não puder usar AppCompat.

Para oferecer suporte a emojis sem a biblioteca AppCompat, faça o seguinte:

  1. No arquivo build.gradle do seu app, inclua emoji2 e emoji2-views.

    build.gradle
    
    def emojiVersion = "1.0.0-alpha03"
    implementation "androidx.emoji2:emoji2:$emojiVersion"
    implementation "androidx.emoji2:emoji2-views:$emojiVersion"
    

    O módulo emoji2-views fornece subclasses de TextView, Button e EditText que implementam a EmojiCompat. Não use em um app que inclua AppCompat, porque ele já implementa EmojiCompat.

  2. No XML e no código, sempre que você usar TextView, EditText ou Button, use EmojiTextView, EmojiEditText ou EmojiButton.

    activity_main.xml
    
    <androidx.emoji2.widget.EmojiTextView ... />
    <androidx.emoji2.widget.EmojiEditText ... />
    <androidx.emoji2.widget.EmojiButton ... />
    

    Ao incluir o módulo emoji2, o sistema usa o provedor padrão de fontes para download para carregar a fonte de emojis automaticamente logo após a inicialização do app. Nenhuma outra configuração é necessária.

  3. Para testar a integração, inicie o app em um dispositivo com Android 11 ou versão anterior e use as strings de teste a seguir. Confira se todos os caracteres são renderizados corretamente.

    • 14.0: 🫠, 🫱🏼‍🫲🏿, 🫰🏽
    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Usar a EmojiCompat sem widgets

A EmojiCompat usa EmojiSpan para renderizar imagens corretas. Portanto, ele precisa converter qualquer objeto CharSequence em um objeto Spanned com objetos EmojiSpan. A classe EmojiCompat oferece o método process() para converter CharSequences em instâncias de Spanned. Com esse método, é possível chamar process() em segundo plano e armazenar os resultados em cache, o que melhora o desempenho do app.

Kotlin

val processed = EmojiCompat.get().process("neutral face \uD83D\uDE10")

Java

CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");

Usar a EmojiCompat para editores de método de entrada

A classe EmojiCompat permite que os teclados renderizem os emojis com suporte do app com que estão interagindo. Editores de método de entrada (IMEs, na sigla em inglês) podem usar o método getEmojiMatch() para conferir se uma instância da EmojiCompat é capaz de renderizar um emoji. Esse método usa um objeto CharSequence de um emoji e retorna true se a EmojiCompat puder detectar e renderizar o emoji.

O teclado também pode conferir a versão da EmojiCompat que é compatível com o app para determinar qual emoji renderizar na paleta. Para conferir a versão, se disponível, o teclado pode procurar as seguintes teclas no pacote EditorInfo.extras:

  • EDITOR_INFO_METAVERSION_KEY: representa a versão dos metadados de emoji que o app usa. Se essa tecla não existe, o app não está usando a EmojiCompat.
  • EDITOR_INFO_REPLACE_ALL_KEY: se a chave existir e estiver definida como true, o app vai configurar EmojiCompat para substituir todos os emojis, mesmo que estejam presentes no sistema.

Saiba mais sobre como configurar uma instância da EmojiCompat.

Usar emojis em visualizações personalizadas

Se o app tiver visualizações personalizadas que são subclasses diretas ou indiretas de TextView, por exemplo, Button, Switch ou EditText, e essas visualizações puderem mostrar conteúdo gerado pelo usuário, elas precisarão implementar EmojiCompat.

O processo varia dependendo se o app usa ou não a biblioteca AppCompat.

Adicionar visualizações personalizadas para apps com a AppCompat

Se o app usa AppCompat, estenda a implementação de AppCompat em vez da implementação da plataforma. Use a tabela a seguir como guia para estender as visualizações em AppCompat:

Em vez de estender… Estenda
TextView AppCompatTextView
EditText AppCompatEditText
ToggleButton AppCompatToggleButton
Switch SwitchCompat
Button AppCompatButton
CheckedTextView AppCompatCheckedTextView
RadioButton AppCompatRadioButton
CheckBox AppCompatCheckBox
AutoCompleteTextView AppCompatAutoCompleteTextView
MultiAutoCompleteTextView AppCompatMultiAutoCompleteTextView

Adicionar visualizações personalizadas para apps sem a AppCompat

Caso seu app não use a AppCompat, use os auxiliares de integração de visualização no módulo emoji2-views-helper que foram projetados para uso em visualizações personalizadas. Esses são os auxiliares que a biblioteca AppCompat usa para implementar o suporte a emojis.

Conclua as etapas a seguir para oferecer suporte a visualizações personalizadas para apps que não usam a AppCompat.

  1. Adicione a biblioteca emoji2-views-helper:

    implementation "androidx.emoji2:emoji2-views-helper:$emojiVersion"
    
  2. Siga as instruções para incluir EmojiTextViewHelper ou EmojiEditTextHelper nas visualizações personalizadas do app.

  3. Para testar a integração, inicie o app em um dispositivo com Android 10 ou versão anterior e use a string de teste a seguir. Confira se todos os caracteres são renderizados corretamente.

    • 14.0: 🫠, 🫱🏼‍🫲🏿, 🫰🏽
    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Recursos opcionais para lidar com a emoji2

Depois de incluir a biblioteca emoji2 no app, é possível adicionar os recursos opcionais descritos nesta seção.

Configurar a emoji2 para usar uma fonte ou um provedor de fontes disponíveis para download diferente

Para configurar a emoji2 para usar uma fonte ou um provedor de fontes disponíveis para download diferente, faça o seguinte:

  1. Desative a EmojiCompatInitializer adicionando o seguinte ao manifesto:

    <provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer"
               tools:node="remove" />
    </provider>
  2. Siga uma das seguintes ações:

Modificar o comportamento da EmojiCompat

Você pode usar uma instância de EmojiCompat.Config para modificar o comportamento de EmojiCompat.

A opção de configuração mais importante é setMetadataLoadStrategy(), que controla quando a EmojiCompat carrega a fonte. O carregamento de fonte começa assim que EmojiCompat.load() é chamado, e isso aciona todos os downloads necessários. O sistema cria uma linha de execução para o download de fontes, a menos que seu app ofereça uma.

LOAD_STRATEGY_MANUAL permite controlar quando EmojiCompat.load() é chamado, e LOAD_STRATEGY_DEFAULT inicia o carregamento de forma síncrona na chamada para EmojiCompat.init().

A maioria dos apps usa LOAD_STRATEGY_MANUAL para controlar a linha de execução e o tempo de carregamento da fonte. Seu app precisa adiar até a primeira tela ser exibida para evitar a introdução de latência de inicialização. A EmojiCompatInitializer segue essa prática e adia o carregamento da fonte de emojis até que a primeira tela seja retomada.

Use os seguintes métodos da classe base para definir outros aspectos da configuração:

  • setReplaceAll(): determina se EmojiCompat substitui todos os emojis que encontra por instâncias de EmojiSpan. Por padrão, quando a EmojiCompat infere que o sistema pode renderizar um emoji, ela não substitui esse emoji. Quando definido como true, EmojiCompat substitui todos os emojis por objetos EmojiSpan.
  • setEmojiSpanIndicatorEnabled(): indica se a EmojiCompat substitui um emoji por um objeto EmojiSpan. Quando definido como true, EmojiCompat desenha um plano de fundo para a EmojiSpan. Esse método é usado principalmente para fins de depuração.
  • setEmojiSpanIndicatorColor: define a cor para indicar um EmojiSpan. O valor padrão é GREEN.
  • registerInitCallback(): informa um app sobre o estado de inicialização da EmojiCompat.

Adicionar listeners de inicialização

As classes EmojiCompat e EmojiCompat.Config fornecem os métodos registerInitCallback() e unregisterInitCallback() para registrar e cancelar o registro de callbacks de inicialização. Seu app usa esses callbacks para aguardar até que a EmojiCompat seja inicializada antes de você processar o emoji em uma linha de execução em segundo plano ou em uma visualização personalizada.

Para usar esses métodos, crie uma instância da classe EmojiCompat.InitCallback. Chame esses métodos e transmita a instância da classe EmojiCompat.InitCallback. Quando a inicialização for bem-sucedida, a classe EmojiCompat chamará o método onInitialized(). Se a biblioteca não for inicializada, a classe EmojiCompat chamará o método onFailed().

Para conferir o estado de inicialização a qualquer momento, chame o método getLoadState(). Esse método retorna um dos seguintes valores: LOAD_STATE_LOADING, LOAD_STATE_SUCCEEDED ou LOAD_STATE_FAILED.

Suporte para fontes incluídas na emoji2

Você pode usar o artefato emoji2-bundled para incluir uma fonte de emojis no seu app. No entanto, como a fonte NotoColorEmoji tem mais de 10 MB, recomendamos que o app use fontes para download sempre que possível. O artefato emoji2-bundled é destinado a apps em dispositivos não compatíveis com fontes para download.

Para usar o artefato emoji2-bundled, faça o seguinte:

  1. Inclua os artefatos emoji2-bundled e emoji2:

    implementation "androidx.emoji2:emoji2:$emojiVersion"
    implementation "androidx.emoji2:emoji2-bundled:$emojiVersion"
    
  2. Configure emoji2 para usar a configuração agrupada:

    Kotlin

    EmojiCompat.init(BundledEmojiCompatConfig(context))

    Java

    EmojiCompat.init(new BundledEmojiCompatConfig(context));
  3. Teste a integração seguindo as etapas anteriores para incluir emojicompat com ou sem AppCompat. Verifique se a string de teste é exibida corretamente.

    • 14.0: 🫠, 🫱🏼‍🫲🏿, 🫰🏽
    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Impacto da configuração automática da EmojiCompat

O sistema aplica a configuração padrão usando a biblioteca de inicialização, EmojiCompatInitializer e DefaultEmojiCompatConfig.

Depois que a primeira atividade é retomada no app, o inicializador programa o carregamento da fonte de emojis. Esse breve atraso permite que o app mostre o conteúdo inicial sem nenhuma possível latência devido ao carregamento de fontes em uma linha de execução em segundo plano.

O DefaultEmojiCompatConfig procura um provedor de fontes para download instalado pelo sistema que implemente a interface EmojiCompat, como o Google Play Services. Em dispositivos com o Google Play Services, a fonte é carregada usando esse serviço.

O inicializador cria uma linha de execução em segundo plano para carregar a fonte do emoji, e o download da fonte pode levar até 10 segundos antes de expirar. Depois do download, a inicialização da EmojiCompat leva aproximadamente 150 milissegundos em uma linha de execução em segundo plano.

Adie a inicialização da EmojiCompat, mesmo que você desative a EmojiCompatInitializer. Se você configurar o EmojiCompat manualmente, chame EmojiCompat.load() depois que ele exibir a primeira tela do app para evitar a contenção em segundo plano com o carregamento da primeira tela.

Após o carregamento, o EmojiCompat usa cerca de 300 KB de RAM para armazenar os metadados do emoji.