Xamarinから.NET MAUI移行でAndroidResourceがContentになる原因と解決策(Platforms/Android/Resourcesとcsproj設定)

Xamarin.Android から .NET MAUI へ移行すると、これまで「ビルドアクション:AndroidResource」にしていた drawable/values 配下の png/xml が、なぜか Content 扱いになり、Resource.Drawable などで参照できず困ることがあります。原因は「MAUI のリソースは置き場が複数系統」という設計にあります。本記事では移行後の正しい置き方と、確実に直す csproj 設定を整理します。

目次

起きていること:Xamarin の「Resources」と MAUI の「Resources」は別物

Xamarin.Android のプロジェクトでは、プロジェクト直下の Resources フォルダーが “Android のネイティブリソース” そのものでした。ここに drawable/values/layout などを置き、ファイルのビルドアクションを AndroidResource にすると、AAPT(aapt2)がリソースとしてコンパイルし、C# 側では Resource.Drawable や Resource.Id といった形で参照できました。

一方、.NET MAUI(シングルプロジェクト)では、プロジェクト直下にある Resources は「MAUI が各プラットフォーム向けに変換・配布する共有リソース置き場」です。つまり、同じ “Resources” という名前でも役割が違うため、Xamarin の感覚で Resources/drawable をそのまま持ってくると、MAUI 側では意図した扱いにならず、IDE 上でも Content 扱いに見えることがあります。

観点Xamarin.Android.NET MAUI(シングルプロジェクト)
プロジェクト直下の ResourcesAndroid ネイティブリソース共有リソース(MAUI が変換して配る)
Android の drawable/values/layout を置く場所Resources/ 配下Platforms/Android/Resources/ 配下
ビルドアクション設定の考え方AndroidResource を明示する運用が一般的共有は「置き場で判断」、Android ネイティブは AndroidResource(csproj 明示が堅い)

フォルダー構造の具体例:移行前の Xamarin.Resources をどこに移すか

「何をどこへ移すべきか」が曖昧なままだと、移行後のプロジェクトに Resources が2つの意味で混在してしまいます。まずは “移行前→移行後” の対応表を作って、チーム内の共通認識を作るのがおすすめです。

Xamarin.Android(移行前)
├─ Resources
│  ├─ drawable
│  │  └─ icon.png
│  ├─ values
│  │  └─ colors.xml
│  └─ layout
│     └─ main.axml
└─ Assets
   └─ config.json

.NET MAUI(移行後のおすすめ)
├─ Resources(MAUI 共有)
│  ├─ Images
│  │  └─ logo.svg        (MauiImage)
│  └─ Raw
│     └─ config.json     (MauiAsset)
└─ Platforms
   └─ Android
      └─ Resources(Android ネイティブ)
         ├─ drawable
         │  └─ icon.png   (AndroidResource)
         ├─ values
         │  └─ colors.xml (AndroidResource)
         └─ layout
            └─ main.axml  (AndroidResource)

移行前の Assets は、MAUI では Resources/Raw(MauiAsset)に寄せると “Android 以外でも使える資産” として管理しやすくなります。一方で、drawable/values/layout/xml は Android の仕組みで参照されることが多いため、基本は Platforms/Android/Resources へ移すのが安全です。

結論:MAUI のリソースは「共有」と「Android ネイティブ」の2系統

移行で迷うポイントは、MAUI ではリソースの置き場が大きく2系統に分かれることです。ここを最初に押さえると、「AndroidResource が選べない」問題はほぼ整理できます。

系統置き場主なビルドアクション向いている用途参照のイメージ
共有リソース(MAUI 管轄)Resources/(例:Resources/Images, Resources/Fonts, Resources/Raw)MauiImage, MauiFont, MauiAsset などマルチプラットフォームで同じ素材を使う(画像・フォント・生データ等)XAML や C# の ImageSource、アセット読み込みなど
Android ネイティブリソース(AAPT 管轄)Platforms/Android/Resources/(drawable/values/layout/xml…)AndroidResourceAndroid 固有の仕組みで必要(通知アイコン、バックアップ除外 XML、FileProvider、レイアウト XML 等)Resource.Drawable/Resource.Id/Resource.Layout など

ポイントは「Android のネイティブ資産として扱いたいかどうか」です。Resource.* で参照したい、あるいは Android の設定 XML(xml フォルダー)として参照したい場合は、基本的に Platforms/Android/Resources 側に寄せます。

まずやるべき整理:移行対象ファイルを3分類する

現場の移行で最も事故が少ないのは、最初にファイルを次の3種類に分けてから移すやり方です。闇雲に “全部 AndroidResource に戻す” より、後工程の保守が楽になります。

分類代表例おすすめの置き場理由
共有で使える素材アプリ内で表示する画像、SVG、アイコン、フォント、JSON/CSV などResources/Images, Resources/Fonts, Resources/RawMAUI が各解像度へ変換したり、各 OS の作法に合わせて配置してくれるため
Android 固有で必要なもの通知アイコン、network_security_config.xml、file_paths.xml、バックアップ除外ルール、カスタムレイアウト XMLPlatforms/Android/Resources(drawable/xml/layout…)AAPT が “Android のリソース” として扱う必要があるため
Android の values に寄せたいが MAUI でも代替できるものcolors.xml 相当、テーマ色、スタイル基本は MAUI の Resources/Styles(XAML)へ寄せ、どうしても必要なら Platforms/Android/Resources/valuesクロスプラットフォームのテーマ設計に寄せると、移行後の差分が減る

この分類ができると、以降の判断がシンプルになります。「Android でしか使わない」「Resource.* が必要」なら Android ネイティブ側へ、そうでないなら MAUI の共有側へ、という形です。

本題:AndroidResource が選べない/Content になるときの最短解決

結論から言うと、Android ネイティブリソースにしたいファイルは Platforms/Android/Resources に置き、さらに csproj でフォルダーごと AndroidResource 扱いに固定するのが一番堅いです。Visual Studio の UI で AndroidResource が出ない/勝手に Content になる、といった “表示や反映の揺れ” を MSBuild 側で吸収できます。

csproj で AndroidResource を明示する(推奨)

Microsoft Learn の Localization ドキュメントでも、個別ファイルに対して UI でビルドアクションを設定するより、フォルダー単位で指定する方法が紹介されています。移行時はこの形に寄せると安定します。

<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
  <AndroidResource Include="Platforms\Android\Resources\**"
                   TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

ポイントは2つあります。

  • Condition を付ける:MAUI はマルチターゲットなので、Android ビルドのときだけ効かせます。
  • TargetPath を付ける:サブフォルダー構造(drawable/values/xml…)を保ったまま取り込ませます。

Content との二重取り込みを避けたい場合

プロジェクトによっては、SDK スタイルの “暗黙のファイル取り込み” により、同じファイルが Content と AndroidResource の両方に入ってしまうことがあります(ビルド警告や予期せぬパッケージング差分の原因になります)。その場合は、Android 向けの条件付きで Content を除外するのが安全です。

<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
  <Content Remove="Platforms\Android\Resources\**\*.*" />
  <AndroidResource Include="Platforms\Android\Resources\**"
                   TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

この “Remove → Include” の順にしておくと、UI 上の表示が何であっても、最終的なビルド入力が揃いやすくなります。

Content のままで良いケース/ダメなケース

「Content になっているけど、動いているから放置して良い?」は移行でよく出る判断ポイントです。結論としては “何をしたいか” で決まります。

やりたいことContent のままでも成立しやすいAndroidResource が必要になりやすい
画像を画面に表示したい共有リソース(Resources/Images)へ移せば OK密度別 drawable、ローカライズ drawable を Android の規則で扱いたい場合
Resource.Drawable.xxx で参照したい基本的に NG(参照できない/見つからない原因になりがち)必須
@xml/xxx のように AndroidManifest から参照したいNG(Android の xml リソースとして入っていない可能性)必須
カスタムレイアウト XML を使いたいNG(layout リソースとして扱われない)必須

目安として、Resource.Id/Resource.Drawable/Resource.Layout/Resource.String などが “見つからない” コンパイルエラーになったら、ほぼ Android リソースとして取り込めていません。その場合は AndroidResource 扱いに揃えるのが最短です。

「AndroidResource は MAUI には無い」と言われる背景

移行直後に検索すると「MAUI では AndroidResource を使わない」という説明に当たることがあります。これは “共有リソースは MAUI の Resources に置けば自動で各プラットフォームへ配られる” という文脈では正しい一方で、Android のネイティブリソース(drawable/values/layout/xml)まで含めて “全部不要” と解釈すると事故ります。

現実的には、MAUI には次の2つの世界が同居しています。

  • MAUI のリソース変換パイプライン:Resources/Images などを元に、Android/iOS/Windows それぞれの形式へビルド時に変換・配置する。
  • .NET for Android のリソースパイプライン:Platforms/Android/Resources を Android のリソースとしてコンパイルし、Resource.* 参照や @xml/ 参照で使えるようにする。

このため、IDE 上で “AndroidResource が選べない” としても、プロジェクトとして Android ネイティブリソースが不要とは限りません。必要なものは AndroidResource に揃え、不要なものは MAUI 共有へ寄せる、という切り分けが最も安全です。

それでも直らないとき:ビルドキャッシュと生成物を疑う

csproj を直したのに Resource.* が出てこない/古いまま、という場合は、移行時の “残骸” が悪さをしていることが多いです。次の手順を上から順に試すと、原因の切り分けが早くなります。

チェック具体的な操作狙い
bin/obj を消すソリューションを閉じ、プロジェクト配下の bin/obj を削除してからビルドリソース生成物の差し替え・キャッシュ破棄
クリーン → リビルドVisual Studio の「クリーン」→「リビルド」増分ビルドの取りこぼし回避
ファイル名の規則を再確認Android のリソース名は基本的に小文字+数字+アンダースコア(空白/ハイフン不可)AAPT が無視/失敗しているケースを潰す
重複リソースを探す同名の png/xml が複数フォルダーに存在しないか確認生成時の競合・上書きの防止

特に移行直後は、旧 Xamarin の Resources が残ったまま、MAUI の Resources と二重になりがちです。「意図した方だけがビルドに入っているか」を一度整理すると、以降の不具合が減ります。

ビルド前にファイル生成・コピーを差し込みたい場合

例えば「ビルド前に colors.xml を自動生成して Platforms/Android/Resources/values に置きたい」「CI で生成した png を配置したい」といったケースでは、MSBuild のターゲットに処理を差し込みます。Android のリソース処理より 前 に動かすのがポイントです。

一例として、Android リソースをまとめる内部ターゲット(_GenerateAndroidResourceDir)より前に動くように指定します。

<Target Name="GenerateMyAndroidResources"
        BeforeTargets="_GenerateAndroidResourceDir"
        Condition="$(TargetFramework.Contains('-android'))">

  <!-- 例:生成物を Platforms/Android/Resources/values にコピー -->
  <Copy SourceFiles="$(MSBuildProjectDirectory)\BuildArtifacts\colors.xml"
        DestinationFolder="$(MSBuildProjectDirectory)\Platforms\Android\Resources\values"
        SkipUnchangedFiles="true" />

</Target>

ポイントは「生成先を Platforms/Android/Resources にする」ことと、「ターゲットを Android のリソース生成より前にする」ことです。こうすると、後続の AndroidResource 取り込みに間に合い、Resource.* 参照や @xml/ 参照で使える状態になりやすくなります。

移行後のおすすめ運用:共有は MAUI、Android ネイティブは最小限

移行後にチーム開発で揉めやすいのが、「全部 Android 側に寄せるか、MAUI 側に寄せるか」です。おすすめは次の方針です。

  • 画面で使う画像・フォント・生データは MAUI 共有(Resources/)へ寄せる:将来 iOS/Windows を足すときに効きます。
  • Android の仕組みで参照されるものだけ Platforms/Android/Resources へ:数を絞るほど、移行後のビルド差分が減ります。
  • AndroidResource の設定は csproj に寄せる:IDE の表示揺れや個別設定漏れを防げます。

特に “Xamarin の Resources をそのまま残す” と、MAUI の Resources と名前が衝突し、メンバー間の認識ズレを生みがちです。フォルダー構造を MAUI の作法に合わせて整理しておくと、後々の拡張(多言語化、テーマ切替、アイコン差し替え)が楽になります。

よくある質問

Android の colors.xml や styles.xml はどうする?

A: UI 全体の色・スタイルとして使うだけなら、MAUI の Resources/Styles(XAML の ResourceDictionary)へ寄せた方が移行後のメリットが大きいです。一方、Android のテーマやネイティブ側の仕組み(特定の属性、ライブラリが values を要求する等)が絡む場合は、Platforms/Android/Resources/values に置いて AndroidResource として扱うのが安全です。

Android の layout(XML レイアウト)は MAUI でも必要?

A: 通常の画面は MAUI の XAML で作れるため不要なことが多いです。ただし、Android のネイティブ UI を埋め込む、サードパーティ SDK がレイアウト ID を要求する、通知のカスタムレイアウトを使うなど、Android 依存の理由がある場合は Platforms/Android/Resources/layout に残します。

プロパティ画面で AndroidResource が出ないのは不具合?

A: 表示上の制約・バージョン差分・マルチターゲットの文脈などで、IDE のビルドアクション一覧が期待通りにならないケースがあります。運用としては、UI で頑張るよりも csproj 側で <AndroidResource ... /> を明示し、ビルド結果を安定させるのが現実的です。

まとめ

  • .NET MAUI の Resources/ は “共有リソース”。Xamarin.Android の Resources/ と同じ感覚で使わない。
  • Android の drawable/values/layout/xml は Platforms/Android/Resources/ に置く。
  • UI で AndroidResource が選べない/Content になるときは、csproj でフォルダーごと AndroidResource を明示すると安定する。
  • 反映されないときは、bin/obj 削除→クリーン→リビルドと、ファイル名規則・重複をチェック。

参考資料

  • Microsoft Q&A: What is AndroidResource type under Android-Maui?
  • Microsoft Learn: .NET for Android Build Items
  • Microsoft Learn: Localization – .NET MAUI
  • Microsoft Learn: Secure storage – .NET MAUI

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次