Android + Admob = Problems

EDIT: The following post solved my problems: http://forum.unity3d.com/threads/67817-I-will-pay-someone-to-show-me-how-to-integrate-admob – Much appreciating for finding this post again and posting the solution!

I have seen the two threads already available on the forums
http://forum.unity3d.com/threads/62699-Android-AdMob?highlight=android+admob
http://forum.unity3d.com/threads/58620-Unity-Android-amp-Banner-Ads-(AdMob)

, but I’m still having some issues with it. My game just crashes. I’m using the beta tester package located here:
http://beta.unity3d.com/erik/AndroidAdIntegration.unitypackage

I’ve checked the output using adb (I ran it real time to see whats happening). My current guess is that Java isn’t compiling a new version of the plugin, and I’m not quite sure how to get it to do that. I have come this conclusion because I have changed AdPlugin

Here’s some code to give you guys an idea-- you’ll notice that it crashes on line 48:
E/AndroidRuntime( 2219): at com.some_company.plugin.AdPluginActivity.setupAds(AdPluginActivity.java:4

I/DEBUG   ( 1153): Build fingerprint: 'google/passion/passion/mahimahi:2.1/ERD79/22607:user/release-keys'
I/DEBUG   ( 1153): pid: 2219, tid: 2225  >>> com.some_company.plugin <<<
I/DEBUG   ( 1153): signal 11 (SIGSEGV), fault addr 449a8000
I/DEBUG   ( 1153):  r0 44845610  r1 449a8000  r2 000019b8  r3 00000008
I/DEBUG   ( 1153):  r4 8182c570  r5 00000200  r6 00000100  r7 00000200
I/DEBUG   ( 1153):  r8 00000100  r9 449699d8  10 00040000  fp 0011ac48
I/DEBUG   ( 1153):  ip 00000000  sp 4755fd10  lr 8105b704  pc afe0df5c  cpsr 20000010
D/AndroidRuntime( 2219): Shutting down VM
W/dalvikvm( 2219): threadid=3: thread exiting with uncaught exception (group=0x4001b178)
E/AndroidRuntime( 2219): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 2219): java.lang.NoClassDefFoundError: com.qwapi.adclient.android.view.QWAdView
[COLOR=darkorange]E/AndroidRuntime( 2219):     at com.some_company.plugin.AdPluginActivity.setupAds(AdPluginActivity.java:48)[/COLOR]
E/AndroidRuntime( 2219):     at com.some_company.plugin.AdPluginActivity.onCreate(AdPluginActivity.java:29)
E/AndroidRuntime( 2219):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime( 2219):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
E/AndroidRuntime( 2219):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
E/AndroidRuntime( 2219):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
E/AndroidRuntime( 2219):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
E/AndroidRuntime( 2219):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 2219):     at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 2219):     at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime( 2219):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2219):     at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 2219):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime( 2219):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime( 2219):     at dalvik.system.NativeStart.main(Native Method)
I/Process (   71): Sending signal. PID: 2219 SIG: 3
I/dalvikvm( 2219): threadid=7: reacting to signal 3
E/dalvikvm( 2219): Unable to open stack trace file '/data/anr/traces.txt': Permission denied

Now, here is the entirety of AdPluginActivity.java-- to save you some time, I’ll note that line 48 is:
adView.setAdListener( new SimpleAdListener()

Additionally, I print our some debug that does not appear in the Android log above on line 37 (a bunch of H’s)

package com.some_company.plugin;

import com.qwapi.adclient.android.data.Ad;
import com.qwapi.adclient.android.data.Status;
import com.qwapi.adclient.android.requestparams.*;
import com.qwapi.adclient.android.view.QWAdView;

import com.admob.android.ads.AdView;
import com.admob.android.ads.SimpleAdListener;
import com.admob.android.ads.AdManager;

import com.unity3d.player.UnityPlayerActivity;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;

// Both AdMob and Quattro Wireless (and this activity) dumps information to the 'logcat'.
// Please inspect it using 'adb logcat' from the command line/terminal, to track down faulty behavior.

public class AdPluginActivity extends UnityPlayerActivity
{
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setupAds();
    }
    
    final private boolean useQWads = true;
    final private boolean gravityBottom = true;

    private void setupAds()
    {
[COLOR=darkorange]        System.out.println"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");[/COLOR]
        RelativeLayout layout = new RelativeLayout(this);
        addContentView(layout, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));

        if (gravityBottom)
            layout.setGravity(Gravity.BOTTOM);
        
            // Please read http://developer.admob.com/wiki/Android before trying this code,
            // especially the part about how to use test mode, and add test devices (below).
            // Also, a valid publisher id is needed, even in test mode it seems.
            AdView adView = new AdView(this);
[COLOR=darkorange]            adView.setAdListener( new SimpleAdListener()[/COLOR]
            {
                public void onFailedToReceiveAd(com.admob.android.ads.AdView adView)
                {
                    Log.d("AdListener", "onFailedToReceiveAd: " + adView.toString());
                    super.onFailedToReceiveAd(adView);
                }

                public void onFailedToReceiveRefreshedAd(com.admob.android.ads.AdView adView)
                {
                    Log.d("AdListener", "onFailedToReceiveRefreshedAd: " + adView.toString());
                    super.onFailedToReceiveRefreshedAd(adView);
                }

                public void onReceiveAd(com.admob.android.ads.AdView adView)
                {
                    Log.d("AdListener", "onReceiveAd: " + adView.toString());
                    super.onReceiveAd(adView);
                }

                public void onReceiveRefreshedAd(com.admob.android.ads.AdView adView)
                {
                    Log.d("AdListener", "onReceiveRefreshedAd: " + adView.toString());
                    super.onReceiveRefreshedAd(adView);
                }
            } );
            adView.setBackgroundColor(0xff000000);
            adView.setPrimaryTextColor(0xffffffff); 
            adView.setSecondaryTextColor(0xffcccccc);
            adView.setKeywords("Android game");
            adView.setRequestInterval(15);
            adView.setVisibility(android.view.View.VISIBLE);
            adView.requestFreshAd();

//            AdManager.setTestDevices( new String[] { "<add test device ids here>" } );
//            AdManager.setPublisherId( "<add publisher id here>" );

            layout.addView(adView);
    }
}

Now, I’ve tried a couple of things; I noticed on one of the forum posts, someone mentioned changing this:

#!/bin/sh
javac src/com/some_company/plugin/AdPluginActivity.java -classpath [COLOR=darkorange]"/Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/bin/classes.jar;./admob-sdk-android.jar"[/COLOR] -bootclasspath $ANDROID_SDK_ROOT/platforms/android-8/android.jar -d .
jar cvfM plugin.jar com/

To this (same thing as above but no quotes, and semi-colon replaced with colon)

#!/bin/sh
javac src/com/some_company/plugin/AdPluginActivity.java -classpath [COLOR=darkorange]/Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/bin/classes.jar:./admob-sdk-android.jar[/COLOR] -bootclasspath $ANDROID_SDK_ROOT/platforms/android-8/android.jar -d .
jar cvfM plugin.jar com/

That did not work either. I also tried running the above from the terminal:

./build_plugin.sh

(I’m on the dreadful Mac OSX if you haven’t noticed), and this is what I get for an error:

Fatal Error: Unable to find package java.lang in classpath or bootclasspath
com : no such file or directory
java.util.zip.ZipException: ZIP file must have at least one entry
    at java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:304)
    at java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:146)
    at java.util.zip.ZipOutputStream.close(ZipOutputStream.java:321)
    at sun.tools.jar.Main.create(Main.java:468)
    at sun.tools.jar.Main.run(Main.java:180)
    at sun.tools.jar.Main.main(Main.java:1149)

Thanks for your help in advance. If someone stumbles upon this post in the future, I hope it has or does assist you in setting it up admob.

Thanks
-Rob

I was just about to do the logcat output mentioned in the other thread.

The entirety of my build_plugin.sh file looks like this:

#!/bin/sh
javac /Users/jeremyalessi/Documents/Business/AlessiGamesLLC/MidnightStatus/Development/Projects/CrashForCashUnity3/CrashForCash/Assets/Plugins/src/com/some_company/plugin/AdPluginActivity.java -classpath /Applications/Unity/Unity.app/Contents/PlaybackEngines/AndroidPlayer/bin/classes.jar:/Users/jeremyalessi/Documents/Business/AlessiGamesLLC/MidnightStatus/Development/Projects/CrashForCashUnity3/CrashForCash/Assets/Plugins/admob-sdk-android.jar:/Users/jeremyalessi/Documents/Business/AlessiGamesLLC/MidnightStatus/Development/Projects/CrashForCashUnity3/CrashForCash/Assets/Plugins/qwandroidsdk.jar -bootclasspath /Users/jeremyalessi/Documents/Business/AlessiGamesLLC/Tools/Android/android-sdk-mac_86/platforms/android-8/android.jar -d .
jar cvfM plugin.jar com/

This allowed me to rebuild the AdPluginActivity.java file without any errors. The Plugin.jar file and the com folder it builds land up on my user folder ( /Users/jeremyalessi/ ). For me the problem arises when I run the game with my ads. The ads pop up during the splash screen (and the ads register within my AdMob account as I can tell by checking the website) but as soon as the game moves past the splash screen it crashes. Hope this helps!

Your game is crashing because it tries to load the Quattro Wireless SDK code. Please read the AdPluginActivity.java again carefully and you will find a final private boolean useQWads = true defining the different paths in the code. Setting it to false will enable the Admob path.

Unity will never recompile your plugins for you; not native nor Java code. For Java you need to provide the Java code as .jar archive files (with the compiled Java code as .class files inside it). That’s what the build_plugin.sh script is for.

Yes, it is necessary to change the separator character (semi-colon vs colon) when running it on OSX. It is also necessary to actually run the script (or compile it manually, or use and IDE like Eclipse) to create the .class files which then go into the .jar file. All this is actually part of our documentation.

Looks like javac (the Java compiler) can’t find the regular Java packages, so you probably need to add it to the classpath. Or use an IDE (Eclipse) to do this manual labor for you.

Jeremy, if you still have problems please submit your project with plugins and everything attached to a bug report and we will try to take a look at it to make sure Unity’s Android code is not doing anything stupid here.

OK, my problem seems to be project/scene specific. It works just fine with an empty scene.

Actually, while trying this on my mac I noticed that this error usually is a bit of a red herring as it is emitted if javac can’t find all the .jar files added to the -classpath. Please double-check the path to the .jars in your build_plugins.sh; probably you didn’t update the paths to reflect how your system is set up.

Hey erique–

Thanks for the reply; I did do remove the quattro package, but I guess I messed up building the package. I’ll try again with the docs you posted and post back if it fixes my problem.

Thanks :slight_smile:

Alright, I’ve gone through a lot of the docs.

I got Eclipse, installed the NDK, plugins for Eclipse for the android, got Hello World to pop up in the simulator, added classes.jar to the project, and I finally got the example code to compile into a Jar. I’ve also read up on the docs over at Admob. I’ve made progress, but I’ve hit a little road bump again.

I have a couple guesses as to what might be going wrong.

  1. I may have written the android manifest wrong, such that it can’t find AdPluginActivity, and is now crashing.
  2. I am thinking that I need to write some sort of C++ wrapper to call my java code below. However, I didn’t think this was necessary since everything, as far as my experience with AdMob goes, should be called automatically since it is a delegate in the Java Code. The only thing that the plugin should really do is display a little window. I don’t think I need to call anything from Unity.
E/AndroidRuntime(20677): Uncaught handler: thread main exiting due to uncaught exception
[COLOR=darkorange]E/AndroidRuntime(20677): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.some_company.plugin/com.some_company.plugin.AdPluginActivity}: java.lang.ClassNotFoundException: [/COLOR]com.some_company.plugin.AdPluginActivity in loader dalvik.system.PathClassLoader@4470f160
E/AndroidRuntime(20677):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2417)
E/AndroidRuntime(20677):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
E/AndroidRuntime(20677):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
E/AndroidRuntime(20677):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
E/AndroidRuntime(20677):     at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(20677):     at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(20677):     at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime(20677):     at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(20677):     at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(20677):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime(20677):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime(20677):     at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(20677): Caused by: java.lang.ClassNotFoundException: com.some_company.plugin.AdPluginActivity in loader dalvik.system.PathClassLoader@4470f160
E/AndroidRuntime(20677):     at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
E/AndroidRuntime(20677):     at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
E/AndroidRuntime(20677):     at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
E/AndroidRuntime(20677):     at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
E/AndroidRuntime(20677):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2409)
E/AndroidRuntime(20677):     ... 11 more
I/Process (   73): Sending signal. PID: 20677 SIG: 3
I/dalvikvm(20677): threadid=7: reacting to signal 3
E/dalvikvm(20677): Unable to open stack trace file '/data/anr/traces.txt': Permission denied
V/RenderScript_jni(  155): surfaceDestroyed
V/RenderScript(  155): setSurface 0 0 0x0
D/ViewFlipper(  155): updateRunning() mVisible=false, mStarted=true, mUserPresent=true, mRunning=false
I/wpa_supplicant(  763): CTRL-EVENT-SCAN-RESULTS  Ready

Building this plugins seems to have a lot of places for pitfalls-- I’ve read up on the AndroidManifest.XML file, and the various attributes, but I don’t think that I have done anything wrong; And yes, my package is called “com.android.test”.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" android:versionCode="1" android:versionName="1.0" package="com.android.test">
  <uses-sdk android:minSdkVersion="6" />
  <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:anyDensity="true" />
  
  <application android:icon="@drawable/icon"  android:debuggable="true">
	<activity android:name=".AdPluginActivity"
			  android:label="@string/app_name"
			  android:configChanges="keyboardHidden|orientation"
              android:screenOrientation="portrait">
        <intent-filter>
			<action android:name="android.intent.action.MAIN" />
			<category android:name="android.intent.category.LAUNCHER" />
		</intent-filter>
	</activity>
	
    <activity android:name="com.unity3d.player.UnitySoftInputActivity" android:label="@string/app_name" android:screenOrientation="behind" android:windowSoftInputMode="stateAlwaysVisible|adjustPan">
    </activity>
    <activity android:name="com.unity3d.player.UnityVideoPlayerActivity" android:label="@string/app_name">
    </activity>

	<!-- Track Market installs from AdMob ads -->             
	<receiver android:name="com.admob.android.ads.analytics.InstallReceiver" android:exported="true">
		<intent-filter>
			<action android:name="com.android.vending.INSTALL_REFERRER" />
		</intent-filter>
	</receiver>
	
  </application>

  <!-- AdMob SDK requires Internet permission -->
  <uses-permission android:name="android.permission.INTERNET" />

  <!-- Quattro Wireless 'requires' some more permissions -->
  <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

Here is the code I am using. One guess I had was that I didn’t properly name an activity above, but since I have little experience with building plugins or the AndroidManifest.xml, I’m not entirely sure.

package com.android.test;

import com.admob.android.ads.AdView;
import com.admob.android.ads.SimpleAdListener;
import com.admob.android.ads.AdManager;

import com.unity3d.player.UnityPlayerActivity;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.RelativeLayout;

// Both AdMob and Quattro Wireless (and this activity) dumps information to the 'logcat'.
// Please inspect it using 'adb logcat' from the command line/terminal, to track down faulty behavior.

public class AdPluginActivity extends UnityPlayerActivity
{
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setupAds();
    }
    
    final private boolean gravityBottom = true;

    private void setupAds()
    {
    	RelativeLayout layout = new RelativeLayout(this);
        addContentView(layout, new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));

		if (gravityBottom)
			layout.setGravity(Gravity.BOTTOM);
    	
		   
		// Please read http://developer.admob.com/wiki/Android before trying this code,
		// especially the part about how to use test mode, and add test devices (below).
		// Also, a valid publisher id is needed, even in test mode it seems.
        AdView adView = new AdView(this);
        adView.setAdListener( new SimpleAdListener()
        {
    		public void onFailedToReceiveAd(com.admob.android.ads.AdView adView)
    		{
    			Log.d("AdListener", "onFailedToReceiveAd: " + adView.toString());
    			super.onFailedToReceiveAd(adView);
    		}

    		public void onFailedToReceiveRefreshedAd(com.admob.android.ads.AdView adView)
    		{
    			Log.d("AdListener", "onFailedToReceiveRefreshedAd: " + adView.toString());
    			super.onFailedToReceiveRefreshedAd(adView);
    		}

    		public void onReceiveAd(com.admob.android.ads.AdView adView)
    		{
    			Log.d("AdListener", "onReceiveAd: " + adView.toString());
    			super.onReceiveAd(adView);
    		}

    		public void onReceiveRefreshedAd(com.admob.android.ads.AdView adView)
    		{
    			Log.d("AdListener", "onReceiveRefreshedAd: " + adView.toString());
    			super.onReceiveRefreshedAd(adView);
    		}
        } );
        
        adView.setBackgroundColor(0xff000000);
        adView.setPrimaryTextColor(0xffffffff); 
        adView.setSecondaryTextColor(0xffcccccc);
        adView.setKeywords("Beer Pong Classic");
        adView.setRequestInterval(15);
        adView.setVisibility(android.view.View.VISIBLE);
        adView.requestFreshAd();

//	        AdManager.setTestDevices( new String[] { "<add test device ids here>" } );
//	        AdManager.setPublisherId( "<add publisher id here>" );

		layout.addView(adView);

    }
}

Thanks for the replies :slight_smile:

Is there anything new on this since the plugins changed? I was struggling to get it to work before with the example that was given on the google group for the beta, but now I’m totally lost.
It looks like we just add the admod sdk jar file into plugins/android, but I’m kinda guessing at that based one what I’ve read elsewhere. Is there any documentation on this anywhere?
I’m almost at the point of offering to pay someone to show me how to set it up on skype.

try the following thread may be: http://forum.unity3d.com/threads/67817-I-will-pay-someone-to-show-me-how-to-integrate-admob

Hey Wozik, that tutorial solved all of my issues. I don’t know what I did wrong above, but I do know that the thread shows you how to appropriately set up the Admob SDK.

can u plz tell me how to do every thing to setup admob in my application and basic requirement i m not able to get from where i have to start this implementation and one thing more that i have plugin package for unity and i import it and after that what i have to do plz reply

Thanks in advance

Hey my app also crashed when implementing admob but now solve the issue by watching this vedio.