Start Debugging
2015-09-27 更新日 2023-11-18 xamarinxamarin-forms Edit on GitHub

How To: Xamarin Forms アプリに AdMob を追加する

Custom view renderer を使い、Xamarin Forms アプリ (Android / iOS) に AdMob 広告を組み込む手順をステップバイステップで解説します。

新しいプラットフォーム / 新しいテクノロジーで開発する際に、最初に考えることの 1 つがマネタイズです。私の場合の問いは「AdMob はどれくらい簡単に統合できるのか?」というもの。Xamarin Forms に対する答えは「ケースバイケース」で、運と達成したいことの複雑さ次第です。詳細は順を追って説明します。

最初に、必要なコンポーネントをプロジェクトに追加する必要があります。今回は Visual Studio を使いますが、Xamarin Studio でもほぼ同様のはずです。プラットフォームごとに分岐します。

この時点で Android プロジェクトはビルドできなくなり、COMPILETODALVIK : UNEXPECTED TOP-LEVEL エラーが出ているはずです。修正するには、Droid プロジェクトの Properties から Android Options タブを開き、Advanced で Java Max Heap Size の値を 1G にしてください。これでエラーなくビルドできるようになるはずです。

次に、共有 / PCL プロジェクトに新しい Content View を追加し AdMobView と名付けます。コンストラクター内に生成されたコードを削除して、次のような状態にします。

public class AdMobView : ContentView
{
    public AdMobView() { }
}

この新しい view をページに追加します。XAML では次のように書けます。

<controls:AdMobView />

control に何も干渉しないようにしてください。「何も」とは、重なり合う control、ページの padding、control の margin / spacing などのことです。広告 control に何かが重なっていると広告は表示されず、エラーも出ません。注意してください。

次は custom view renderers の追加です。こちらもプラットフォームごとに進めます。

Android

新しいクラス AdMobRenderer を以下のコードで追加してください。ExportRenderer 属性は必ず namespace の上に置きます。そうしないと魔法は起きません。

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]

namespace AdExample.Droid.Renderers
{
    public class AdMobRenderer : ViewRenderer
    {
        public AdMobRenderer(Context context) : base(context)
        {

        }

        private int GetSmartBannerDpHeight()
        {
            var dpHeight = Resources.DisplayMetrics.HeightPixels / Resources.DisplayMetrics.Density;

            if (dpHeight <= 400) return 32;
            if (dpHeight <= 720) return 50;
            return 90;
        }

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                var ad = new AdView(Context)
                {
                    AdSize = AdSize.SmartBanner,
                    AdUnitId = "ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx"
                };

                var requestbuilder = new AdRequest.Builder();

                ad.LoadAd(requestbuilder.Build());
                e.NewElement.HeightRequest = GetSmartBannerDpHeight();

                SetNativeControl(ad);
            }
        }
    }
}

続いて、AdActivity と広告表示に必要な権限 ACCESS_NETWORK_STATE、INTERNET を追加するため AndroidManifest.xml を変更します。次の例のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
	<uses-sdk android:minSdkVersion="15" />
	<application>
    <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" />
  </application>
  <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  <uses-permission android:name="android.permission.INTERNET" />
</manifest>

これで完了です。Android のビルドで AdMobView の content view 内に広告が表示されるはずです。

iOS

まずは AppDelegate.cs に 1 行追加して、application ID で SDK を初期化します。これは ad unit ID と混同しないでください。LoadApplication 呼び出しの直前に追加します。

MobileAds.Configure("ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx");

そして同じように、AdMobRenderer という新しいクラスを追加し、以下のコードを貼り付け、AdmobID を自分の banner unit の ID に置き換えてください。

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]

namespace GazetaSporturilor.iOS.Renderers
{
    public class AdMobRenderer : ViewRenderer
    {
        BannerView adView;
        bool viewOnScreen;

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement == null)
                return;

            if (e.OldElement == null)
            {
                adView = new BannerView(AdSizeCons.SmartBannerPortrait)
                {
                    AdUnitID = "ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx",
                    RootViewController = GetRootViewController()
                };

                adView.AdReceived += (sender, args) =>
                {
                    if (!viewOnScreen) this.AddSubview(adView);
                    viewOnScreen = true;
                };

                var request = Request.GetDefaultRequest();

                e.NewElement.HeightRequest = GetSmartBannerDpHeight();
                adView.LoadRequest(request);

                base.SetNativeControl(adView);
            }
        }

        private UIViewController GetRootViewController()
        {
            foreach (UIWindow window in UIApplication.SharedApplication.Windows)
            {
                if (window.RootViewController != null)
                {
                    return window.RootViewController;
                }
            }

            return null;
        }

        private int GetSmartBannerDpHeight()
        {
            var dpHeight = (double)UIScreen.MainScreen.Bounds.Height;

            if (dpHeight <= 400) return 32;
            if (dpHeight <= 720) return 50;
            return 90;
        }
    }
}

これで完了です。両プラットフォームで広告が配信されるようになりました。コメントや提案があれば、下のコメント欄でお知らせください。

2017/12/30 更新

本記事では Banner 広告の表示を扱い、view サイズを 320 x 50 dp に固定しました。smart banners を実装したい方は、続編をご覧ください: Xamarin Forms における AdMob Smart Banner のサイズ調整

2018/01/21 更新

ようやく勇気を出して自分のアプリの 1 つを iOS でビルドしてみたので、最新版の AdMob for Xamarin に対応するよう本記事を更新しました。12/30 の更新で触れた smart sizing のコードも入れています。コメント欄で iOS 実装の手助けをしてくれた皆さん、ありがとう。

次に読む

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< 戻る