Unfilled Recovery inApp implementation

Last edited: 2025/05/29


Android: Kotlin

Key Components

Functions:

Methods:

Implementation Details

1. AdListener Setup

Attach an AdListener to the existing ad request. If the GAM’s response is empty, the listener will trigger the Unfilled Recovery.

adView.adListener = object: AdListener() {
   override fun onAdFailedToLoad(adError : LoadAdError) {
       removeAdFromLayout(adView)
       adView.destroy()
       createSecondAd(publisherAdUnitId)
   }
}
adView.loadAd(adRequest)

2. Creating an Unfilled Recovery Ad unit

If AdListener detects an empty response from GAM, createSecondAd() generates a new (Unfilled Recovery) ad request. createSecondAd() method takes a String containing the publisher's ad unit path as a parameter.

private fun createSecondAd(publisherAdUnitId: String) {
   val adView = AdManagerAdView(this)
   adView.setAdSize(AdSize.BANNER)
   adView.adUnitId = "Unfilled_Recovery_ad_unit_ID"
   addAdToLayout(adView)
   val adRequest: AdManagerAdRequest = AdManagerAdRequest.Builder()
       .addCustomTargeting("yb_ur_adunitpath", publisherAdUnitId)
       .build()
   adView.loadAd(adRequest)
}

3. Layout Handling

Ensure the original Ad unit is removed before injecting a new one (injecting Unfiled Recovery ad):

private fun removeAdFromLayout(adView: AdManagerAdView) {
   val constraintLayout: ConstraintLayout = findViewById(R.id.main_layout)
   constraintLayout.removeViewInLayout(adView)

To insert a new ad:

private fun addAdToLayout(adView: AdManagerAdView) {
   adView.id = View.generateViewId()
   val constraintLayout: ConstraintLayout = findViewById(R.id.main_layout)
   constraintLayout.addView(adView)
   val set = ConstraintSet()
   set.clone(constraintLayout)
   set.connect(adView.id, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT)
   set.connect(adView.id, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT)
   set.applyTo(constraintLayout)
}

Full Implementation Example

private fun createFirstAd() {
   val publisherAdUnitId = "Publisher_ad_unit_ID"
   val adView = AdManagerAdView(this)
   adView.setAdSize(AdSize.BANNER)
   adView.adUnitId = publisherAdUnitId
   addAdToLayout(adView)
   val adRequest = AdManagerAdRequest.Builder().build()
   adView.adListener = object: AdListener() {
       override fun onAdFailedToLoad(adError : LoadAdError) {
           removeAdFromLayout(adView)
           adView.destroy()
           createSecondAd(publisherAdUnitId)
       }
   }
   adView.loadAd(adRequest)
}

private fun createSecondAd(publisherAdUnitId: String) {
   val adView = AdManagerAdView(this)
   adView.setAdSize(AdSize.BANNER)
   adView.adUnitId = "Unfilled_Recovery_ad_unit_ID"
   addAdToLayout(adView)
   val adRequest: AdManagerAdRequest = AdManagerAdRequest.Builder()
       .addCustomTargeting("yb_ur_adunitpath", publisherAdUnitId)
       .build()
   adView.loadAd(adRequest)
}

private fun addAdToLayout(adView: AdManagerAdView) {
   adView.id = View.generateViewId()
   val constraintLayout: ConstraintLayout = findViewById(R.id.main_layout)
   constraintLayout.addView(adView)
   val set = ConstraintSet()
   set.clone(constraintLayout)
   set.connect(adView.id, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT)
   set.connect(adView.id, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT)
   set.applyTo(constraintLayout)
}

private fun removeAdFromLayout(adView: AdManagerAdView) {
   val constraintLayout: ConstraintLayout = findViewById(R.id.main_layout)
   constraintLayout.removeViewInLayout(adView)
}

Notes on Integration


Android: Java

Key Components

Classes & Methods:

Implementation Details

1. AdListener Setup

Attach an AdListener to the existing ad request. If the GAM’s response is empty, the listener will trigger the Unfilled Recovery.

adView.setAdListener(new AdListener() {
    @Override
    public void onAdFailedToLoad(LoadAdError adError) {
        removeAdFromLayout(adView);
        adView.destroy();
        createSecondAd(publisherAdUnitId);
    }
});
adView.loadAd(adRequest);

2. Creating an Unfilled Recovery Ad unit

If AdListener detects an empty response from GAM, createSecondAd() generates a new (Unfilled Recovery) ad request. createSecondAd() method takes a String containing the publisher's ad unit path as a parameter.

private void createSecondAd(String publisherAdUnitId) {
    AdManagerAdView adView = new AdManagerAdView(this);
    adView.setAdSize(AdSize.BANNER);
    adView.setAdUnitId("Unfilled_Recovery_ad_unit_ID");
    addAdToLayout(adView);

    AdManagerAdRequest adRequest = new AdManagerAdRequest.Builder()
        .addCustomTargeting("yb_ur_adunitpath", publisherAdUnitId)
        .build();

    adView.loadAd(adRequest);
}

3. Layout Handling

Ensure the original Ad unit is removed before injecting a new one (Unfilled Recovery ad).

To remove an ad:

private void removeAdFromLayout(AdManagerAdView adView) {
    ConstraintLayout constraintLayout = findViewById(R.id.main_layout);
    constraintLayout.removeViewInLayout(adView);
}

To insert a new ad:

private void addAdToLayout(AdManagerAdView adView) {
    adView.setId(View.generateViewId());
    ConstraintLayout constraintLayout = findViewById(R.id.main_layout);
    constraintLayout.addView(adView);

    ConstraintSet set = new ConstraintSet();
    set.clone(constraintLayout);
    set.connect(adView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT);
    set.connect(adView.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT);
    set.applyTo(constraintLayout);
}

Full Implementation Example

private void createFirstAd() {
    final String publisherAdUnitId = "Publisher_ad_unit_ID";
    final AdManagerAdView adView = new AdManagerAdView(this);
    adView.setAdSize(AdSize.BANNER);
    adView.setAdUnitId(publisherAdUnitId);
    addAdToLayout(adView);

    AdManagerAdRequest adRequest = new AdManagerAdRequest.Builder().build();

    adView.setAdListener(new AdListener() {
        @Override
        public void onAdFailedToLoad(LoadAdError adError) {
            removeAdFromLayout(adView);
            adView.destroy();
            createSecondAd(publisherAdUnitId);
        }
    });

    adView.loadAd(adRequest);
}

private void createSecondAd(String publisherAdUnitId) {
    AdManagerAdView adView = new AdManagerAdView(this);
    adView.setAdSize(AdSize.BANNER);
    adView.setAdUnitId("Unfilled_Recovery_ad_unit_ID");
    addAdToLayout(adView);

    AdManagerAdRequest adRequest = new AdManagerAdRequest.Builder()
        .addCustomTargeting("yb_ur_adunitpath", publisherAdUnitId)
        .build();

    adView.loadAd(adRequest);
}

private void addAdToLayout(AdManagerAdView adView) {
    adView.setId(View.generateViewId());
    ConstraintLayout constraintLayout = findViewById(R.id.main_layout);
    constraintLayout.addView(adView);

    ConstraintSet set = new ConstraintSet();
    set.clone(constraintLayout);
    set.connect(adView.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT);
    set.connect(adView.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT);
    set.applyTo(constraintLayout);
}

private void removeAdFromLayout(AdManagerAdView adView) {
    ConstraintLayout constraintLayout = findViewById(R.id.main_layout);
    constraintLayout.removeViewInLayout(adView);
}

Notes on Integration


iOS / Swift

in progress

On this page: