Compatibilidad con emojis

La biblioteca de compatibilidad EmojiCompat tiene como objetivo mantener los dispositivos Android actualizados con los últimos emojis. Evita que tu app muestre caracteres de emojis faltantes en forma de ☐, lo que indica que tu dispositivo no tiene una fuente para mostrar el texto. Gracias al uso de la biblioteca de compatibilidad EmojiCompat, los usuarios de tu app no necesitan esperar a que las actualizaciones del SO Android obtengan los últimos emojis.

Dispositivos que muestran emojis
Figura 1: Comparación de emojis

Consulta los siguientes recursos relacionados:

  • App de ejemplo de compatibilidad de emojis Java | Kotlin

¿Cómo funciona EmojiCompat?

La biblioteca de compatibilidad EmojiCompat proporciona clases para implementar la retrocompatibilidad de emojis en dispositivos con Android 4.4 (nivel de API 19) y versiones posteriores. Puedes configurar EmojiCompat con fuentes empaquetadas o descargables. Para obtener más información sobre la configuración, consulta las siguientes secciones:

EmojiCompat identifica emojis para un determinado CharSequence; los sustituye con EmojiSpans si es necesario; y, por último, renderiza los glifos emoji. En la Figura 2, se demuestra este proceso.

Proceso de EmojiCompat
Figura 2: Proceso de EmojiCompat

Cómo configurar fuentes descargables

La configuración de fuentes descargables usa esa función de la biblioteca de compatibilidad a fin de descargar una fuente de emojis. También actualiza los metadatos de emojis que la biblioteca de compatibilidad EmojiCompat necesita para mantenerse actualizada con las últimas versiones de la especificación Unicode.

Cómo agregar la dependencia de biblioteca de compatibilidad

Para usar la biblioteca de compatibilidad EmojiCompat, debes modificar las dependencias de ruta de clase del proyecto de tu app en el entorno de desarrollo.

Para agregar una biblioteca de compatibilidad al proyecto de tu aplicación:

  1. Abre el archivo build.gradle de tu aplicación.
  2. Agrega la biblioteca de compatibilidad a la sección dependencies.

Groovy

dependencies {
    ...
    implementation "com.android.support:support-emoji:28.0.0"
}

Kotlin

dependencies {
    ...
    implementation("com.android.support:support-emoji:28.0.0")
}

Cómo inicializar la configuración de fuentes descargables

Debes inicializar EmojiCompat para cargar los metadatos y el tipo de letra. Como el proceso de inicialización puede tardar un poco, se ejecuta en un subproceso en segundo plano.

A fin de inicializar EmojiCompat con la configuración de fuentes descargables, sigue estos pasos:

  1. Crea una instancia de la clase FontRequest y proporciona la autoridad del proveedor de fuentes, el paquete del proveedor de fuentes, la consulta de fuentes y una lista de conjuntos de hashes para el certificado. Si quieres obtener más información sobre FontRequest, consulta la sección Cómo usar la función Fuentes para descargar de forma programática en la documentación Fuentes para descargar.
  2. Crea una instancia de FontRequestEmojiCompatConfig y proporciona instancias de Context y FontRequest.
  3. Inicializa EmojiCompat llamando al método init() y pasa la instancia de FontRequestEmojiCompatConfig.
  4. Kotlin

    class MyApplication : Application() {
    
        override fun onCreate() {
            super.onCreate()
            val fontRequest = FontRequest(
                    "com.example.fontprovider",
                    "com.example",
                    "emoji compat Font Query",
                    CERTIFICATES
            )
            val config = FontRequestEmojiCompatConfig(this, fontRequest)
            EmojiCompat.init(config)
        }
    }
    

    Java

    public class MyApplication extends Application {
      @Override
       public void onCreate() {
         super.onCreate();
         FontRequest fontRequest = new FontRequest(
           "com.example.fontprovider",
           "com.example",
           "emoji compat Font Query",
           CERTIFICATES);
         EmojiCompat.Config config = new FontRequestEmojiCompatConfig(this, fontRequest);
         EmojiCompat.init(config);
       }
    }
    
  5. Usa widgets EmojiCompat en los XML de diseño. Si estás usando AppCompat, consulta la sección Cómo usar los widgets EmojiCompat con AppCompat.
  6. <android.support.text.emoji.widget.EmojiTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
    
    <android.support.text.emoji.widget.EmojiEditText
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
    
    <android.support.text.emoji.widget.EmojiButton
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
    

Si quieres obtener más información para configurar EmojiCompat con la configuración de fuentes descargables, ve a la app de muestra de compatibilidad de emojis Java | Kotlin.

Componentes de la biblioteca

Componentes de la biblioteca en el proceso de EmojiCompat
Figura 3: Componentes de la biblioteca en el proceso de EmojiCompat
Widgets: EmojiEditText, EmojiTextView, EmojiButton
Implementaciones de widgets predeterminadas para usar EmojiCompat con TextView, EditText y Button.
EmojiCompat
Superficie pública principal de la biblioteca de compatibilidad. Realiza todas las llamadas externas y coordina con las otras partes del sistema.
EmojiCompat.Config
Configura la instancia singleton que se creará.
EmojiSpan
Una subclase ReplacementSpan que reemplaza el carácter (secuencias) y renderiza el glifo.
Fuente EmojiCompat
EmojiCompat usa una fuente para mostrar emojis. Esta fuente es una versión modificada de la fuente de emojis para Android. La fuente se modifica de la siguiente manera:
  • A fin de ofrecer retrocompatibilidad para renderizar emojis, todos los caracteres de emojis se representan con un único punto de código Unicode en el Área de uso privado complementario A de Unicode que comienza con U+F0001.
  • Los metadatos de emojis adicionales se insertan en un formato binario en la fuente y se analizan en el tiempo de ejecución mediante EmojiCompat. Los datos se incorporan en la tabla meta de la fuente, con la etiqueta privada Emji.

Opciones de configuración

Puedes usar la instancia EmojiCompat para modificar el comportamiento de EmojiCompat. Puedes usar los siguientes métodos de la clase base a fin de establecer la configuración:

Kotlin

val config = FontRequestEmojiCompatConfig(...)
        .setReplaceAll(true)
        .setEmojiSpanIndicatorEnabled(true)
        .setEmojiSpanIndicatorColor(Color.GREEN)
        .registerInitCallback(object: EmojiCompat.InitCallback() {
            ...
        })

Java

EmojiCompat.Config config = new FontRequestEmojiCompatConfig(...)
       .setReplaceAll(true)
       .setEmojiSpanIndicatorEnabled(true)
       .setEmojiSpanIndicatorColor(Color.GREEN)
       .registerInitCallback(new InitCallback() {...})

Cómo agregar objetos de escucha de inicialización

EmojiCompat y las clases EmojiCompat proporcionan métodos registerInitCallback() y unregisterInitCallback() para registrar una devolución de llamada de inicialización. A fin de usar estos métodos, crea una instancia de la clase EmojiCompat.InitCallback. Llama a estos métodos y pasa la instancia de la clase EmojiCompat.InitCallback. Cuando la inicialización de la biblioteca de compatibilidad EmojiCompat es correcta, la clase EmojiCompat llama al método onInitialized(). Si la biblioteca no se inicializa, la clase EmojiCompat llama al método onFailed().

Para comprobar el estado de inicialización en cualquier momento, llama al método getLoadState(). Esto muestra uno de los siguientes valores: LOAD_STATE_LOADING, LOAD_STATE_SUCCEEDED o LOAD_STATE_FAILED.

Cómo usar EmojiCompat con widgets de AppCompat

Si estás usando AppCompat widgets, puedes usar widgets EmojiCompat que se extienden desde AppCompat widgets.

  1. Agrega la biblioteca de compatibilidad a la sección de dependencias.

    Groovy

    dependencies {
        ...
        implementation "com.android.support:support-emoji-bundled:$version"
    }
    

    Kotlin

          dependencies {
              implementation("com.android.support:support-emoji-appcompat:$version")
          }
          

    Groovy

          dependencies {
              implementation "com.android.support:support-emoji-appcompat:$version"
          }
          
  2. Usa widgets AppCompat Widget de EmojiCompat en los XML de diseño.
  3. <android.support.text.emoji.widget.EmojiAppCompatTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
    
    <android.support.text.emoji.widget.EmojiAppCompatEditText
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
    
    <android.support.text.emoji.widget.EmojiAppCompatButton
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"/>
    

Cómo configurar fuentes empaquetadas

La biblioteca de compatibilidad EmojiCompat también está disponible en una versión de fuentes empaquetadas. Este paquete incluye la fuente con los metadatos incorporados. El paquete también incluye una BundledEmojiCompatConfig que usa el AssetManager para cargar metadatos y fuentes.

Nota: El tamaño de la fuente está en varios megabytes.

Cómo agregar la dependencia de biblioteca de compatibilidad

Para usar la biblioteca de compatibilidad EmojiCompat con la configuración de fuentes empaquetadas, debes modificar las dependencias de ruta de clase del proyecto de tu app en el entorno de desarrollo.

Para agregar una biblioteca de compatibilidad al proyecto de tu aplicación:

  1. Abre el archivo build.gradle de tu aplicación.
  2. Agrega la biblioteca de compatibilidad a la sección dependencies.

Groovy

dependencies {
    ...
    implementation "com.android.support:support-emoji:28.0.0"
}

Kotlin

dependencies {
    ...
    implementation("com.android.support:support-emoji:28.0.0")
}

Cómo usar fuentes empaquetadas para configurar EmojiCompat

Para usar fuentes empaquetadas a fin de configurar EmojiCompat, realiza los siguientes pasos:

  1. Usa BundledEmojiCompatConfig a fin de crear una instancia de EmojiCompat y proporciona una instancia de Context.
  2. Llama al método init() para inicializar EmojiCompat y pasa la instancia de BundledEmojiCompatConfig.

Kotlin

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
        val config = BundledEmojiCompatConfig(this)
        EmojiCompat.init(config)
    }
}

Java

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        EmojiCompat.Config config = new BundledEmojiCompatConfig(this);
        EmojiCompat.init(config);
        ...
    }
}

Cómo usar EmojiCompat sin widgets

EmojiCompat usa EmojiSpan para renderizar las imágenes correctas. Por lo tanto, tiene que convertir cualquier CharSequence dado en instancias Spanned con EmojiSpans. La clase EmojiCompat proporciona un método para convertir CharSequences en instancias Spanned con EmojiSpans. Con este método, puedes procesar y almacenar en caché las instancias procesadas en vez de la string sin procesar, lo que mejora el rendimiento de tu aplicación.

Kotlin

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

Java

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

Cómo usar EmojiCompat para los IME

Con la biblioteca de compatibilidad EmojiCompat, los teclados pueden renderizar los emojis compatibles con la aplicación con la que están interactuando. Los IME pueden usar el método hasEmojiGlyph() para verificar si EmojiCompat es capaz de renderizar un emoji. Este método toma un CharSequence de un emoji y muestra true si EmojiCompat puede detectarlo y renderizarlo.

El teclado también puede verificar la versión de la biblioteca de compatibilidad EmojiCompat que admite la app a fin de determinar qué emojis debe renderizar en la paleta. Para verificar la versión, si está disponible, el teclado debe comprobar si las siguientes claves existen en el paquete EditorInfo.extras:

Después de recibir las claves del paquete EditorInfo.extras, el teclado puede usar el método hasEmojiGlyph(), donde metadataVersion es el valor de EDITOR_INFO_METAVERSION_KEY, para verificar si la app puede renderizar un emoji específico.

Cómo usar EmojiCompat con widgets personalizados

Siempre puedes usar el método process() para preprocesar el CharSequence en tu app y agregarlo a cualquier widget que pueda renderizar instancias Spanned, por ejemplo, TextView. Además, EmojiCompat proporciona las siguientes clases auxiliares de widgets a fin de que puedas enriquecer tus widgets personalizados con compatibilidad con emojis sin mucho esfuerzo.

Ejemplo de TextView

Kotlin

class MyTextView(context: Context) : AppCompatTextView(context) {

    private val emojiTextViewHelper: EmojiTextViewHelper by lazy(LazyThreadSafetyMode.NONE) {
        EmojiTextViewHelper(this).apply {
            updateTransformationMethod()
        }
    }

    override fun setFilters(filters: Array<InputFilter>) {
        super.setFilters(emojiTextViewHelper.getFilters(filters))
    }

    override fun setAllCaps(allCaps: Boolean) {
        super.setAllCaps(allCaps)
        emojiTextViewHelper.setAllCaps(allCaps)
    }
}

Java

public class MyTextView extends AppCompatTextView {
   ...
   public MyTextView(Context context) {
       super(context);
       init();
   }
   ...
   private void init() {
       getEmojiTextViewHelper().updateTransformationMethod();
   }

   @Override
   public void setFilters(InputFilter[] filters) {
       super.setFilters(getEmojiTextViewHelper().getFilters(filters));
   }

   @Override
   public void setAllCaps(boolean allCaps) {
       super.setAllCaps(allCaps);
       getEmojiTextViewHelper().setAllCaps(allCaps);
   }

   private EmojiTextViewHelper getEmojiTextViewHelper() {
       ...
   }
}
Ejemplo de EditText

Kotlin

class MyEditText(context: Context) : AppCompatEditText(context) {

    private val emojiEditTextHelper: EmojiEditTextHelper by lazy(LazyThreadSafetyMode.NONE) {
        EmojiEditTextHelper(this).also {
            super.setKeyListener(it.getKeyListener(keyListener))
        }
    }

    override fun setKeyListener(input: KeyListener?) {
        input?.also {
            super.setKeyListener(emojiEditTextHelper.getKeyListener(it))
        }
    }

    override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
        val inputConnection: InputConnection = super.onCreateInputConnection(outAttrs)
        return emojiEditTextHelper.onCreateInputConnection(
                inputConnection,
                outAttrs
        ) as InputConnection
    }
}

Java

public class MyEditText extends AppCompatEditText {
   ...
   public MyEditText(Context context) {
       super(context);
       init();
   }
   ...
   private void init() {
       super.setKeyListener(getEmojiEditTextHelper().getKeyListener(getKeyListener()));
   }

   @Override
   public void setKeyListener(android.text.method.KeyListener keyListener) {
       super.setKeyListener(getEmojiEditTextHelper().getKeyListener(keyListener));
   }

   @Override
   public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
       InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
       return getEmojiEditTextHelper().onCreateInputConnection(inputConnection, outAttrs);
   }

   private EmojiEditTextHelper getEmojiEditTextHelper() {
       ...
   }
}

Preguntas frecuentes

  • ¿Cómo inicio la descarga de fuentes?
  • Las fuentes de emojis se descargan en la primera solicitud si no existen en el dispositivo. La programación de descarga es transparente para la app.

  • ¿Cuánto tiempo se necesita para inicializar?
  • Después de descargar la fuente, la inicialización de EmojiCompat tarda aproximadamente 150 milisegundos.

  • ¿Cuánta memoria usa la biblioteca de compatibilidad EmojiCompat?
  • Actualmente, la estructura de datos para encontrar los emojis se carga en la memoria de la app y usa alrededor de 200 KB.

  • ¿Puedo usar EmojiCompat para un TextView personalizado?
  • Sí. EmojiCompat proporciona clases auxiliares para widgets personalizados. También es posible preprocesar una string determinada y convertirla en Spanned. Para obtener más información sobre las clases auxiliares de widget, consulta la sección Cómo usar EmojiCompat con widgets personalizados.

  • ¿Qué sucede si agrego widgets en los XML de diseño en dispositivos con Android 4.4 (nivel de API 19) o versiones anteriores?
  • Puedes incluir la biblioteca de compatibilidad EmojiCompat o sus widgets en tus aplicaciones compatibles con dispositivos que ejecutan Android 4.4 (nivel de API 19) o versiones anteriores. Sin embargo, si un dispositivo ejecuta una versión de Android anterior a la del nivel de API 19, EmojiCompat y sus widgets estarán en un estado "sin operación". Esto significa que EmojiTextView se comporta exactamente como una TextView normal. La instancia EmojiCompat entra de inmediato en un estado LOAD_STATE_SUCCEEDED cuando llamas al método init().

Recursos adicionales

Para obtener más información sobre el uso de la biblioteca EmojiCompat, mira el video EmojiCompat.