0

I'm trying to put an AdMob banner into my app but half the time it doesn't show any content. The AdListener even receives an call to onAdLoaded and I never get any error.
I noticed that if the ad isn't showing and I put the app in the background somehow the ad starts to show. For example if I:

  1. close and reopen the app
  2. start an fullscreen interstitial ad
  3. start the in-app purchase overlay

All these actions trigger an update that somehow redraws/remeasures the views.
I tried many different things to simulate this in onAdLoaded.

Is it possible that AdMob can't find a matching ad even if I don't get any errors? According to the website the match rate is 98%. The number of impressions is about a third of the requests.

I found more posts with similar issues (all from ~7 years ago) but none of their answers worked in my case:
Admob not showing up until phone is locked
AdMob won't show the banner until refresh or sign in to google plus
Android AdMob: addView doesn't show ad until return to activity
Admob ads appear only after first refresh

I tried to get this to work for over two days. Please take a look at my code, I annotated it with explainations:

MainActivity:

private AdView adView;

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

    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());
    if(privacyPolicyAcceptedAndHasNoPremium()){ //at first i check the shared preferences
        binding.adPlaceholder.setVisibility(View.VISIBLE); //the adPlaceholder starts as GONE when i set it to VISIBLE the rest of the content slides up
        List<String> testDevices = Arrays.asList(AdRequest.DEVICE_ID_EMULATOR, "...");
        RequestConfiguration requestConfiguration = new RequestConfiguration.Builder().setTestDeviceIds(testDevices).build();
        MobileAds.setRequestConfiguration(requestConfiguration);

        MobileAds.initialize(MainActivity.this, initializationStatus -> {});

        adView = new AdView(this); //i create the adView programmatically but using the xml view element causes the same problem
        adView.setAdSize(AdSize.LARGE_BANNER);
        adView.setAdUnitId("...");
        adView.setAdListener(new AdListener() {
            @Override
            public void onAdLoaded() { // this gets called so i think the ad is successfully downloaded from the google server. i put all kinds of code in here to force the adView to show
                //setContentView(binding.getRoot());
                //binding.adPlaceholder.addView(new View(MainActivity.this));
                //binding.adPlaceholder.forceLayout();
                //binding.constraintLayout.requestLayout();
                //adView.invalidate();
                //adView.bringToFront();
                //adView.setVisibility(AdView.GONE);
                //adView.setVisibility(AdView.VISIBLE);
                //adView.setBackgroundColor(Color.TRANSPARENT);
            }
        }
        AdRequest.Builder adRequestBuilder = new AdRequest.Builder();
        binding.adPlaceholder.addView(adView); //i add the adView into the empty LinearLayout. i tried to add it directly to binding.constraintLayout too.
        adView.loadAd(adRequestBuilder.build());
}

activity_main.xml:

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- this is the empty container into which i load the ads. it sits at the bottom of the screen and is not visible before an ad is showing -->
    <LinearLayout
        android:id="@+id/adPlaceholder"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        android:orientation="vertical"
        android:visibility="gone" />

    <!-- this MotionLayout contains the rest of the app (except the toolbar). it slides up when an ad is showing -->
    <androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/motionLayout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layoutDescription="@xml/activity_main_scene"
        app:layout_constraintBottom_toTopOf="@+id/adPlaceholder"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:context=".MainActivity">
    ...
    </androidx.constraintlayout.motion.widget.MotionLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Manifest:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application ...>
    <meta-data
        android:name="com.google.android.gms.ads.APPLICATION_ID"
        android:value="..." />
    ...
</application>

Edit:

enter image description here

einUsername
  • 1,569
  • 2
  • 15
  • 26

1 Answers1

0

I finally found a way that works for me.

I'm just setting the window background color to the color that it already has. This is really fast and doesn't recreate the activity.

However I don't know why this works and why only this worked for me. I guess it updates the views in a similar way to the many other solutions from the other questions.

adView.setAdListener(new AdListener() {
    @Override
    public void onAdLoaded() {
        super.onAdLoaded();
        getWindow().setBackgroundDrawableResource(R.color.background);
    }
}
einUsername
  • 1,569
  • 2
  • 15
  • 26