Admob on Android: banner space not reserved before loading
Asked Answered
J

2

6

We have been using AdMob on our Android app for more than 4 years. In the last days, we encountered an issue with AdMob, without modifying any code.

As you can see from the picture below:

  • PREVIOUSLY, the banner space was reserved, before the banner was loaded
  • NOW, the banner space is not reserved before loading, creating a very annoying experience for the user, who sees content shifting down after the banner is loaded

enter image description here

===

Here is a description of our implementation:

we are placing our banner about 20% top of the screen of a fragment, inside a LinearLayout "banner_container"

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
....
<LinearLayout android:id="@+id/banner_container"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
....
</LinearLayout>

on Fragment's "onCreateView" we are adding the banner to the container

@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

...

adView = new AdView(getActivity()); 
adView.setAdSize(AdSize.SMART_BANNER);
adView.setAdUnitId(AD_UNIT_ID);

LinearLayout mBannerContainer = rootView.findViewById(R.id.banner_container); 
mBannerContainer.setVisibility(View.VISIBLE); 
mBannerContainer.addView(adView);

AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR) .build();

adView.loadAd(adRequest);

...

}

===

How can we revert to the situation where the banner space is already reserved on loading?

Juback answered 6/11, 2018 at 5:8 Comment(4)
Why are you using visibility to "gone" when layout is loading. Instead u can use invisible for banner_containerHabsburg
Hi @DharakBhatt, the reason is because it defaults to gone for premium users. However, I just tried to changed it to visible in the xml layout, but the same happens (consider that it is set to visibile in the onCreateView anyway). I think it depends on the layout_height which is wrap_content. For some reason, previously AdMob was setting the height of the banner even before the banner it was loaded, and now not.Juback
@DanieleB Did you ever figure anything out on this? This is causing me to be penalized for accidental clicks.Secondbest
Hi @Steve M, I could not find a solution, apart from manually presetting the height of the linear layoutJuback
P
14

Since Admob does not reserve the banner height before loading it, the solution seems to be to do it manually.

According to the Admob guide for Banner Ads:

Smart Banners are ad units that will render screen-wide banner ads on any screen size across different devices in either orientation. Smart Banners help deal with increasing screen fragmentation across different devices by "smartly" detecting the width of the phone in its current orientation, and making the ad view that size.

Three ad heights (in dp, density-independent pixel) are available:

32 - used when the screen height of a device is less than 400 50 - used when the screen height of a device is between 400 and 720 90 - used when the screen height of a device is greater than 720

Solution 1

You know the height using below method:

    public static int getAdViewHeightInDP(Activity activity) {
         int adHeight = 0;

         int screenHeightInDP = getScreenHeightInDP(activity);
         if (screenHeightInDP < 400)
             adHeight = 32;
         else if (screenHeightInDP >= 400 && screenHeightInDP <= 720)
             adHeight = 50;
         else
             adHeight = 90;

         return adHeight;
     }
    

     public static int getScreenHeightInDP(Activity activity) {
         DisplayMetrics displayMetrics = ((Context) activity).getResources().getDisplayMetrics();
    
         float screenHeightInDP = displayMetrics.heightPixels / displayMetrics.density;
    
         return Math.round(screenHeightInDP);
     }

In your "banner_container" remove:

android:visibility="gone"

Change Fragment "onCreateView":

    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

         ...

         adView = new AdView(getActivity()); 
         adView.setAdSize(AdSize.SMART_BANNER);
         adView.setAdUnitId(AD_UNIT_ID);

         LinearLayout mBannerContainer = rootView.findViewById(R.id.banner_container); 
         mBannerContainer.setLayoutParams(
              new LinearLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            getAdViewHeightInDP(this.getActivity())
               ));
         )
         mBannerContainer.addView(adView);

         AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR) .build();

         adView.loadAd(adRequest);

         ...

     }

Solution 2

Instead of using the methods "getAdViewHeightInDP" and "getScreenHeightInDP", the method "AdSize.SMART_BANNER.getHeightInPixels (this)" is used.

In your "banner_container" remove:

android:visibility="gone"

Change Fragment "onCreateView":

    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

         ...

         adView = new AdView(getActivity()); 
         adView.setAdSize(AdSize.SMART_BANNER);
         adView.setAdUnitId(AD_UNIT_ID);

         LinearLayout mBannerContainer = rootView.findViewById(R.id.banner_container); 
         mBannerContainer.setLayoutParams(
              new LinearLayout.LayoutParams(
                            ViewGroup.LayoutParams.MATCH_PARENT,
                            AdSize.SMART_BANNER.getHeightInPixels(this.getActivity())
               ));
         )
         mBannerContainer.addView(adView);

         AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR) .build();

         adView.loadAd(adRequest);

         ...

     }
Preciosity answered 21/11, 2018 at 12:45 Comment(3)
Thanks! This helped but I think method 2 is more accurate. LayoutParams height is expected to be an int in terms of pixels. But the 2, 50 and 90 per the Google specs are dp not pixels. So you would need to convert the result of getAdViewHeightInDP to pixels. In the end I found it easiest to just set the height of my adView directly as adView.getLayoutParams().height = AdSize.SMART_BANNER.getHeightInPixels(this);Feer
Solution 2 worked. It saved my time. I don't understand why Google leaves current behaviour which will cause lot of issues.Pebrook
Thanks, solution 2 worked. That change in behavior causes apps to behave in a way against Google policies. Without solution 2, the ads will move or hide content, possibly having users accidentally click on ads.Loutitia
M
4

Just to reiterate from the comment and clarify with codeblock, it was easiest to do this:

LinearLayout layout = (LinearLayout) findViewById(R.id.mainLayout); layout.addView(adView, 0); adView.getLayoutParams().height = AdSize.SMART_BANNER.getHeightInPixels(this);

I really wish Admob informed of this change in behaviour to ad loading so that developers were aware and can avoid accidental clicks.

Mouldon answered 10/1, 2019 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.