2022-10-12

ExpoのManaged WorkflowでAndroid 13のThemed Iconsを設定する

Android 13でThemed Icons(テーマ別アイコン) が導入され、壁紙やテーマに合わせてアプリアイコンの色を変更できるようになりました。これをExpoのManaged Workflowで設定する方法について説明します。

前提

必要な変更内容

Themed Iconを使うにはandroid/app/src/main/res/mipmap-anydpi-v26の下のic_launcher.xmlic_launcher_rounded.xml ファイルを編集する必要があります。

Managed Workflowを利用している場合androidフォルダ配下は管理されていないため、ビルド前のタイミング(Prebuild時)でConfig Pluginを実行してファイルの内容を更新する必要があります。

一度expo prebuildを実行してビルド前の状態を確認するとic_launcher.xmlic_launcher_rounded.xmlの中身は以下のようになっていることがわかります。

<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@color/iconBackground"/>
    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

これらのファイルの<adaptive-icon>の配下に以下の記述を追加する必要があります。

<monochrome android:drawable="@mipmap/ic_launcher_foreground" />

Config Pluginの作成

以下のようなConfig Pluginを作成します。

import { ConfigPlugin, withDangerousMod } from "@expo/config-plugins"
import fs from "fs"
import path from "path"


export const withMonochromeIcon: ConfigPlugin = config => {
  return withDangerousMod(config, [
    "android",
    async c => {
      console.log("withMonochromeIcon()")
      const mipMap26Path = path.join(
        c.modRequest.platformProjectRoot,
        "app",
        "src",
        "main",
        "res",
        "mipmap-anydpi-v26",
      )
      for (const file of ["ic_launcher.xml", "ic_launcher_round.xml"]) {
        const filePath = path.join(mipMap26Path, file)
        const contents = fs.readFileSync(filePath, "utf-8")
        const replacedContents = contents.replace(SEARCH_TEXT, REPLACE_TEXT)
        fs.writeFileSync(filePath, replacedContents)
        console.log("update", filePath)
      }
      return c
    },
  ])
}

const SEARCH_TEXT =
  '    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>'
const REPLACE_TEXT = `    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
    <monochrome android:drawable="@mipmap/ic_launcher_foreground" />`

Config PluginをTypeScriptで記述するための設定についてはこちらの記事を参考にしてください。

ic_launcher.xmlic_launcher_rounded.xmlを更新するためのDefault modsは用意されていないため、withDangerousModを使います。ファイルの内容を読み込み、テキストを置換しています。

今回は面倒だったのでテキスト置換していますが今後これらのファイルの内容が変わることも考えられるため、気になる方はXMLパーサで読み込んでオブジェクトを更新しそれをXMLにまた変換するというやり方をした方が安全かもしれません。

実際の表示を確認

実際にConfig Pluginを適用してPrebuildした後アプリをビルドしてみると、端末のホーム画面でアイコンが壁紙に合わせたカラーになっていることが確認できます。

Android 13 Themed Icon

参考

最終更新: 2022-10-12 03:15
筆者: @gaishimo 主にReact Nativeでのアプリ開発を行っています。
© 2021 Omoidasu, Inc. All rights reserved.