ADMob How too, A FULL EXAMPLE

For a VERY long time a bunch of people have been asking how to integrate Admob into there Android MonoGame Apps, After traveling around the Web and trying MANY examples, Most in Java and All NEVER a complete guide, I’ve completed the simplest and FULL example on how to do the simplest way possible using Visual Studio 2017 and the Latest Monogame 3.6 Dev. Here it is.

Firstly after creating your Android App Open “Manage NuGet Packages” (Right click project->Manage NuGet Packages)
Browse search for this “Xamarin.GooglePlayServices.Ads.Lite” and install it

if its a new Project, create an Android manifest (Right Click project->Prooperties->Android Manifest->Create)
Insert the following via editing the Android Manifest.xml

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<uses-permission android:name="android.permission.INTERNET" />
	<!-- Below MUST be put into the manifest to allow the ad to react to the user-->
	<activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />

Heres and example of MY FULL Manifest

xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="AdController.AdController" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
	<uses-sdk android:targetSdkVersion="22" android:minSdkVersion="22" />
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<uses-permission android:name="android.permission.INTERNET" />
	<!-- Below MUST be put into the manifest to allow the ad to react to the user-->
	<activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
	<application android:label="AdController"></application>
</manifest>

Next Make a new Class Call it what ever you want, I called Mine AdController my NameSpace/Project was also called AdController so don’t forget to change the namespace to yours

Here is the complete code for the Class

using Android.Gms.Ads;
using Android.Gms.Ads.Reward;

/// <summary>
/// For Ads to work 
/// NuGet Xamarin.GooglePlayServices.Ads.Lite
/// Only then can ads be added to the project
/// 
/// AndroidManifest.xml File
/// add these lines
// 	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
//	  <uses-permission android:name="android.permission.INTERNET" />
//	<!-- Below MUST be put into the manifest to allow the ad to react to the user-->
//	  <activity android:name="com.google.android.gms.ads.AdActivity"
//	  android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
///
/// </summary>

namespace AdController
{
  public static class AdController
  {
    public static InterstitialAd interstitialHandle = null;
    public static IRewardedVideoAd rewardHandle = null;


    // APP ID This is a test use yours from Admob
    private static string appID = "ca-app-pub-3940256099942544~3347511713";
    // AD ID's This is a test use yours from Admob
    public static string adID1 = "ca-app-pub-3940256099942544/1033173712"; // standard full page ad
    public static string adID2 = "ca-app-pub-3940256099942544/5224354917"; // reward full page ad

    public static bool adRegularLoaded = false;
    public static bool adRewardLoaded = false;
    public static bool adRewarded = false;
    public static bool youMadeMoney = false;

    /*********************************************************************************************
     * Function Name : InitAdRegularAd
     * Description : Initialize a regular full page ad
     * if you need to change the adID, just set
     * interstitialRegular.AdUnitId to point to another adIDx
     * ******************************************************************************************/
    public static void InitRegularAd()
    {
      MobileAds.Initialize(Game1.Activity,appID);                                               // initialize the ads        
      interstitialHandle = new InterstitialAd((Activity1)Game1.Activity);
      interstitialHandle.AdUnitId = adID1;                                                     // adID string, can repoint this on the fly
      interstitialHandle.AdListener = null;
      ListeningRegular listening = new ListeningRegular();
      interstitialHandle.AdListener = listening;
      interstitialHandle.LoadAd(new AdRequest.Builder().Build());
    }
    /*********************************************************************************************
     * Function Name : ShowRegularAd
     * Description : display the ad
     * ******************************************************************************************/
    public static void ShowRegularAd()
    {
      if(adRegularLoaded)
      {
        adRegularLoaded = false;
        adRewarded = false;
        interstitialHandle.Show();
      }
    }
    /*********************************************************************************************
     * Function Name : InitRewardAd
     * Description : Initialize a reward Ad
     * ******************************************************************************************/
    public static void InitRewardAd()
    {
      ListeningReward listening = new ListeningReward();                                          // create a pointer to our listen class      
      rewardHandle = MobileAds.GetRewardedVideoAdInstance(Game1.Activity);                        // initialize the handle      
      rewardHandle.UserId = appID;                                                                // set the App ID      
      rewardHandle.RewardedVideoAdListener = listening;                                           // point to the rewards Listen class      
      rewardHandle.LoadAd(adID2,new AdRequest.Builder().Build());                                 // load the first one      
    }
    /*********************************************************************************************
     * Function Name : ShowRewardAd
     * Description : display the ad
     * ******************************************************************************************/
    public static void ShowRewardAd()
    {
      if(adRewardLoaded)                                                                          // we ready?        
      {
        adRewardLoaded = false;                                                                   // reset triggers        
        adRewarded = false;
        rewardHandle.Show();                                                                      // show the ad        
      }
    }
  }
  /*********************************************************************************************
    * Class Name : ListeningRegular
    * Description : Listening class for the regualr ad
    * ******************************************************************************************/
  internal class ListeningRegular : AdListener
  {
    public override void OnAdLoaded()
    {
      AdController.adRegularLoaded = true;
      base.OnAdLoaded();
    }
    public override void OnAdClosed()
    {
      // load the next ad ready to display
      AdController.interstitialHandle.LoadAd(new AdRequest.Builder().Build());
      base.OnAdClosed();
    }
    public override void OnAdOpened()
    {
      base.OnAdOpened();
    }
  }
  /*********************************************************************************************
    * Function Name : ListeningReward
    * Description : Listening class for the reward ad
    * ******************************************************************************************/
  internal class ListeningReward : AdListener, IRewardedVideoAdListener
  {
    public ListeningReward()
    {
      // constructor, up to you if you need to do anything in here
    }
    public void OnRewarded(IRewardItem reward)
    {
      // you can use the reward variable to handle your own rewards
      AdController.adRewarded = true;
    }
    public void OnRewardedVideoAdClosed()
    {
      // load the next ad ready to display
      AdController.rewardHandle.LoadAd(AdController.adID2,new AdRequest.Builder().Build());
    }
    public void OnRewardedVideoAdFailedToLoad(int errorCode)
    {
      // error message if you want will be ignored otherwise
    }
    public void OnRewardedVideoAdLeftApplication()
    {
      // ad was clicked on so you just made money
      AdController.youMadeMoney = true;
    }
    public void OnRewardedVideoAdLoaded()
    {
      // ad was loaded
      AdController.adRewardLoaded = true;
    }
    public void OnRewardedVideoAdOpened()
    {
      // ad opening
    }
    public void OnRewardedVideoStarted()
    {
      //ad running
    }
  }
}

And Here is how I called it as an example from MonoGame Game1.cs

/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
private SpriteFont font;
protected override void LoadContent()
{
  // Create a new SpriteBatch, which can be used to draw textures.
  spriteBatch = new SpriteBatch(GraphicsDevice);
  font = Content.Load<SpriteFont>("debugFont");

  // GET AD'S READY TO BE DISPLAYED
  AdController.InitRegularAd();
  AdController.InitRewardAd();

  // TODO: use this.Content to load your game content here
}

/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific content.
/// </summary>
protected override void UnloadContent()
{
  // TODO: Unload any non ContentManager content here
}

/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
  if(GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
  {
    Exit();
  }

  // TODO: Add your update logic here

  base.Update(gameTime);
}

/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
/// 
double oldCount = 0;
Random rnd = new Random();
protected override void Draw(GameTime gameTime)
{
  GraphicsDevice.Clear(Color.CornflowerBlue);

  // TODO: Add your drawing code here
  spriteBatch.Begin();
  if(oldCount < gameTime.TotalGameTime.TotalMilliseconds)
  {
    oldCount = gameTime.TotalGameTime.TotalMilliseconds + 3000;
    if((rnd.Next() & 1) == 1)
    {
      if(AdController.adRewardLoaded)
      {
        AdController.ShowRewardAd();
      }
    }
    else
    {
      if(AdController.adRegularLoaded)
      {
        AdController.ShowRegularAd();
      }
    }
  }
  else
    spriteBatch.DrawString(font,"Waiting for an Ad Reward from ad="+AdController.adRewarded,new Vector2(340,300),Color.White);
  spriteBatch.End();

  base.Draw(gameTime);
   }
 }

That’s it all done, A complete class to display Full page Ad’s from Inside MonoGame including rewards and all there triggers
If you have any comments lets me know, don’t forget to get an AdMob account from www.AdMob.com and use your ID’s in the code above.
Happy Coding,
Enjoy
Paul

6 Likes

Thanks for posting this Paul!
I bundled this up into a library and pushed it up to Nuget to make it even easier to add AdMob to MonoGame projects:

Cheers!

@dmanning23
The sample isn’t working. You can find the issue here: https://github.com/dmanning23/RevMobBuddySample/issues/1

Awesome guide!

But for me it only seems to show test ads. If I add my admob IDs it doesn’t show apps. I double checked the app and ad IDs are correct. Any ideas?

If your app is showing the test ads and the IDs are correct, then you are good to go.
It can take several days for ads to be added to your hopper. Check back on the app in like a week.

I found the issue with mine, in case it helps anyone else.

In admob site I deactivated that it use the location in advanced settings (my app doesn’t have location permission).

Then it worked.

1 Like

got this error on line 119 of your code in AdController.cs:

‘ListeningReward’ does not implement interface member ‘IRewardedVideoAdListener.OnRewardedVideoCompleted()’

Dont know what to do.

Add a new method:

    public void OnRewardedVideoCompleted()
    {
        //ad completed
    }

Thanks for this! It is just what I was looking for and works like a charm.

Has anyone got BANNER ads to work?

Does anyone have an example of this working with the latest Monogame (3.8)?

I can not make current version work with the example.

I’m having issues with 3.8 too, are you also seeing this error?

Java.Lang.RuntimeException: 'Unable to get provider com.google.android.gms.ads.MobileAdsInitProvider: java.lang.IllegalStateException:

Managed to fix my error by including metadata in the Manifest, ads are now displaying normally in the game.

Is there a way to have mediation with other ad providers such as MoPub?

Full question here: https://community.monogame.net/t/mopub-ads-mediation-with-admob/

Hi All,

I got it working fine on the Android side. Works well.
On the IOS side I am stumped at a more basic level (see below)
I seem to have a linking or reference problem. Is there a simple step or solution I am missing. I am hoping can tell me the step I have screwed or missed.

thanks,

Severity Code Description Project File Line Suppression State
Error Native linking failed, undefined symbol: _NSValueFromGADAdSize. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._GetNSValue. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _NSStringFromGADAdSize. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._GetNSString. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADSimulatorID. This symbol was referenced by the managed member Google.MobileAds.Request.SimulatorId. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADErrorDomain. This symbol was referenced by the managed member Google.MobileAds.RequestError._ErrorDomain. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeSmartBannerPortrait. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._SmartBannerPortrait. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeSmartBannerLandscape. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._SmartBannerLandscape. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeSkyscraper. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._Skyscraper. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeMediumRectangle. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._MediumRectangle. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeLeaderboard. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._Leaderboard. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeLargeBanner. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._LargeBanner. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeInvalid. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._Invalid. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeFullBanner. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._FullBanner. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeFluid. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._Fluid. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdSizeBanner. This symbol was referenced by the managed member Google.MobileAds.AdSizeCons._Banner. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdLoaderAdTypeUnifiedNative. This symbol was referenced by the managed member Google.MobileAds.AdLoaderAdTypeExtensions.kGADAdLoaderAdTypeUnifiedNative. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711
Error Native linking failed, undefined symbol: _kGADAdLoaderAdTypeNativeCustomTemplate. This symbol was referenced by the managed member Google.MobileAds.AdLoaderAdTypeExtensions.kGADAdLoaderAdTypeNativeCustomTemplate. Please verify that all the necessary frameworks have been referenced and native libraries linked. MM.iOS C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets 711

I have these to errors:

Severity Code Description Project File Line Suppression State
Warning The referenced component ‘C:\Users\admin\AppData\Local\XamarinBuildDownloadCache\FAdM-7.53.1\Frameworks\GoogleMobileAdsFramework-Current\GoogleMobileAds.framework’ could not be found. AdMobBuddy.iOS
Warning The referenced component ‘C:\Users\admin\AppData\Local\XamarinBuildDownloadCache\GAppM-6.2.1\Frameworks\GoogleAppMeasurement.framework’ could not be found. AdMobBuddy.iOS

Just in case anybody is still looking for banner ads I extended this sample. I removed the code related to reward ads because it is all deprecated now. Hope it helps somebody.

In order to display banner adds we need to use a FrameLayout to render MonoGame in instead of a View. The code to initialize banner ads requires a FrameLayout parameter. It constructs the banner ad view, adds it to a LinearLayout and adds that to the frame layout.

using System;
using AdMobDemo;
using Android.Gms.Ads;
using Android.Views;
using Android.Widget;

namespace AdController
{
    public static class AdController
    {
        public static InterstitialAd interstitialHandle = null;
        public static AdView AdView = null;

        public static event EventHandler AdClosed;

        // AD ID's This is a test use yours from Admob
        public static string adID1 = "ca-app-pub-3940256099942544/1033173712"; // standard full page ad
        public static string adID3 = "ca-app-pub-3940256099942544/6300978111"; // banner ad

        public static bool adRegularLoaded = false;
        public static bool adBannerLoaded = false;

        public static void InitBannerAd(FrameLayout fl)
        {
            LinearLayout ll = new LinearLayout((Activity1)Game1.Activity)
            {
                Orientation = Orientation.Horizontal
            };

            ll.SetGravity(GravityFlags.CenterHorizontal | GravityFlags.Bottom);

            MobileAds.Initialize(Game1.Activity);

            AdView = new AdView((Activity1)Game1.Activity)
            {
                AdUnitId = adID3,
                AdSize = AdSize.Banner
            };

            ListeningBanner listening = new ListeningBanner();
            
            AdView.AdListener = listening;
            AdView.LoadAd(new AdRequest.Builder().Build());
            AdView.Visibility = ViewStates.Visible;

            ll.AddView(AdView);
            fl.AddView(ll);
        }

        public static void InitRegularAd()
        {
            MobileAds.Initialize(Game1.Activity);
            interstitialHandle = new InterstitialAd((Activity1)Game1.Activity)
            {
                AdUnitId = adID1,
                AdListener = null
            };

            ListeningRegular listening = new ListeningRegular();

            interstitialHandle.AdListener = listening;
            interstitialHandle.LoadAd(new AdRequest.Builder().Build());

            listening.AdClosed += Listening_AdClosed;
        }

        private static void Listening_AdClosed(object sender, EventArgs e)
        {
            AdClosed?.Invoke(null, null);
        }

        public static void ShowRegularAd()
        {
            if (adRegularLoaded)
            {
                adRegularLoaded = false;
                interstitialHandle.Show();
            }
        }
    }

    internal class ListeningRegular : AdListener
    {
        public event EventHandler AdClosed;

        public override void OnAdLoaded()
        {
            AdController.adRegularLoaded = true;
            base.OnAdLoaded();
        }

        public override void OnAdClosed()
        {
            AdController.interstitialHandle.LoadAd(new AdRequest.Builder().Build());
            AdClosed?.Invoke(this, null);
            base.OnAdClosed();
        }
        public override void OnAdOpened()
        {
            base.OnAdOpened();
        }
    }

    internal class ListeningBanner : AdListener
    {
        public override void OnAdFailedToLoad(LoadAdError p0)
        {
            base.OnAdFailedToLoad(p0);
        }

        public override void OnAdLoaded()
        {
            AdController.adBannerLoaded = true;
            base.OnAdLoaded();
        }

        public override void OnAdClosed()
        {
            AdController.AdView.LoadAd(new AdRequest.Builder().Build());
            base.OnAdClosed();
        }
    }
}

Calling the initialization is done in Activity1.cs. Instead of hosting MonoGame in a View it is hosted in a FrameLayout as I mentioned earlier. You call the initialize method for banner ads in the AdController here. Banner ads are set to automatically repopulate if they are tapped.

using AdController;
using Android.App;
using Android.Content.PM;
using Android.OS;
using Android.Views;
using Android.Widget;
using Microsoft.Xna.Framework;

namespace AdMobDemo
{
    [Activity(
        Label = "@string/app_name",
        MainLauncher = true,
        Icon = "@drawable/icon",
        AlwaysRetainTaskState = true,
        LaunchMode = LaunchMode.SingleInstance,
        ScreenOrientation = ScreenOrientation.FullUser,
        ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.Keyboard | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize
    )]
    public class Activity1 : AndroidGameActivity
    {
        private Game1 _game;
        private FrameLayout fl;

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            _game = new Game1();

            fl = new FrameLayout(this);
            fl.AddView((View)_game.Services.GetService(typeof(View)));

            AdController.InitBannerAd(fl);

            SetContentView(fl);

            _game.Run();
        }
    }
}

In some instance I am fine with just adding Xamarin.GooglePlayServices.Ads.Lite for NuGet packages but other times I need to add the dependencies. Here is a list of packages that I sometimes need to add to get banner ads to work.

  • Xamarin.AndroidX.Browser
  • Xamarin.AndroidX.Collection
  • Xamarin.AndroidX.Core
  • Xamarin.AndroidX.Legacy.Support.V4
  • Xamarin.Build.Download
  • Xamarin.GooglePlayServices.Ads
  • Xamarin.GooglePlayServices.Ads.Base
  • Xamarin.GooglePlayServices.Ads.Identifier
  • Xamarin.GooglePlayServices.Ads.Lite
  • Xamarin.GooglePlayServices.Basement
  • Xamarin.GooglePlayServices.Gass

Adding Xamarin.Build.Download will give you a deprecated warning. It also says that you can ignore it if your project builds fine.

2 Likes