0

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.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
Riverside
  • 207
  • 1
  • 12
  • I'm still trying. I'll keep you posted. – Riverside Jul 15 '14 at 07:38
  • Ok. If you don't want to use an interface, call GLGame.showInterstitialAd(). Just make sure you define interstitial and showInterstital() statically – Nana Ghartey Jul 15 '14 at 12:59
  • That's actually what I was working on a while, however same message poping up. Will give it a try tonight again. – Riverside Jul 15 '14 at 14:26
  • The last option didn't work cause the Mainscreen is re-loaded when switching screens. This cause: java.lang.IllegalStateException: isLoaded must be called on the main UI thread. I go have a try with the interface you mentioned – Riverside Jul 15 '14 at 18:44

2 Answers2

1

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;
     }
}
Nana Ghartey
  • 7,901
  • 1
  • 24
  • 26
  • Wow, thanks a lot! It worked in one time. Actually I don't understand what it exactly does so I'm going to do some study about interfaces. Perfect! – Riverside Jul 15 '14 at 19:14
  • Maybe a later reaction now, but I'm having a memory leak now which is hard to solve. The problem I face now is that each time GLGame is started (each activity is calling this GLGame) a new Ad is loaded. So after switching activities I see my memory increasing and multiple logcat outputs showing Ad Finished Loading. I like to remove all old loaded adds, but it seems they al kept in memory cause of the interface. – Riverside Sep 27 '14 at 08:25
  • Remove all old loaded ads? There shouldn't be old ones if your interstitial reference is a global variable. Don't create and show interstital ads and see if that still causes the memory leak. – Nana Ghartey Sep 27 '14 at 08:35
  • The interface is still a little mystery but I'm getting there. If you say it's a global variable then I only need to load it once. I can work on that now. And I've been debugging for a week now on my memory leak. I found two, the first is solved and the second is certainly the admob. No doubt about that. – Riverside Sep 27 '14 at 15:34
  • Fixed, it seems the GC does some cleaning up with the admob. Instead of creating an ad each time, I just call displayinterstitial each time and hopefully an ad is loaded. When this doesn't work (so no Ad in memory), I set the preference so it will reload. It only takes two switches of activity, but that beautifully reduce the amount of ads too. And no leaking memory. Thanks for the direction again Nana, appreciate it. – Riverside Sep 27 '14 at 16:15
0

Please refer to below code.

private void displayAdmobInterstitialAd(InterstitialAd pAd){
    if(pAd.isLoaded()){
        pAd.show();
    }
}

public void popAdmobInterstitialAd(){
    final InterstitialAd adMobInterstitialAd = new InterstitialAd(ResourcesManager.getInstance().activity);
    adMobInterstitialAd.setAdUnitId("Your AD unit ID");
    final AdRequest adRequest = new AdRequest.Builder().build();
    ResourcesManager.getInstance().getActivity().runOnUiThread(new Runnable() {

        @Override
        public void run() {
            adMobInterstitialAd.loadAd(adRequest);
        }
    });

    adMobInterstitialAd.setAdListener(new AdListener() {
        public void onAdLoaded(){
            displayAdmobInterstitialAd(adMobInterstitialAd);
        }
    });
}

I use this method on sceneManager class of my andengine project. just execute loadAd on runOnUiThread... that's all.

my android app

Dalcoms
  • 21
  • 5