Android Emoji Policy と DefaultEmojiCompatConfig と Playサービス依存の罠

PlayストアでAndroid Emoji Policy なるものが要求されるようになりました。
Developer Program Policy: October 27, 2021 announcement - Play Console Help
「Apps running on Android 12 and above must comply with the latest Unicode version within 4 months of public availability.」
だそうで、Android 12 以上の端末で動作するアプリは最新の絵文字に4ヶ月以内に対応しなければならないそうです。

それに伴い AndroidX AppCompat 1.4.0 と AndroidX Emoji2 1.0.0 がリリースされました。

https://developer.android.com/jetpack/androidx/releases/emoji2 の下の方を見ると以下のようなことが書いてあります。

  • appcompat は androidx.emoji2 を依存関係に持つよ。
  • androidx.startup を使って EmojiCompatInitializer による自動設定を粉うよ。
  • DefaultEmojiCompatConfig を使ってデフォルトのフォントプロバイダーを探すよ。
  • 自動初期化を無効にするにはうんぬんかんぬん。

しかし試しにアプリを書いてみると古い端末では13.1の絵文字は表示されません。

コードを読んで原因をみてみましょう。

  • androidx.emoji2.text.DefaultEmojiCompatConfigは queryIntentContentProviders(Intent(action="androidx.content.action.LOAD_EMOJI_FONT")) で端末中のContentProviderを探す。
  • (providerInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == ApplicationInfo.FLAG_SYSTEM を満たさないものを除外する。
  • com.google.android.gms.fonts だけが残る。
  • そのContentProviderと連携して何かする。

バリバリにPlayサービスに依存してますね。当然それなりに新しいPlayサービスが入ってないと自動ロードは働きません。
手元の端末だとXperia 10 III はオッケー、Xperia Z3 Compact はダメでした。

絵文字プロバイダがない場合は EmojiCompat.Config 相当のオブジェクトが生成されず、EmojiCompat.init はまだ呼び出されていない状態になります。
このままだとEmojiTextViewはインスタンス生成時に例外を出します。AppCompatTextViewは端末OSに入ってる絵文字を表示します。
ユーザ体験的には残念ですね。

古い端末向けのワークアラウンド

  • 依存関係にimplementation "androidx.emoji2:emoji2-bundled:$emojiVersion"を追加。
  • アプリ初期化や画面初期化の際に EmojiCompat.init(BundledEmojiCompatConfig(applicationContext)) を呼び出す。

すると「まだEmojiCompatが初期化されていなければ」アプリにバンドルした絵文字データが使われるようになります。