How To: Add AdMob to your Xamarin Forms app

One of the first things people think about when developing for a new platform / using a new technology is monetization; and in my case the question is: how easy is it to integrate AdMob? For Xamarin Forms the answer would be: “It depends” – it depends on luck & on the complexity of what you want to achieve; but I will detail this as we move along.

The first thing you need to do is add the required components to your projects. For this walktrough I will be using Visual Studio but it should be relatively the same when using Xamarin Studio. Here, things go separate ways for each of the platforms:

  • for Android – add the Google Play Services component
  • for iOS – add the AdMob component
  • for Windows Phone – download the SDK from here and add it as a reference

By now, you Android project should no longer be building & you should be receiving a COMPILETODALVIK : UNEXPECTED TOP-LEVEL error. To fix that, go into your Droid project properties, select the Android Options tab and then under Advanced modify the value for the Java Max Heap Size to 1G. Your project should now build without any errors.

Next, inside your shared / PCL project add a new Content View and call it AdMobView. Remove the code generated inside it’s constructor & it should look like this:

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

Add this new view to your page. In XAML you can do it like this:

<controls:AdMobView WidthRequest="320" HeightRequest="50" />

Make sure NOTHING interferes with the control. By nothing I mean – overlapping controls, page padding, control margins / spacing, etc. If you have something overlapping the ad control, ads will not display & you won’t receive an error, so be careful.

Next, it’s time to add the custom view renderers; and again, we’ll handle each platform:

Android

Add a new class called AdMobRenderer with the code below. Make sure to keep the ExportRenderer attribute above the namespace, otherwise the magic won’t happen.

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

namespace AdExample.Droid.Renderers
{
    public class AdMobRenderer : ViewRenderer<AdMobView, Android.Gms.Ads.AdView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<AdMobView> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                var ad = new Android.Gms.Ads.AdView(Forms.Context);
                ad.AdSize = Android.Gms.Ads.AdSize.Banner;
                ad.AdUnitId = "_your_admob_ad_unit_id_goes_here_";

                var requestbuilder = new Android.Gms.Ads.AdRequest.Builder();
                ad.LoadAd(requestbuilder.Build());

                SetNativeControl(ad);
            }
        }
    }
}

Next, you need to modify your AndroidManifest.xml file to add the AdActivity & required permissions for displaying ads: ACCESS_NETWORK_STATE, INTERNET; just like in the example below.

<?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>

That’s it. Your Android build should now display ads inside the AdMobView content view.

Windows Phone

Just like for Android, add a new class to your WinPhone project called AdMobRenderer having the code below.

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

namespace AdExample.WinPhone.Renderers
{
    public class AdMobRenderer : ViewRenderer<AdMobView, GoogleAds.AdView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<AdMobView> e)
        {
            base.OnElementChanged(e);

            if (Control == null)
            {
                var ad = new GoogleAds.AdView();
                ad.Format = AdFormats.Banner;
                ad.AdUnitID = "_your_admob_ad_unit_id_goes_here_";

                var adRequest = new GoogleAds.AdRequest();
                ad.LoadAd(adRequest);

                SetNativeControl(ad);
            }
        }
    }
}

iOS

This, I haven’t got the chance to test yet as I don’t have a Mac around but people say it works, so I’ve added it for reference. Same as before, just add a new class called AdMobRenderer and copy-paste the code below.

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

namespace GazetaSporturilor.iOS.Renderers
{
    public class AdMobRenderer : ViewRenderer
    {
        const string AdmobID = "_your_admob_ad_unit_id_goes_here_";

        GADBannerView 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 GADBannerView(GADAdSizeCons.SmartBannerPortrait)
                {
                    AdUnitID = AdmobID,
                    RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
                };

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

                GADRequest request = GADRequest.Request;

                adView.LoadRequest(request);
                base.SetNativeControl(adView);
            }
        }
    }
}

That’s it. Now you have ads being served on all platforms. Any comments or suggestions you have leave them in the comments section below.




16 Comments

You, sir, are a life saver. Almost a year later and this is still relevant. If anyone cares, a few things have changed for the iOS implementation:

GADBannerView is now a BannerView, and the constructor is slightly different.

adView = new BannerView(size: AdSizeCons.Banner, origin: new CGPoint(-10, 0))
                {
                    AdUnitID = AdmobID,
                    RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
                };

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

                adView.LoadRequest(Request.GetDefaultRequest());
                base.SetNativeControl(adView);

Works like a charm though, thanks!!!

Thanks for the writeup! I’ve been able to add AdMob adds to my Android and iOS projects.

I had to make some changes to the names of some of the classes to make this work on iOS with the latest AdMob component version.

using System;
using Vocabilis;
using Vocabilis.iOS.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using Google.MobileAds;
using UIKit;

[assembly: ExportRenderer(typeof(AdMobView), typeof(AdMobRenderer))]
namespace GazetaSporturilor.iOS.Renderers
{
	public class AdMobRenderer : ViewRenderer
	{
		const string AdmobID = "_your_admob_ad_unit_id_goes_here_";

		BannerView adView;
		bool viewOnScreen;

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

			if (e.NewElement == null)
				return;

			if (e.OldElement == null)
			{
				adView = new BannerView(AdSizeCons.SmartBannerPortrait)
				{
					AdUnitID = AdmobID,
					RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
				};

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


				adView.LoadRequest(Request.GetDefaultRequest());
				base.SetNativeControl(adView);
			}
		}
	}
}

hmmm… I can’t get this to fly in my Forms project even updating with the notes from the commenters here. Am I perhaps adding the wrong NuGet packages? I see several available that match the description but the original instructions don’t specific which ones exactly – can someone let me know the full name/id of the packages that need to be included here?
thanks much

sorry – to be clear the Android works ok but iOS is throwing “ex = {Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[AppDelegate window]: unrecognized selector sent to instance 0x17062aa80” exception when running the line:

adView.LoadRequest(Request.GetDefaultRequest());

in the AdMobRenderer for iOS. I’m guessing this may be related to iOS 10?

Thanks for sharing . I have test the code and it works fine for testing purpose with admob, anyway when i publish the app , it does not work ,just showing blank space. please advise

What versions of the google play services are required for Android? The iOS Version works very well but the android version only comes with a blank control. This are my used NuGet packages: http://pastebin.com/BCBDdJuS

Is something else required? Or did not just not work in a Simulator? I cannot reference the latest Google Play Service because my Mono.Android version is not the latest (and actual I don’t know how to upgrade without loosing anything) and I cannot reference the entire Google Play Service because I cannot compile / debug anymore if I do so.

Is there a problem with iOS with this setup? I see Ads on the Simulator in the debug but the release Version from the AppStore has just empty blank placeholders where ads should be. Did I miss something?

I feel totally stupid that it took me this long to figure out, so just in case there’s anyone else as *special* as me that stumbles into this issue in the future, too:

You need to create “AdMobView” in the “shared/PCL” project in the solution.
The “AdMobRenderer” classes need be created in each PLATFORM specific project (eg: one in the Android one, one in the iOS one).

Hi, I am very new to Xamarin Forms sorry if this is a stupid question but I am getting the error ‘Controls’ is an undeclared prefix.

I have put your line of code on my shared code MainPage XAML. I have searched Google in regards to Controls as a usable element but nothing has come up.

Thanks

You need to add the ‘controls’ namespace at the top in your .XAML file. In my case for example it’s:

xmlns:controls="clr-namespace:MyProject.Controls;assembly=MyProject"

Replace the namespace & assembly to match your app – or if you’re using Visual Studio just type in ‘xmlns:controls=’ and IntelliSense will help you out.

Leave a Reply

Your email address will not be published. Required fields are marked *

Are you a human? * Time limit is exhausted. Please reload the CAPTCHA.