Handling Mobile Ads in C# and Xamarin

Recently I put out two games, The Chaotic Workshop and Space Esc8bit, which both have with a free ad supported version. There’s lots of support and examples for native code, but to get them working with MonoGame and Xamarin in C# took a bit of searching through Forums and trial and error to get it working across all platforms.

What I opted for was a single AdManager class which which encapsulated everything needed for loading and showing ads for any and all platforms.

A Banner Test Ad showing in The Chaotic Workshop on iOS.

Setting Up

First, since the ads would be shown overtop of the game view, it was required to set up the platform specific Views which would hold the ads themselves.

As you can see below, iOS is rather straightforward, but for Android, the constructor is a little more involved. We need to get the GameView, as well as create an AdContainer, and then place both of them into the original mainview. This AdContainer is for the BannerAd that we’ll add later.

///
/// Initialise a new AdMob Ad Overlay. This is a Cross platform method which will run on both Android and iOS.
/// 

/// The host game to et the service container from
/// The location to place the add on the screen
public AdManager(Game Game, Vector2 location)
{
	this.Game = Game;

#if __ANDROID__

	//Interstitial Ads
	mInterstitialAd = new InterstitialAd(Game.Activity);

	// Get the Game View
	GameView = (View)Game.Services.GetService(typeof(View));

	// Create the Ad Container
	AdContainer = new LinearLayout(Game.Activity)
	{
	    Orientation = Orientation.Horizontal
	};
	AdContainer.SetGravity(GravityFlags.CenterHorizontal | GravityFlags.Bottom);
	AdContainer.SetBackgroundColor(Android.Graphics.Color.Transparent); // Need on some devices, not sure why

	//AdContainer.AddView(RewardedVideoAd);

	// A layout to hold the ad container and game view
	var mainLayout = new FrameLayout(Game.Activity);
	mainLayout.AddView(GameView);
	mainLayout.AddView(AdContainer);
	Game.Activity.SetContentView(mainLayout);

#elif __IOS__
	ViewController = Game.Services.GetService(typeof(UIViewController)) as UIViewController;
	Location = new CGPoint(location.X, location.Y);
#endif
}

Banner Ads

Banner ads are great because they provide ads while, if designed properly, shouldn’t impede the players enjoyment of the game.

Below here is how the Banner Ads are set up.

///
/// Adds the banner.
/// 

/// Ad unit identifier.
/// Location.
public void InitBanner(string adUnitID, Vector2 Location)
{

#if __ANDROID__
// Must be here for Android
        Location = Vector2.One;

	// The actual ad view
	var bannerAd = new AdView(Game.Activity)
	{
	    AdUnitId = adUnitID,
	    AdSize = AdSize.SmartBanner,
	};
// Load a New Ad
	bannerAd.LoadAd(new AdRequest.Builder()
#if DEBUG
// Prevents generating real impressions while testing
	.AddTestDevice("DEADBEEF9A2078B6AC72133BB7E6E177")
#endif
	.Build());

	// Add the banner view to the AdContainer.
	AdContainer.AddView(bannerAd);

#elif __IOS__
	this.Location = new CGPoint(Location.X, Location.Y);
	// Setup your BannerAdView
	AdViewBanner = new BannerView(size: AdSizeCons.Banner, origin: this.Location)
	{
	    AdUnitID = adUnitID,
	    RootViewController = ViewController
	};

	// Setup Events
	AdViewBanner.AdReceived += (object sender, EventArgs e) =>
	{
	    if (!isAddOnScreen)
	        ViewController.View.AddSubview(AdViewBanner);
	    isAddOnScreen = true;
	    AdsAreBeingReceived = true;
	};

	AdViewBanner.ReceiveAdFailed += (object sender, BannerViewErrorEventArgs e) =>
	{
	    Console.WriteLine(e.Error.DebugDescription);
	};

	Request request = Request.GetDefaultRequest();
#if DEBUG
	request.TestDevices = new[] { "GAD_SIMULATOR_ID", "kGADSimulatorID" };
#endif
        // Load Ad
	AdViewBanner.LoadRequest(request);
#endif
}

Here we place the BannerAd as well as pass the Adunit ID from Admob.

Once we’ve set up the BannerAd Views for each platform, we need to then tell the banner ad view to load ads. This is done differently is each platform.

Note: it’s really important you use TestDevice IDs as well as Googles test adunit ID, so that you don’t pick up false impressions and also so AdMob doesn’t ban you! This method has seemed to be working for me, but double check on your own system.

There’s no need to call a Show() method or anything, it will start showing banner ads as soon as some are loaded.

Below you can see a version of the test ad working in Space Esc8bit on Android.

Interstitial Ads

Intersitital Ads are good to show during transitions in your game, such as between levels or during a game over. We use them in The Chaotic Workshop and Space Exc8bit at the end of every other level.

Initialising

First job is to Initialise the Interstitial Ads.

 ///

/// Adds the initerstialel ad.
/// 

/// Ad unit identifier.
public void InitIniterstialelAd(string adUnitID)
{
    this.AdUnitID = adUnitID;
#if __ANDROID__
	try
	{
	    mInterstitialAd.AdUnitId = adUnitID;
	}
	catch (Exception ex)
	{
	    Console.WriteLine(ex.Message);
	}
	mInterstitialAd.AdListener = new AdListener();
#elif __IOS__
	// Intersitials must be re-instantiated each time
	// the ad's are loaded.
#endif
	LoadIniterstialelAd();
}

Note: for iOS this is handled very differently. Each time you show an Interstitial Ad, you need to instantiate the InterestitialAd object. Otherwise it will throw errors. The way i’ve set it up is this is done each time ‘LoadIniterstialelAd’ is called.

Loading

Much the same way banner ads are handled, here we create a request object and then load the ad. For Interstitial Ads though, you need to check if an ad has been loaded yet before showing it.

Note how we call ‘AdViewInterstitial = new Interstitial(this.AdUnitID);’ here for iOS. As I said before, you need to Re-instantiate the ‘Interstitial’ object each time you want to load an ad.

public void LoadIniterstialelAd()
{
#if __ANDROID__
	if (mInterstitialAd.IsLoaded==false)
	{
	var adRequest = new AdRequest.Builder()
#if DEBUG
		.AddTestDevice("DEADBEEF9A2078B6AC72133BB7E6E177") // Prevents generating real impressions while testing
#endif
		.Build();
	mInterstitialAd.LoadAd(adRequest);
	}
#elif __IOS__

	Request request = Request.GetDefaultRequest();
#if DEBUG
	request.TestDevices = new[] { "GAD_SIMULATOR_ID", "kGADSimulatorID" };
#endif

	if (AdViewInterstitial == null || AdViewInterstitial.HasBeenUsed == true)
	{
	    Console.WriteLine("Creating AdViewInterstitial");
	    AdViewInterstitial = new Interstitial(this.AdUnitID);
	    AdViewInterstitial.AdReceived += (object sender, EventArgs e) =>
	    {
	        Console.WriteLine("Add Recived");
	    };
	    AdViewInterstitial.ScreenDismissed += delegate
	    {
	        Console.WriteLine("Dissmised");
	    Engine.Pause = false;
	    };

	    AdViewInterstitial.ReceiveAdFailed += (object sender, InterstitialDidFailToReceiveAdWithErrorEventArgs e) =>
	    {
	        Console.WriteLine(e.Error.DebugDescription);
	};
	    AdViewInterstitial.LoadRequest(request);
	}

#endif
}

Showing The Ads

We’re now ready to show the ads. The Android Interstitial Ad object is instantiated in the constructor, and therefore the only check is for whether there is an ad loaded.

For iOS, since the ‘Interstitial’ object is re-instantiated each time we call it, we need to do a few more checks, but the method is essentially the same.

///
/// Shows the initersial ad if there's one loaded.
/// 

public void ShowInitersialAd()
{
#if __ANDROID__
	if (mInterstitialAd.IsLoaded)
	{
	    mInterstitialAd.Show();
	}
#elif __IOS__
	try
	{
	    if (AdViewInterstitial != null)
	    {
	        if (AdViewInterstitial.IsReady)
	        {
	            UIViewController viewController = Game.Services.GetService(typeof(UIViewController)) as UIViewController;
	            AdViewInterstitial.PresentFromRootViewController(viewController);
	        }
	    }
	}
	catch
	{
	    Console.WriteLine("Error Showing Ad");
	}
#endif

One other thing to be aware of, in Android, when the Interstitial Ads are shown, the game is paused, where as in iOS the game continues to run. It’s important to set up a method where the game is paused until the Interstitial Ad is closed.

Below here, you can see the test Interstitial Ad showing:

So there you go. You can get a copy of the full AdManager here.

If you like what you read, give me a follow, or keep up with me on Twitter.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s