Tutorial: AdMob in Unity without overriding the main activity

As of August 1st, 2014, Google will no longer be supporting the "Legacy" AdMob SDK, as implemented in this tutorial, and has migrated to the new Google Play Services library for Android AdMob integration.
A new tutorial for this implementation can be found in a two part series HERE and HERE

Introduction

During development on Atomic Attack, one of my goals was to implement Google's AdMob advertising platform. After searching around on the internet and unity forms, I either found links to pre-compiled plugins for sale on the Unity store or tutorials expanded on Unity's tutorial for writing plugins, which suggests that you need to modify the XML manifest to override the main android activity to one you create in the plugin (which extends Unity's activity class).

Before I continue, let me explain that doing this isn't a terrible thing. It obviously works, as many Unity developers have done this technique for there published games, and its what the official Unity tutorial recommends. My problems with this approach are few, but big enough that I had to find another solution.

he major issue I have is if you ever had to add more than one plugin that overrode the main activity. Only one plugin will be allowed to be the main activity, and any solutions require you to have access to the source code (which in the case of Unity store purchases, you usually do not). This was a big enough of a concern to me, and forced me to come up with a new solution.

- Before you begin -

Before you being this tutorial, you will need the following:

  • A Unity Android application (I will be starting with a blank project)
  • Eclipse, or another javascript development application
  • A Google AdMob or AdSense account (You can open one here: http://www.google.com/ads/admob/)
  • The Google AdMob SDK (This tutorial uses version 6.2.1) - A copy of this will need to be in your Assets/Plugins/Android directory
  • An Android device (Android plugins will not load in the Unity ditor)

Step 1: Preparing your lugin

Open up Eclipse (or which ever JS environment you are using) and create a new android application project. On the second screen in Eclipse, Fill in the application, project and package name to what ever you would like for the name of your project, and if you have an option for theme, be sure to select "none". Finally make sure you deselect create activity, to ensure you begin with a blank project.

Screens 1, 2 and 3 during the new project wizard in Eclipse

Click Finish to have eclipse make your project for you. It shouldn't look like much at this point, as there are no current classes or interfaces defined for you, but Eclipse has done some of the work to ensure the proper Android libraries have been imported with you.

Next, we will add the additional libraries that you will need to access some of the Unity and AdMob javascript. To do this, we must edit the java build path for our project. Open up the project properties for your new project. (Project -> Properties, or right click on the project in the package explorer, and click on Properties). Navigate to Java Build Path, and click on the Libraries tab. This window should have 2 entries already. Android 4.2 and Android Dependencies. We are going to ad 2 more.

Click on the button "Add External JARs". First, add the Unity player classes JAR file, which is located at <UnityInstallPath>\Editor\Data\PlaybackEngines\Androidplayer\bin\classes.jar. Next, add the Google Ad Mobs SDK, which will be where ever you saved it on your local machine.

After adding both .jar files, your Libraries tab should look something like this.

After adding both .JAR files, click on Order and Export and make sure that the two new .jars will be exported with your new .jar file.

Click OK to close the window, and apply your changes. Your plugin is now ready for some code.

Step 2: Code The Plugin

Create a new empty class, with the same name as your project (in my example, I am using AdMob). Do not override or implement any other class. Make sure to give it the package name of your plugins package. Add a constructor, but leave it blank for now. You should have something that looks like this:

package com.example.AdMob

public class AdMob
{
//Constructor
AdMob()
{
}
}

Now that we have our main class and constructor, let's build and display our first Ad. First, we will need to add 3 global variables:

  • private String pubID - Your public AdMob ID. Make sure this is correct, or you wont get any credit for the Ad.
  • private Activity activity
  • private AdView adView
  • private LinearLayout layout
package com.example.admob;

//All of the imports that are needed for this tutorial are added here.
import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;
import com.unity3d.player.UnityPlayer;
import android.app.Activity;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;

public class admob {
private String pubID = "YOURADMOBPUBLICIDGOESHERE"; //Your public AdMob ID. Make sure this is correct, or you wont get any credit for the Ad.
private Activity activity; //Store the android main activity
private AdView adView; //The AdView we will display to the user
private LinearLayout layout; //The layout the AdView will sit on
//Constructor
admob()
{
}
}

Make sure to replace the string in pubID to make that of your AdMob account id. Failure to do so could make ads fail to show up, or fail to give you credit.

Let's start building our constructor function by adding the line activity = UnityPlayer.currentActivity; This will set our local variable activity to the current Android activity that the game uses. Next, we want to make sure that building and showing our AdMobs only happens inside the UI thread of our application. For that, we utilize the function runOnUiThread() inside our activity object. Your constructor function should look something like this:

//Constructor
public AdMob() {
activity = UnityPlayer.currentActivity;

activity.runOnUiThread(new Runnable() {
public void run(){
//Code in here will run on the UI thread of this application
}
});
}

In order to show our ad, we need to define a layout to add to the activity and build the AdView to add to the newly created layer. Instead of going into to much detail, I think it's best to just show you the code, as it is pretty self explanatory.

//Constructor
public AdMob() {
activity = UnityPlayer.currentActivity;

activity.runOnUiThread(new Runnable() {
public void run(){
layout = new LinearLayout(activity);

activity.addContentView(layout, new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
adView = new AdView(activity, AdSize.SMART_BANNER, pubID);
adView.loadAd(new AdRequest());

layout.addView(adView.getRootView(), new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
});
}

One thing to note in the above code, when we create a new AdView, the 2nd parameter is AdSize.SMART_BANNER, this can be changed to a variety of options, and you should change it depending on what you want the Ad to look like. SMART_BANNER is a good default, because it will use a banner that will fit perfectly along from edge to edge on your screen, regardless of device size or screen resolution and ratio. To learn more about smart banners, and other options for your ad size, take a look here.

Our plugin is now ready to be exported and tested.

Step 3: Exporting The Plugin

Exporting of our plugin is handled in eclipse by highlighting the project you want to export in the project explorer, and selecting File->Export (or right clicking on the project in the explorer and selecting Export). In the first window, make sure to select JAR file from the options. Click Next to bring up the File Specification window. Here, make sure the AdMob project we created is checked, and our export destination is our Unity projects Assets\Plugins\Android folder. Name it AdMob.jar, and click Finish. The wizard will pack up the JAR file, making it available for our Unity project.

Pages 1 and 2 from the Export Wizard

Important Tip If you haven't already, now is a good time to move a copy of the AdMob SDK to the Assets/Plugins/Android directory.

Step 4: Calling Our Plugin From Unity

Now that we have a JAR plugin for unity, we just need to call it from somewhere in our Unity project. Start by creating a new javascript file in unity. I'm going to name is AdMobController (the .js extension is added for you automatically). Open up the new file in your favorite development environment (the default that comes with Unity is MonoDevelop, and is what I will be using) and immediately erase the entire contents of the file. We are going to replace the templated code with our own to make it operate as a MonoBehaviour.

#pragma strict

public class AdMobController extends MonoBehaviour {
private static var s_Controller : AdMobController;
function Awake()
{
if(s_Controller == null)
s_Controller = this;
}
}

I choose to extend MonoBehaviour, because we don't want to accidentally create multiple duplicated ads on our application. Documentation on what a MonoBehaviour is can be found here.

To activate our new plugin, we need to create a new AndroidJavaObject, and by using our package name, we can have it cast to the AdMob type we created in our JAR file. 

public class AdMobController extends MonoBehaviour {
private static var s_Controller : AdMobController;
private static var jo:AndroidJavaObject;

function Awake()
{
s_Controller = this;
#if UNITY_ANDROID
jo = new AndroidJavaObject("com.example.admob.AdMob");
#endif
}
}

Tip AndroidJavaObject is the Unity representation of a generic instance of java.lang.object. More documentation on this can be found here and here if you are interested in learning more about Objects.

Step 5: Modifying the Manifest

AdMob obviously needs access to the internet in order to run, and any Android application attempting to pull any information from the internet needs to ask permission via it's AndroidManifest.xml file. Unity will usually create it's own AndroidManifest.xml file when packaging your project, but also allows for you to override the one it creates with one you define inside of the Assets/Plugins/Android folder. You can either create one from scratch, or copy over the default one that unity has created for your project.

I recommend coping over the default, as Unity will have already tailored some of it for your project, and that way we wont cause any unexpected errors due to forgetting some line in the XML file. To get the default, make a build in Unity, and let it complete and save. Then look in your projects temp/stagingarea folder. There should be a AndroidManifest.xml file generated for you. Copy that to your projects Assets/Plugins/Android folder, and edit it in monodevelop.

Once you have your own working Manafest.xml file defined in your project, add the following two permissions to it directly inside of the <manifest> </manifest> XML tags.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

You are also going to need to add the AdMob activity to the list of activities in the manifest. Add the following XML markup to the list of activities already defined in your manifest.

<activity android:name="com.google.ads.AdActivity" 
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
</activity>

The last manifest modification is to turn ForwardNativeEventsToDalvik to true on our UnityPlayerNativeActivity. Doing so will allow our Ad's to receive clicks. Find the line that resembles <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" /> and change it to read <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />

Save your changes, and return to Unity. Sadly, the Ad's will not show up in our Unity Editor, but we can check them out on our test Android device. Simply make a build, install on your device and press play. You should now have a clickable Ad showing on your Android application!

I hope you found the following tutorial informative, and if you have any trouble understanding or implementing something related to AdMob, please write a comment below, or contact me directly through the contact page and I will respond as quickly as I can!

Downloads

For your reference, the source codes used in this tutorial can be found here:

Unity Package (.unitypacakge 5kb): here (Last Uploaded April 3, 2013)

Source code for Plugin (.rar 362kb): here (Last Uploaded April 3, 2013)

You can also play the game the implements a solution very similar to this here

Happy Coding!