Posted at

EmojiCompatでAndroid絵文字サポート


Emoji Compatibility

EmojiCompatサポートライブラリを使って、古い端末(Android 4.4までサポート)でもtofu ☐ にならないようにする事ができます。


:smile: EmojiCompatの仕組み



  • EmojiCompat で使用する絵文字用のフォントはダウンロード又はアプリにバンドルして使える


  • EmojiCompatは、指定されたCharSequenceの絵文字を識別し、必要に応じて
    それらを EmojiSpans に置き換えて、最後に絵文字をレンダリングする

image1.png

今回は絵文字用のフォントをダウンロードして使えるようにしたいと思います。


:computer:環境構築


app/build.gradle に以下を追加します。

implementation 'com.android.support:support-emoji:28.0.0'

事前に以下の準備を行います。



  1. Downloadable Fontsを使用してフォントをダウンロードできるようにする



    • AndroidStudioを使ってダウンロードフォントを指定する


      • layout editorから適当なtextviewを選択

      • サイドメニューの「textAppearance」>「fontFamily」で「More Fonts.」を選択
        image2.png

      • 「Noto」で検索し、Font Nameがnoto_color_emoji_compatのフォントを検索
        image3.png


      • Create downloadable font を選択し「OK」


      • すると res/font に以下のようなxmlとres/values配下に認証情報とプリロード用のファイルが作成される

        <?xml version="1.0" encoding="utf-8"?>
        
        <font-family xmlns:app="http://schemas.android.com/apk/res-auto"
        app:fontProviderAuthority="com.google.android.gms.fonts"
        app:fontProviderPackage="com.google.android.gms"
        app:fontProviderQuery="Noto Color Emoji Compat"
        app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
        </font-family>







  2. 準備ができたので、ApplicationクラスのonCreateでDownloadable Fontsを使う為にリクエストを送る実装を追加

            val fontRequest = FontRequest(
    
    "com.google.android.gms.fonts",
    "com.google.android.gms",
    "Noto Color Emoji Compat",
    R.array.com_google_android_gms_fonts_certs
    )
    val config = FontRequestEmojiCompatConfig(applicationContext, fontRequest)
    EmojiCompat.init(config)


    :pencil: 実装





簡単なサンプル

まずは絵文字をログに出力させてみたいと思います。

       // Downloadable Fontsを使う為に準備

val fontRequest = FontRequest(
"com.google.android.gms.fonts",
"com.google.android.gms",
"Noto Color Emoji Compat",
R.array.com_google_android_gms_fonts_certs
)
val config = FontRequestEmojiCompatConfig(applicationContext, fontRequest)
EmojiCompat.init(config)
// 初期化が終わったタイミングで絵文字をログに出力
EmojiCompat.get().registerInitCallback(object : EmojiCompat.InitCallback() {
override fun onInitialized() {
super.onInitialized()

val text = EmojiCompat.get().process("\uD83E\uDD23")
Log.d(TAG, "emoji: $text")
}
})

出力結果

image4.png

※AndroidStudioのLogcatではMacの絵文字が表示されるので注意


EmojiAppCompatTextView を使う

今度は絵文字用にカスタムされたViewを使って絵文字を表示したいと思います。

レイアウトファイルでTextViewの代わりにEmojiTextViewを使います。

    <androidx.emoji.widget.EmojiTextView

android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

あとは通常のTextViewと同じように絵文字も含んだ文字列を設定します。

textView.text = "\uD83E\uDD23"

image5.png

ちゃんと表示されました :sparkles:


:bomb: バッドノウハウ


IllegalStateException: Not initialized yet が出る場合。

     Caused by: java.lang.IllegalStateException: Not initialized yet

at androidx.core.util.Preconditions.checkState(Preconditions.java:131)
at androidx.emoji.text.EmojiCompat.process(EmojiCompat.java:742)
at androidx.emoji.text.EmojiCompat.process(EmojiCompat.java:702)
at androidx.emoji.text.EmojiCompat.process(EmojiCompat.java:666)
at androidx.emoji.text.EmojiCompat.process(EmojiCompat.java:634)

初期化されてない状態で使おうとしているので registerInitCallback で初期化後に

処理を行うようにする。