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 Nuget package Xamarin.GooglePlayServices.Ads.Lite
- for iOS – add Nuget package Xamarin.Google.iOS.MobileAds
- for Windows Phone –
download the SDK from here and add it as a referenceplatform no longer supported
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() { }
}
Code language: C# (cs)
Add this new view to your page. In XAML you can do it like this:
<controls:AdMobView />
Code language: HTML, XML (xml)
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
{
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);
}
}
}
}
Code language: C# (cs)
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>
Code language: HTML, XML (xml)
That’s it. Your Android build should now display ads inside the AdMobView content view.
iOS
Start off by adding one line in your AppDelegate.cs to initialize the SDK with your application ID. Careful, do not mistake this with your ad unit ID! Add this just before the LoadApplication call.
MobileAds.Configure("ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx");
Code language: C# (cs)
Then, same as before, just add a new class called AdMobRenderer and copy-paste the code below replacing the AdmobID with the ID of your banner unit.
[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;
}
}
}
Code language: C# (cs)
That’s it. Now you have ads being served on both platforms. Any comments or suggestions you have leave them in the comments section below.
Update 30 Dec 2017
In this article we looked at displaying Banner ads and hard-coded the view size to 320 x 50 dp. If you’re looking to implement smart banners have a look at this follow-up post: AdMob Smart Banner sizing in Xamarin Forms
Update 21 Jan 2018
I finally made the courage to try and build one of my apps for iOS so I’ve updated this article to work with the latest version of AdMob for Xamarin. I’ve also included the smart sizing code mentioned in the 30 Dec update. Thanks to everyone helping out in the comments section with the iOS implementation.
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.
[csharp]adView = new BannerView(size: AdSizeCons.Banner, origin: new CGPoint(-10, 0))
{
AdUnitID = AdmobID,
RootViewController = UIApplication.SharedApplication.Windows[0].RootViewController
};
adView.AdReceived += (sender, args) =>
{
if (!viewOnScreen) this.AddSubview(adView);
viewOnScreen = true;
};
adView.LoadRequest(Request.GetDefaultRequest());
base.SetNativeControl(adView);[/csharp]
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.
[csharp]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) =>
{
if (!viewOnScreen) this.AddSubview(adView);
viewOnScreen = true;
};
adView.LoadRequest(Request.GetDefaultRequest());
base.SetNativeControl(adView);
}
}
}
}[/csharp]
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:
[csharp]adView.LoadRequest(Request.GetDefaultRequest());[/csharp]
in the AdMobRenderer for iOS. I’m guessing this may be related to iOS 10?
hi Sir, i really haven’t had the change to test this on iOS yet so I won’t be able to help you there.
Does that download for Windows Phone works for uwp as well? Do we have any Chance to integrated into uwp project?
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
Thanks Bro !
From Morocco :D
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?
Awesome! It works for me in Android, thanks for your share. :D
Now Google AdMob not support UWP. Do you have any way to show Ads in Xamarin.Forms?
How to implement Video Advertise?
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:
[xml]xmlns:controls="clr-namespace:MyProject.Controls;assembly=MyProject"[/xml]
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.
How to implement RewardedAds
How to show Rewarded Ads in Xamarin.Forms
my ads are showing nothing but I am not getting any error:
my view is here:
[csharp]using System;
using Xamarin.Forms;
namespace Eithar.Controls
{
public class AdMobView : ContentView
{
public AdMobView() { }
}
}[/csharp]
and my render is:
[csharp]using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using UIKit;
using Syncfusion.SfBusyIndicator.XForms.iOS;
using Com.OneSignal;
using Syncfusion.ListView.XForms.iOS;
using Syncfusion.SfPullToRefresh.XForms.iOS;
using Firebase.Core;
using Google.MobileAds;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(Eithar.Controls.AdMobView), typeof(Eithar.iOS.AdMobRenderer))]
namespace Eithar.iOS
{
public class AdMobRenderer : ViewRenderer
{
const string AdmobID = "ca-app-pub-xxxxxxxxxxxxxxxxxxxxxx";
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 += (object sender, EventArgs args) =>
{
if (!viewOnScreen) this.AddSubview(adView);
viewOnScreen = true;
};
adView.LoadRequest(Request.GetDefaultRequest());
base.SetNativeControl(adView);
}
}
}
}[/csharp]
then in my sign in page:
Hi Jassim, I finally got around playing with iOS myself and I’ve updated the AdMob renderer code for iOS to work with the latest SDKs. I’ve tested the new code just now and it should work.
Also, when debugging why ads don’t show it’s good to look in the Output window. The ads SKD won’t crash your application if there’s an error, instead it will print the error message to the console. I had the same issue and in my case it was saying that I didn’t set the RootViewController; apparetly there were some changes in that area, thus the new method which cycles through the application windows & returns the first RootViewController that it finds.
please check you XAML page,
Make sure you don’t have any padding or margin in the container of the Ad control,
I’ve so far managed to get the Android version working. Haven’t tried iOS yet.
I’m just wondering what the part about ‘AdActivity’ is for? This bit:
When I added that to the Android manifest, the build process showed an error which I tried to fix with various tinkers and google searches until successive problems pretty much bulldozed the entire project. I had to undo a lot of changes to get it working and building successfully again!
On second try, I followed your instructions step-by-step, building and testing at each point, and found that there wasn’t any need for the AdActivity part at all. I currently have ads displaying on my app without that addition.
Either way, this has been incredibly useful, so thanks! I just thought I’d let you know that the AdActivity part in the Android Manifest seems to be not needed, at least in my case. For reference, my Manifest data looks like this:
Cheers!
Update: Oops. I’ve just discovered, clicking on the ad results in a white screen with nothing else happening. I take it this is what the AdActivity stuff is for…?
Hi, just a final comment further to what I posted earlier – the whole thing is totally working for me, and clicking on an ad opens the google chrome app and it all works fine. I even see my AdMob account has been updated with its first $0.05 earning thanks to that test click, ha.
The reason it didn’t work before is presumably because I’m based in China and forgot to try it with my VPN switched on.
So overall, I can say that I’ve managed to get everything setup while completely bypassing the part where AdActivity was supposed to be added to the Android Manifest..!
Glad to hear you got it working. Be very careful though, don’t under any circumstances click on your own ads. In fact, don’t even display them during development as even that is against AdMob’s TOS. What I tend to do is wrap the LoadAd call inside a #if !DEBUG statement like so:
[csharp]#if !DEBUG
ad.LoadAd(requestbuilder.Build());
e.NewElement.HeightRequest = GetSmartBannerDpHeight();
#endif[/csharp]
This way you make sure ads only get displayed in release builds. Alternatively, you could also use test devices like so, but then you’d need to maintain that list as you use new devices / emulators (you can get the device ID by watching the Output window when the AdMob SDK initializes).
[csharp]requestbuilder.AddTestDevice("device-id");[/csharp]
Gret Article, thanks so much for publishing
Orther choise
https://www.youtube.com/watch?v=CbCR0smKysY
It’s using Microsoft Advertising SDK and Google Admob
I looked at many Xamarin AdMob, but this one is most straight-forward and reliable, especially how you dynamically set the Height of the SmartBanner.
Thanks for sharing and well done!
PS: You can remove “dpHeight > 400 && ” from GetSmartBannerDpHeight
Thanks Boris! Good catch on those if conditions, I’ve updated the code.
Hi. When i get request from admob, my debug console spamming me:
D/AudioManager (26589): getStreamVolume isRestricted mode = 0. And this affects on the performance. Anyone have this problem?
I’m trying to implement ads in my app, and eventually in-app purchases (to register a full version upgrade from free)
I’ve been following the tutorial from this site
https://www.c-sharpcorner.com/article/google-admob-display-ads-in-xamarin-forms/
I’ve created my AdMob Account, and added my app, I have the adUnitID, and from what I can tell that part is completed properly.
The problem I am having is when I try to compile the code, I get missing AndroidX assemblies,
Here is the specific error I am getting
Could not find 8 Android X assemblies, make sure to install the following NuGet packages:
– Xamarin.AndroidX.Lifecycle.LiveData
– Xamarin.Google.Android.Material
– Xamarin.AndroidX.Legacy.Support.V4
(Please note it says 8 but only lists 3 assemblies)
I’ve tried installing those assemblies. Once they are installed I get two errors when I try to build.
one is
1>C:\Users\jesse\OneDrive\Documents\Source\…\obj\Debug\90\lp\124\jl\res\values\values.xml(1778): error APT2000: expected enum but got (raw string) slide.
Which is this line in the code
slide
And the other error is
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\Android\Xamarin.Android.Aapt2.targets(164,3): error APT2062: failed linking references.
This is the linking reference it refers to.
If I change the SDK version to Android10, all of the errors go away, the package gets deployed, but will not show up in the app launcher, and will not start when I try to debug it.