Search code examples
androidadmobinterstitial

Show Interstitial ads on a natural breaking point in game


I'm having trouble showing interstitial adds on a natural breaking point in my game. For now I'm able to load and show these interstitial adds, even when I'm changing activities.

My main problem is that I can't decide myself when these adds will show.

I use OpenGl ES and use the badlogic framework. Therefore the mainactivity is called each time over and over when I switch screens.

This is what I created now, by using my shared preferences and a little helper class I'm able to trace in which stage the add is.

  public abstract class GLGame extends Activity implements Game, Renderer {
  enum GLGameState {
    ....  
}
   GLSurfaceView glView;    
   GLGraphics glGraphics;
   ....       
  public InterstitialAd interstitial;

  private static final String AD_UNIT_ID = "****";


@Override 
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...

    glView = new GLSurfaceView(this);
    glView.setRenderer(this);

    setContentView(glView);

    glGraphics = new GLGraphics(glView);

   .... 

// my shared pref is set to 0 when add is not loaded
       if (addcheck.showadd(getApplicationContext())==0){
       interstitial = new InterstitialAd(getApplicationContext());
    interstitial.setAdUnitId(AD_UNIT_ID);

       // Create ad request.
       AdRequest adRequest = new AdRequest.Builder()
       .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
           .addTestDevice("****")
       .build();

    // Begin loading your interstitial.
    // I set my shared pref to 1 to tell the add is loaded, for later use in the game
         interstitial.loadAd(adRequest);
     interstitial.setAdListener(new AdListener(){
          public void onAdLoaded(){
              addcheck.setadd(1,getApplicationContext());
                          }});
    }


 // Somewhere in my game I set the pref to 2, where I want to show the add. 
     if (addcheck.showadd(getApplicationContext())==2&interstitial.isLoaded()){
        displayInterstitial();
 // after showing the add, I put my pref back to 1, so I it wont show later      
        addcheck.setadd(1,getApplicationContext());
            }

}
public void displayInterstitial() {
      if (interstitial.isLoaded()) {
        interstitial.show();
      }
    }

In my case, I will call displayInterstitial from out the same mainactivity, however this mainactivity is re-loaded a few more times. I think the interstitial is not valid anymore cause I'm getting nullpointer error on interstitial.isLoaded()

Here is some logcat output, which is not my main problem.

07-13 21:49:53.009: E/AndroidRuntime(29230): FATAL EXCEPTION: main
07-13 21:49:53.009: E/AndroidRuntime(29230): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.badlogic.androidgames.glbasics/com.glbasics.MainScreen}: java.lang.NullPointerException
07-13 21:49:53.009: E/AndroidRuntime(29230):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956)
07-13 21:49:53.009: E/AndroidRuntime(29230):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)

Someone knows how to show these loaded adds when I want to? The preferences was just an idea I was playing with.


Solution

  • First, to solve the NPE, you must reconstruct the interstitial when the ad is closed or fails to load. You do this onAdClosed() and onAdFailed() callbacks:

      public abstract class GLGame extends Activity implements Game, Renderer{
      public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
           interstitial = new InterstitialAd(GLGame.this);
            interstitial.setAdUnitId("*****");
             reloadInterstitials();
            // Create ad request
            AdRequest adRequest = new AdRequest.Builder().build();
    
            // Begin loading your interstitial
            interstitial.loadAd(adRequest);
      }
    
    private void reloadInterstitials(){
            interstitial.setAdListener(new AdListener() {
                @Override
                public void onAdLoaded() {
                    // TODO Auto-generated method stub
                    super.onAdLoaded();
                }
                @Override
                public void onAdFailedToLoad(int errorCode) {
                    // TODO Auto-generated method stub
                    super.onAdFailedToLoad(errorCode);
                     interstitial = new InterstitialAd(GLGame.this);
                        interstitial.setAdUnitId("*****");
                        // Begin loading your interstitial
                        interstitial.loadAd(new AdRequest.Builder().build());
                        loadInterCallBacks();
                }
    
                @Override
                public void onAdOpened() {
                    // TODO Auto-generated method stub
                    super.onAdOpened();
                }
    
                @Override
                public void onAdClosed() {
                    // TODO Auto-generated method stub
                    super.onAdClosed();
                    interstitial = new InterstitialAd(GLGame.this);
                    interstitial.setAdUnitId("****");
                    loadInterCallBacks();
                    // Begin loading your interstitial
                    interstitial.loadAd(new AdRequest.Builder().build());
                }
    
                @Override
                public void onAdLeftApplication() {
                    // TODO Auto-generated method stub
                    super.onAdLeftApplication();
                }
            });
    
        }
    

    //method to display interstitial

    public void displayInterstitial(){
            if(interstitial.isLoaded())
                interstitial.show();
        }
    

    }

    To answer the main question, you can use a listener to show the loaded ads when you want to.

    Step 1: Define an Interface

    public interface MyInterstitialListener {
    
        public void showInterstitial();
    }
    

    Step 2: Let the GLGame implement the interface:

    public abstract class GLGame extends Activity implements Game, Renderer, MyInterstitialListener{    
    public void showInterstitial() {
         runOnUiThread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                displayInterstitial();
            } });
    }
    

    }

    Then finally in any of the Screen classes, show the ad:

    public class LevelOneScreen extends GLScreen {
    MyInterstitialListener mL;
    
    public LevelOnecreen(Game game) {
            super(game);
        mL = (MyInterstitialListener)game;
        mL.showInterstitial();
    }
    }
    

    You can call MyInterstitialListener#showInterstitial() on a natural breaking point in game. In situations where you'd like to call it in the game loop, use a boolean flag to call it once:

    public void update(float deltaTime) {  //game loop.
         if(!adCalled){ 
         mL.showInterstitial();
         adCalled = true;
         }
    }