The EmojiCompat
support library aims to
keep Android devices up to date with the latest emoji. It prevents your app
from showing missing emoji characters in the form of ☐, which
indicates that your device does not have a font to display the text. By
using the EmojiCompat
support library,
your app users do not need to wait for Android OS updates to get the latest
emoji.

Refer to the following related resources:
How does EmojiCompat work?
The EmojiCompat
support library provides
classes to implement backward-compatible emoji support on devices running
Android 4.4 (API level 19) and higher. You can configure
EmojiCompat
with either bundled or
downloadable fonts. For more information about configuration, refer to the
following sections:
EmojiCompat
identifies emoji for a given
CharSequence
, replaces them with
EmojiSpans
, if required, and
finally renders the emoji glyphs. Figure 2 demonstrates the process.

Downloadable fonts configuration
The downloadable fonts configuration uses the Downloadable Fonts support
library feature to download an emoji font. It also updates the necessary
emoji metadata that the EmojiCompat
support library needs to keep up with the latest versions of the Unicode
specification.
Adding support library dependency
To use the EmojiCompat
support library,
you must modify your app project's classpath dependencies within your
development environment.
To add a support library to your application project:
- Open the
build.gradle
file of your application. - Add the support library to the
dependencies
section.
dependencies { ... implementation "androidx.emoji:emoji:28.0.0" }
dependencies { ... implementation("androidx.emoji:emoji:28.0.0") }
Initializing the downloadable font configuration
You need to initialize EmojiCompat
to
load the metadata and the typeface. Since initialization can take some time,
the initialization process runs on a background thread.
To initialize EmojiCompat
with the
downloadable font configuration, perform the following steps:
- Create an instance of the
FontRequest
class and provide the font provider authority, the font provider package, the font query, and a list of sets of hashes for the certificate. For more information aboutFontRequest
, refer to the Using Downloadable Fonts programmatically section in the Downloadable Fonts documentation. - Create an instance of
FontRequestEmojiCompatConfig
and provide instances ofContext
andFontRequest
. - Initialize
EmojiCompat
by calling theinit()
method and pass the instance ofFontRequestEmojiCompatConfig
. - Use
EmojiCompat
widgets in layout XMLs. If you are usingAppCompat
, refer to the Using EmojiCompat widgets with AppCompat section.
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) } }
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); } }
<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"/>
For more information about how to configure
EmojiCompat
with the downloadable font
configuration, go to Emoji Compatibility sample app
Java
| Kotlin.
Library components

- Widgets:
EmojiEditText
,EmojiTextView
,EmojiButton
- Default widget implementations to use
EmojiCompat
withTextView
,EditText
, andButton
. EmojiCompat
- Main public surface for the support library. It performs all the external calls and coordinates with the other parts of the system.
EmojiCompat.Config
- Configures the singleton instance to be created.
EmojiSpan
- A
ReplacementSpan
subclass that replaces the character (sequences) and renders the glyph. EmojiCompat
FontEmojiCompat
uses a font to display emoji. This font is a modified version of the Android Emoji font. The font is modified as follows:- To provide backward compatibility to render emoji, all emoji characters are represented with a single Unicode code point in Unicode’s Supplemental Private Use Area-A starting with U+F0001.
-
Extra emoji metadata is inserted in a binary format into the font and
is parsed at runtime by
EmojiCompat
. The data is embedded in the font’smeta
table, with the private tag Emji.
Configuration options
You can use the EmojiCompat
instance to
modify EmojiCompat
behavior. You can use
the following methods from the base class to set the configuration:
setReplaceAll()
: Determines whetherEmojiCompat
should replace all emoji it finds withEmojiSpans
. By default,EmojiCompat
tries its best to understand if the system can render an emoji and does not replace those emoji. When set totrue
,EmojiCompat
replaces all emoji it finds withEmojiSpans
.setEmojiSpanIndicatorEnabled()
: Indicates whetherEmojiCompat
has replaced an emoji with anEmojiSpan
. When set totrue
,EmojiCompat
draws a background for theEmojiSpan
. This method is mainly used for debugging purposes.setEmojiSpanIndicatorColor()
: Sets the color to indicate anEmojiSpan
. The default value isGREEN
.registerInitCallback
: Informs app about the state of theEmojiCompat
initialization.
val config = FontRequestEmojiCompatConfig(...) .setReplaceAll(true) .setEmojiSpanIndicatorEnabled(true) .setEmojiSpanIndicatorColor(Color.GREEN) .registerInitCallback(object: EmojiCompat.InitCallback() { ... })
EmojiCompat.Config config = new FontRequestEmojiCompatConfig(...) .setReplaceAll(true) .setEmojiSpanIndicatorEnabled(true) .setEmojiSpanIndicatorColor(Color.GREEN) .registerInitCallback(new InitCallback() {...})
Adding initialization listeners
EmojiCompat
and
EmojiCompat
classes
provide
registerInitCallback()
and
unregisterInitCallback()
methods to register an initialization callback. To use these methods, create
an instance of the
EmojiCompat.InitCallback
class. Call
these methods and pass the instance of the
EmojiCompat.InitCallback
class. When the
initialization of the EmojiCompat
support
library is successful, the EmojiCompat
class calls the
onInitialized()
method. If the library
fails to initialize, the EmojiCompat
class calls the
onFailed()
method.
To check the initialization state at any point, call the
getLoadState()
method. It returns one of the following values:
LOAD_STATE_LOADING
,
LOAD_STATE_SUCCEEDED
,
or LOAD_STATE_FAILED
.
Using EmojiCompat with AppCompat widgets
If you are using AppCompat widgets
, you
can use EmojiCompat
widgets that extend
from AppCompat widgets
.
- Add the support library to the dependencies section.
- Use
EmojiCompat
AppCompat Widget
widgets in layout XMLs.
<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"/>
Bundled fonts configuration
The EmojiCompat
support library is also
available in a bundled font version. This package includes the font with the
embedded metadata. The package also includes a
BundledEmojiCompatConfig
that uses the AssetManager
to load the metadata
and fonts.
Note: The size of the font is in multiple megabytes.
Adding support library dependency
To use the EmojiCompat
support library
with bundled font configuration, you must modify your app project's
classpath dependencies within your development environment.
To add a support library to your application project:
- Open the
build.gradle
file of your application. - Add the support library to the
dependencies
section.
dependencies { ... implementation "androidx.emoji:emoji:28.0.0" }
dependencies { ... implementation("androidx.emoji:emoji:28.0.0") }
Using bundled fonts to configure EmojiCompat
To use bundled fonts to configure
EmojiCompat
, perform the following steps:
- Use
BundledEmojiCompatConfig
to create an instance ofEmojiCompat
and provide an instance ofContext
. - Call the
init()
method to initializeEmojiCompat
and pass the instance ofBundledEmojiCompatConfig
.
class MyApplication : Application() { override fun onCreate() { super.onCreate() val config = BundledEmojiCompatConfig(this) EmojiCompat.init(config) } }
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); EmojiCompat.Config config = new BundledEmojiCompatConfig(this); EmojiCompat.init(config); ... } }
Using EmojiCompat without widgets
EmojiCompat
uses
EmojiSpan
to render correct images.
Therefore, it has to convert any given CharSequence
into
Spanned
instances with
EmojiSpans
. The
EmojiCompat
class provides a method to
convert CharSequences
into
Spanned
instances with
EmojiSpans
. Using this method,
you can process and cache the processed instances instead of the raw string,
which improves the performance of your application.
val processed = EmojiCompat.get().process("neutral face \uD83D\uDE10")
CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");
Using EmojiCompat for IMEs
Using the EmojiCompat
support library,
keyboards can render the emoji supported by the application they are
interacting with. IMEs can use the
hasEmojiGlyph()
method to check if EmojiCompat
is capable
of rendering an emoji. This method takes a CharSequence
of
an emoji and returns true
if
EmojiCompat
can detect and render the
emoji.
The keyboard can also check the version of the
EmojiCompat
support library that the app
supports to determine which emoji to render in the palette. To check the
version, if available, the keyboard needs to check whether the following
keys exist in the
EditorInfo.extras
bundle:
EDITOR_INFO_METAVERSION_KEY
EDITOR_INFO_REPLACE_ALL_KEY
If the key exists in the bundle, the value represents the
version of the emoji metadata that the app uses. If this key does not
exist, the app is not using EmojiCompat
.
If the key exists and is set to true
, this indicates that
the app has called the
SetReplaceAll()
method. For more information about
EmojiCompat
configuration,
refer to the Configuration options
section.
After receiving the keys in the
EditorInfo.extras
bundle,
the keyboard can use the
hasEmojiGlyph()
method, where metadataVersion
is the value for
EDITOR_INFO_METAVERSION_KEY
,
to check whether the app can render a specific emoji.
Using EmojiCompat with custom widgets
You can always use the process()
method to preprocess the CharSequence
in your app and add
it to any widget that can render Spanned
instances; for
example, TextView
. In addition,
EmojiCompat
provides the following widget
helper classes to let you enrich your custom widgets with emoji support with
minimum effort.
- Sample TextView
- Sample EditText
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) } }
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() { ... } }
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 } }
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() { ... } }
Frequently asked questions
- How do I initiate the font download?
- How much time does it take to initialize?
- How much memory does the EmojiCompat support library use?
- Can I use EmojiCompat for a custom TextView?
- What happens if I add widgets in layout XMLs on devices that run on Android 4.4 (API level 19) or lower?
The emoji fonts are downloaded on first request, if they do not exist on the device. The download scheduling is transparent to the app.
After the font is downloaded, it takes approximately 150 milliseconds
to initialize EmojiCompat
.
Currently, the data structure to find the emoji is loaded in the app’s memory and uses around 200KB.
Yes. EmojiCompat provides helper classes for custom widgets. It is also
possible to preprocess a given string and convert it to
Spanned
. For more information about widget helper
classes, refer to the
Using EmojiCompat with custom widgets
section.
You can include the EmojiCompat
support library or its widgets in your applications that support devices
running Android 4.4 (API level 19) or lower. However, if a device runs
on an Android version prior to API level 19,
EmojiCompat
and its widgets are in a
"no operation" state. This means that
EmojiTextView
behaves exactly
like a regular TextView
.
EmojiCompat
instance; it immediately
gets into a
LOAD_STATE_SUCCEEDED
state when you call the
init()
method.
Additional resources
For additional information on using the
EmojiCompat
library, watch EmojiCompat.