Mark Ormesher
Mark Ormesher

Reputation: 2408

An AdView element creates a blank area on some devices?

I have an AdView element in a relatively simple layout, which is shown/hidden depending whether the user has enabled ads, and whether any ads are available.

The RelativeLayout that contains the AdView is hidden by default, and is only shown to the user when onAdLoaded() is called. If the user has disabled ads, or if onAdFailedToLoad() is called, then the RelativeLayout remainds hidden (or is re-hidden if it was shown for some reason previously).

This is working fine on most devices, but for a small number of devices (including a Samsung Galaxy Ace) there is a problem. With ads turned off everything is fine, but if ads are turned on then the AdView takes up the appropriate amount of space, but is completely blank (it's not black, it's just completely invisible).

This is the relevant segment of the layout file:

<RelativeLayout
        android:id="@+id/adContainer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:visibility="gone"
        style="@style/layout_row">

    <!-- AdView is inserted here -->

</RelativeLayout>

@style/layout_row just adds a little margin along the top to keep it off the very top of the screen, but nothing else.

This is the section of the code that creates and inserts the ad (called inside onResume()):

// hide advert by default
findViewById(R.id.adContainer).setVisibility(View.GONE);

// check if ads are turned on
if (prefs.getBoolean("show_ads", true)) {
    // create a new ad view
    AdView adView = new AdView(this);
    adView.setAdSize(AdSize.BANNER);
    adView.setAdUnitId("___ MY ID ___");

    // add it to the relative layout
    ((RelativeLayout) findViewById(R.id.adContainer)).addView(adView);

    // deal with the arrival of ads
    adView.setAdListener(new AdListener() {

        // hide ad block if none could be found
        @Override
        public void onAdFailedToLoad(int errorCode) {
            findViewById(R.id.adContainer).setVisibility(View.GONE);
            super.onAdFailedToLoad(errorCode);
        }

        // show ad block if one was found
        @Override
        public void onAdLoaded() {
            findViewById(R.id.adContainer).setVisibility(View.VISIBLE);
            super.onAdLoaded();
        }

    });

    // request ads
    AdRequest adRequest = new AdRequest.Builder()
            .addTestDevice(AdRequest.DEVICE_ID_EMULATOR) // Emulators
            .addTestDevice("8AFD3F7DD723DA9355EE3B35E8666475") // My Samsung S4 test device
            .build();
    adView.loadAd(adRequest);
} else {
    // hide the ad block
    findViewById(R.id.adContainer).setVisibility(View.GONE);
}

To repeat, this works absolutely fine on most devices, including devices that set the ads to test mode and those that don't. The problem has only appeared so far on a Galaxy Ace, but unfortunately I don't have access to the device to read the logcat.

Can anyone offer me any advice about what might be causing this and what could be done to fix it?

Thanks :)

UPDATE: I put a bright pink background colour on the RelativeLayout to see what was going on, and I found that on the problematic device, the layout was being shown - there's a big pink block in the size and shape of the ad, right where the ad should be. This can only mean that onAdLoaded() is being called, but still no ad is being show. Any ideas?

Upvotes: 0

Views: 1324

Answers (1)

Mark Ormesher
Mark Ormesher

Reputation: 2408

After many attempts at various solutions, I finally wrote a method that takes the last 100 lines of Logcat and prompts the user to do something with them. In this case I asked the Samsung Galaxy Ace owner to email them to me (she's hundreds of miles away, so debugging on my laptop was out of the question).

The problem was so simple I almost kicked myself. Her phone screen is simply too small to display ads. The banner size is 320 x 50dp, but her screen is exactly 320dp wide and my app has 7dp padding around the sides, so the ad was failing to show.

I have two options: detect the screen size and only show ads on devices big enough, or re-arrange the layout to make sure the ads get the full width and avoids the edge padding. I haven't decided which route to take yet.

This brings to light what I think is a major flaw in the AdMob SDK: when an ad cannot be shown because of sizing issues, onAdLoaded() is still called. I believe that this success method should not be called unless and ad is loaded and shown; if the space is to small, I think onAdFailedToLoad() or some other failure method should be invoked.


Ultimately, I settled on a mix of both. I have rearranged the layout to make sure the AdView can have the entire screen width if needed, and I now check the screen size as well:

// hide advert by default
findViewById(R.id.adContainer).setVisibility(View.GONE);
// find the screen width
Display display = getWindowManager().getDefaultDisplay();
int width;
if (android.os.Build.VERSION.SDK_INT >= 13) {
    Point size = new Point();
    display.getSize(size);
    width = size.x;
} else {
    width = display.getWidth();
}
// show advert if they are enabled AND they will fit
if (prefs.getBoolean("show_ads", true) && width>=320) {
    // ads
} else {
    // no ads
}

An ideal solution? Not really. But it works.

Upvotes: 2

Related Questions