Search code examples
javaandroidlibgdxadmobinterstitial

What am I doing wrong, how do I add an interstitial ad


I've been trying to figure out how to add ads to my project for days. I'm hoping that you guys can show me what to do. I am trying to ad the ad after the first round (First time the player dies) After they close the ad; it will allow them to play again.

No ads are appearing and I am getting errors such as:

09-02 17:14:53.825: W/dalvikvm(635): threadid=11: thread exiting with uncaught exception     (group=0x40a13300)
09-02 17:14:53.835: E/AndroidRuntime(635): FATAL EXCEPTION: GLThread 75
09-02 17:14:53.835: E/AndroidRuntime(635): java.lang.NullPointerException
09-02 17:14:53.835: E/AndroidRuntime(635):  at     com.JrodManU.LaserJumper.android.Ad.loadAd(Ad.java:45)
09-02 17:14:53.835: E/AndroidRuntime(635):  at     com.JrodManU.LaserJumper.android.AndroidLauncher.loadAd(AndroidLauncher.java:26)
09-02 17:14:53.835: E/AndroidRuntime(635):  at   com.JrodManU.LaserJumper.LaserJumper.loadAd(LaserJumper.java:36)
09-02 17:14:53.835: E/AndroidRuntime(635):  at com.JrodManU.LaserJumper.screens.InGameScreen.    <init>(InGameScreen.java:51)
09-02 17:14:53.835: E/AndroidRuntime(635):  at     com.JrodManU.LaserJumper.LaserJumper.create(LaserJumper.java:15)
09-02 17:14:53.835: E/AndroidRuntime(635):  at     com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:236)
09-02 17:14:53.835: E/AndroidRuntime(635):  at     android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1505)
09-02 17:14:53.835: E/AndroidRuntime(635):  at     android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)

My classes:

AndroidLauncher

package com.JrodManU.LaserJumper.android;

import android.os.Bundle;

import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.JrodManU.LaserJumper.GameEventListener;
import com.JrodManU.LaserJumper.LaserJumper;

public class AndroidLauncher extends AndroidApplication implements GameEventListener {
    Ad ad = new Ad();
    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
        initialize(new LaserJumper(this), config);
    }

    @Override
    public void showAd() {
        ad.showAd();
    }

    @Override
    public void loadAd() {
        ad.loadAd();
    }

    @Override
    public boolean isShowing() {
        return ad.isShowing();
    }

    @Override
    public boolean isLoaded() {
        return ad.isLoaded();
    }
}

InGameScreen (Screen class)

package com.JrodManU.LaserJumper.screens;

import com.JrodManU.LaserJumper.LaserJumper;

public class InGameScreen implements Screen {
    LaserJumper game;
    boolean firstTime;

    public InGameScreen(LaserJumper game) {
        this.game = game;
        game.loadAd();
        firstTime = true;
    }

    @Override
    public void render(float delta) {
        generalUpdate();
    }

    private void generalUpdate() {
        if(playerDied) {
            if(firstTime && game.isLoaded()) {
                System.out.println("hi");
                game.showAd();
                firstTime = false;
                while(game.isShowing()) {
                    //Waiting for the ad to go away..
                }
        }
    }   

Ad

package com.JrodManU.LaserJumper.android;

import com.JrodManU.LaserJumper.GameEventListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;
import com.google.android.gms.ads.AdListener;

import android.app.Activity;
import android.os.Bundle;

public class Ad extends Activity implements GameEventListener{
    private InterstitialAd mInterstitialAd;
    public static boolean showing;
    public static boolean loaded;    

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mInterstitialAd = new InterstitialAd(this);
        mInterstitialAd.setAdUnitId("*****");
        AdRequest.Builder adRequestBuilder = new AdRequest.Builder();
        adRequestBuilder.addTestDevice(AdRequest.DEVICE_ID_EMULATOR);
        mInterstitialAd.setAdListener(new AdListener() {
            @Override
            public void onAdClosed() {
                showing = false;
            }

            @Override
            public void onAdLoaded() {
                loaded = true;
            }
        });
    }

    public void showAd() {
        if (mInterstitialAd.isLoaded()) {
            mInterstitialAd.show();
            showing = true;
        }
    }

    public void loadAd() {
        AdRequest.Builder adRequestBuilder = new AdRequest.Builder();
        mInterstitialAd.loadAd(adRequestBuilder.build());
    }

    public boolean isShowing() {
        if(showing) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isLoaded() {
        if(loaded) {
            return true;
        } else {
            return false;
        }
    }
}

LaserJumper (main class)

package com.JrodManU.LaserJumper;

import com.JrodManU.LaserJumper.screens.*;
import com.badlogic.gdx.Game;

public class LaserJumper extends Game{
    InGameScreen inGameScreen;
    public Preferences preferences;
    public GameEventListener gameEventListener;
    @Override
    public void create() {
        inGameScreen = new InGameScreen(this);
        setScreen(inGameScreen);
    }

    public void changeToInGame() {
        inGameScreen = new InGameScreen(this);
        setScreen(inGameScreen);
    }

    public LaserJumper(GameEventListener listener) {
        gameEventListener = listener;
    }

    public void showAd() {
        gameEventListener.showAd();
    }

    public void loadAd() {
        gameEventListener.loadAd();
    }

    public boolean isShowing() {
        return gameEventListener.isShowing();
    }

    public boolean isLoaded() {
        return gameEventListener.isLoaded();
    }
}

And finally, the interface GameEventListener

package com.JrodManU.LaserJumper;

public interface GameEventListener {
    public void showAd();
    public void loadAd();
    public boolean isShowing();
    public boolean isLoaded();
}

Solution

  • Your interstitial ad is inside a separate Activity Ad and then you instantiate it directly like this Ad ad = new Ad();

    You should never instantiate Android Activities like that (they way to launch Activities is by using Intents), because Activities have to obey the Activity lifecycle and Android will call through the Activities lifecycle methods.

    The consequence is that the Ad Activity's onCreate() method isn't called and your InterstitialAd has never been instantiated which leads to a NPE later.


    Solution proposal:

    • Don't create an extra activity for the interstitial ad. It is simply not necessary at all. Instead move the Interstitial Ad initialization inside the AndroidLauncher.
    • Use a Handler to manage the showing / hiding of the ad. It is described here: libgdx admob wiki. (The tutorial refers to legacy admob, but the differences to new admob are minimal and I still think it is the best tutorial) It pretty much works the same way as you would do for a normal banner.