Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [Android] Displaying ads

This thread is locked; no one can reply to it. rss feed Print
[Android] Displaying ads
kenmasters1976
Member #8,794
July 2007

Sorry for all the recent Android threads but there's literally no better place on the internet to ask for Allegro related stuff.

This time I'm trying to display ads in my Allegro application. I've read the Android documentation on the subject and made all the necessary changes; the basic steps to include ads are relatively easy, it did almost sound too good to be truth and, indeed, things are never that easy when you're using free open-source libraries. Upon following the instructions, no ads were displayed in the Allegro application. logcat flooded the console with so much information it is hard to tell what's going on but I guess the most relevant info in this case was the following message:

08-15 22:46:25.447  4503  4503 I Ads     : Ad is not visible. Not refreshing ad.
08-15 22:46:25.447  4503  4503 I Ads     : Scheduling ad refresh 60000 milliseconds from now.

I tried to rule out that the ads not displaying was caused by a problem with my setup or the Android emulator so I modified the default Android Studio "Hello world" project to include ads and it worked as expected in the emulator.

Why are the ads not being displayed when using Allegro? Is it possible at all to use Android ads with Allegro?.

Elias
Member #358
May 2000

What type of ads are you using? Fullscreen ads are indeed very easy and they will show over the Allegro view just fine.

If you want your ad to be shown alongside Allegro content you have to add it to the view which is a bit more work.

Can you show your code?

--
"Either help out or stop whining" - Evert

kenmasters1976
Member #8,794
July 2007

I basically followed the Android AdMob guide which consists of making some small changes to the build.gradle file:

...
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'com.google.android.gms:play-services-ads:19.3.0'
}

Updating AndroidManifest.xml:

<manifest>
    <application>
        ...
        <!-- Sample AdMob App ID: ca-app-pub-3940256099942544~3347511713 -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>
    </application>
</manifest>

Finally, overriding onCreate() in my project's MainActivity.java:

#SelectExpand
1... 2public class MainActivity extends AllegroActivity { 3 private AdView mAdView; 4 5 ... 6 @Override 7 public void onCreate(Bundle savedInstanceState) { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.activity_main); 10 11 MobileAds.initialize(this, "ca-app-pub-3940256099942544~3347511713"); 12 mAdView = findViewById(R.id.adView); 13 AdRequest adRequest = new AdRequest.Builder().build(); 14 mAdView.loadAd(adRequest); 15 } 16}

All this as described in the Android guide, using BANNER style ads in the layout defined in the activity_main.xml file. Since banner ads are the first option in the guide, I thought those were easier to implement and haven't really tried the other ones. Also, banner ads really fit into what I wanted to accomplish.

Elias said:

If you want your ad to be shown alongside Allegro content you have to add it to the view which is a bit more work.

I found this question on SO which describes just that but the AllegroSurface is private in AllegroActivity so I couldn't try what that link describes, not without modifying the Allegro source, which might be worth a try, though.

[EDIT:] I tried to reproduce the code in the SO link. I couldn't define the layout in my own MainActivity.onCreate() because the AllegroSurface is not created at that point. So I actually had to edit the Allegro source to edit AllegroActivity.java and define the layout inside the createSurface() method, where the AllegroSurface is actually created. I did this with a dirty test code where I create the AdView object in my own project's MainActivity.onCreate() and store the AdView reference in a variable created for that purpose in AllegroActivity:

MainActivity.java#SelectExpand
1@Override 2public void onCreate(Bundle savedInstanceState) { 3 MobileAds.initialize(this, ADS_APP_ID); 4 mAdView = new AdView(this); 5 ((AdView)mAdView).setAdSize(AdSize.BANNER); 6 ((AdView)mAdView).setAdUnitId(AD_UNIT_ID); 7 super.onCreate(savedInstanceState); 8 ... 9}

In AllegroActivity, in turn, I define the layout in the createSurface() method:

AllegroActivity.java#SelectExpand
1public class AllegroActivity extends Activity { 2 ... 3 // Had to use ViewGroup instead of AdView 4 // to avoid errors when rebuilding Allegro 5 protected ViewGroup mAdView = null; 6 7 void createSurface() 8 { 9 try { 10 Log.d("AllegroActivity", "createSurface"); 11 surface = new AllegroSurface(getApplicationContext(), 12 getWindowManager().getDefaultDisplay(), this); 13 14 SurfaceHolder holder = surface.getHolder(); 15 holder.addCallback(surface); 16 holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); 17 //setContentView(surface); 18 19 LinearLayout layout = new LinearLayout(this); 20 layout.setOrientation(LinearLayout.VERTICAL); 21 layout.addView(surface); 22 if (mAdView != null) 23 layout.addView(mAdView); 24 setContentView(layout); 25 Log.d("AllegroActivity", "createSurface end"); 26 } catch (Exception x) { 27 Log.d("AllegroActivity", "createSurface exception: " + x.getMessage()); 28 } 29 } 30 31 ... 32}

After doing this, now the error I get is the following:

W/Ads     ( 2294): Not enough space to show ad. Needs 320x50 dp, but only has 533x0 dp.

Not sure if this is a step in the right direction or not, though, but it looks like the whole thing might have to do with the application layout definition. Considering that, on Android, al_create_display() returns a display with a size that's not necessarily the same you requested anyway, couldn't the AllegroActivity layout setup honour the layout defined in the project's XML file? That way, I think, you'd get an arbitrary sized display but, by honouring the layout, you could have banner ads working out-of-the-box in Allegro with minimum effort. Just a thought, though, as I don't really know if that'll work.

Elias
Member #358
May 2000

Interstitials are the easiest since they have their own view and will just work and show on top of Allegro.

In your case, yes, you'd have to modify the Allegro source to either have your "mAdView" on top of the OpenGL surface or next to it. Otherwise you either display Allegro's view, or yours with the ads, but not both together.

It's probaby a good idea to always use a view hierarchy in Allegro and in the user's MainActivity.java - by default it would have just Allegro's OpenGL view. But it would then be easy to add other views - in fact your code would then work. Just not what Allegro is doing currently. Maybe you can figure out how to make that change, otherwise I might give it a try at some point.

[edit:] Which is basically what you said in your edit :) I haven't looked what needs changed, but yeah, the idea would be to use an XML layout file which has the OpenGL view in it.

--
"Either help out or stop whining" - Evert

kenmasters1976
Member #8,794
July 2007

By changing LinearLayout to RelativeLayout in my previous post edit, I got the banner ads to finally display alongside Allegro. The ads appear on top of the Allegro display, which is actually a good thing as that's just what I wanted. It still needs some more work as the ads appear on the top-left and I want them to appear centered at the bottom but I guess that's going to be comparatively easier.

I guess with a little more work, the code above could be integrated with Allegro to make banner ads easy to use out-of-the-box.

This post has lots of edits, scroll to the bottom for the latest status.
[EDIT:] Oh, and by the way, I will look into interstitial ads, too. But it's good to know that I can have banner ads working with Allegro.

[EDIT 2:] Understanding how the layouts work took me longer than I expected but was finally able to move the banner ads to the bottom of the display with the following code:

AllegroActivity.java#SelectExpand
1public class AllegroActivity extends Activity { 2 ... 3 protected ViewGroup mAdView = null; 4 protected RelativeLayout.LayoutParams mAdViewParams = null; 5 6 void createSurface() 7 { 8 try { 9 Log.d("AllegroActivity", "createSurface"); 10 surface = new AllegroSurface(getApplicationContext(), 11 getWindowManager().getDefaultDisplay(), this); 12 13 SurfaceHolder holder = surface.getHolder(); 14 holder.addCallback(surface); 15 holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); 16 17 RelativeLayout layout = new RelativeLayout(this); 18 layout.addView(surface); 19 if (mAdView != null) { 20 if (mAdViewParams != null) 21 layout.addView(mAdView, mAdViewParams); 22 else layout.addView(mAdView); 23 } 24 setContentView(layout); 25 Log.d("AllegroActivity", "createSurface end"); 26 } catch (Exception x) { 27 Log.d("AllegroActivity", "createSurface exception: " + x.getMessage()); 28 } 29 } 30 ... 31}

MainActivity.java#SelectExpand
1@Override 2public void onCreate(Bundle savedInstanceState) { 3 MobileAds.initialize(this, ADS_APP_ID); 4 mAdView = new AdView(this); 5 ((AdView)mAdView).setAdSize(AdSize.BANNER); 6 ((AdView)mAdView).setAdUnitId(AD_UNIT_ID); 7 mAdViewParams = new RelativeLayout.LayoutParams(640, 100); 8 mAdViewParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE); 9 mAdViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 10 super.onCreate(savedInstanceState); 11 ... 12}

The 640x100 size for the AdView I just chose it randomly with a size large enough to hold the banner-style ads, whose size defaults to 320x50 pixels.

Speaking of Android ads, what's the difference between Google AdMob and Google Ad Manager?.

[EDIT 3:] Some more details in case someone finds them useful. If you want to use the layout alignment settings that are relative to other views and not the parent, you have to assign the Allegro surface an ID in AllegroActivity, so you can then use the ID to align the ad relative to the Allegro surface in your own project's MainActivity, for example:

// In AllegroActivity.java
surface.setId(0xA11E);  // Any int ID

// In MainActivity.java
mAdViewParams.addRule(RelativeLayout.ALIGN_BOTTOM, 0xA11E);

The AdView size has to be defined in physical pixels, not the standard sizes defined in the documentation. That is, the default LARGE_BANNER size is 320x100 but it is displayed in the emulator with a size of 480x150, so you have to define your AdView size to the right size, otherwise it won't be displayed. Currently, the solution I've used is to initialize the AdView like this instead of using hardcoded values:

AdSize adSize = ((AdView)mAdView).getAdSize();
mAdViewParams = new RelativeLayout.LayoutParams(adSize.getWidthInPixels(getApplicationContext()), 
adSize.getHeightInPixels(getApplicationContext()));

[EDIT 4:] Sorry for bumping this thread again but after doing everything described in the previous edits, I thought I had banner ads finally working and they do actually work but, in an issue kinda related to this previous thread, when I use ads and try to terminate the application with the Back button, the Allegro surface image gets stuck on the screen and I have to force it to disappear by clicking the Home button. This, of course, is not a good thing. I guess it has something to do with the way I'm using the Android Layouts and Views but I've tried lots of variants to remove the views from the layout with no success, for example, the following doesn't work:

AllegroActivity.java#SelectExpand
1void destroySurface() { 2 ... 3 layout.removeView(mAdView); 4 layout.removeView(surface); 5 surface = null; 6 ... 7}

The only thing that I've been able to do about it so far is to replicate the default Allegro behavior when destroying the AllegroSurface, like this:

AllegroActivity.java#SelectExpand
1void destroySurface() { 2 layout.removeView(mAdView); 3 layout.removeView(surface); 4 setContentView(surface); // Recreates the content view originally used in onCreate() 5 ViewGroup vg = (ViewGroup)(surface.getParent()); 6 vg.removeView(surface); 7 surface = null; 8}

Any idea why this works but other options won't? I've also noticed in logcat that by doing what the default Allegro code does (that is, removing the surface from the surface.getParent() ViewGroup), the method AllegroSurface.surfaceDestroyed() gets called automatically but by removing the surface from the layout it won't...?.

[EDIT 5:] After spending hours fighting with this issue, trying lots of combinations for creating/destroying the layouts/views, in the end, and out of ideas, I tried to call finish() at the end of MainActivity.destroySurface() and magically everything seems to be working fine now. It even solved the issue with the Recent apps preview described in the other thread. The application behaves as expected: the Home button stops the application and clicking its preview restores the application to its previous state; on the other hand, closing the application with the Back button kills the application and clicking its preview restarts it; this is the expected behavior and even the preview is preserved correctly.

I'm not sure why this works at all or if it is the right thing to do but after hours of struggle, I'm happy with the result. Any comments? Is this OK or it isn't?.

Thanks.

Go to: