> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adrop.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Interstitial Ads

> Learn how to implement interstitial ads in your Android app.

## Overview

Interstitial ads are full-screen ads that cover the entire interface of the app. They are best suited for natural transition points in the app, such as game level transitions or content page changes.

### Features

* Full-screen immersive ads
* Remain visible until explicitly closed by the user
* Support for image and video ads
* High visual attention

<Note>
  Use the test unit ID for development: `PUBLIC_TEST_UNIT_ID_INTERSTITIAL`
</Note>

***

## Implementation Steps

Interstitial ads are implemented in 4 steps:

1. **Initialize** - Create AdropInterstitialAd instance
2. **Set Listener** - Configure listener for ad events
3. **Load Ad** - Request and receive ads
4. **Show Ad** - Display the ad on screen

***

## Basic Implementation

### Creating AdropInterstitialAd Instance

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import io.adrop.ads.interstitial.AdropInterstitialAd

  class MainActivity : AppCompatActivity() {
      private var interstitialAd: AdropInterstitialAd? = null

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)

          // 1. Create interstitial ad instance
          interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")
      }
  }
  ```

  ```java Java theme={null}
  import io.adrop.ads.interstitial.AdropInterstitialAd;

  public class MainActivity extends AppCompatActivity {
      private AdropInterstitialAd interstitialAd;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);

          // 1. Create interstitial ad instance
          interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");
      }
  }
  ```
</CodeGroup>

### AdropInterstitialAd Constructor

<ParamField body="context" type="Context" required>
  Android Context object (Activity or Application Context)
</ParamField>

<ParamField body="unitId" type="String" required>
  Ad unit ID (issued from console)
</ParamField>

***

## Setting Listener

To receive ad events, implement and set `AdropInterstitialAdListener`.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import io.adrop.ads.interstitial.AdropInterstitialAdListener
  import io.adrop.ads.model.AdropErrorCode

  class MainActivity : AppCompatActivity() {
      private var interstitialAd: AdropInterstitialAd? = null

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)

          // 1. Create interstitial ad instance
          interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")

          // 2. Set listener
          interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
              override fun onAdReceived(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Interstitial ad received")
              }

              override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e("Adrop", "Interstitial ad failed to receive: $errorCode")
              }

              override fun onAdImpression(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Interstitial ad impression")
              }

              override fun onAdClicked(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Interstitial ad clicked")
              }

              override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Interstitial ad will present")
              }

              override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Interstitial ad did present")
              }

              override fun onAdWillDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Interstitial ad will dismiss")
              }

              override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Interstitial ad dismissed")
                  // Preload next ad
                  loadInterstitialAd()
              }

              override fun onAdFailedToShowFullScreen(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e("Adrop", "Interstitial ad failed to show: $errorCode")
              }
          }

          // 2-1. Set back button callback listener
          interstitialAd?.closeListener = object : AdropInterstitialAdCloseListener {
              override fun onBackPressed(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "Back button pressed")
              }
          }

          // 3. Load ad
          loadInterstitialAd()
      }

      private fun loadInterstitialAd() {
          interstitialAd?.load()
      }
  }
  ```

  ```java Java theme={null}
  import io.adrop.ads.interstitial.AdropInterstitialAdListener;
  import io.adrop.ads.model.AdropErrorCode;

  public class MainActivity extends AppCompatActivity {
      private AdropInterstitialAd interstitialAd;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);

          // 1. Create interstitial ad instance
          interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");

          // 2. Set listener
          interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
              @Override
              public void onAdReceived(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Interstitial ad received");
              }

              @Override
              public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e("Adrop", "Interstitial ad failed to receive: " + errorCode);
              }

              @Override
              public void onAdImpression(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Interstitial ad impression");
              }

              @Override
              public void onAdClicked(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Interstitial ad clicked");
              }

              @Override
              public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Interstitial ad will present");
              }

              @Override
              public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Interstitial ad did present");
              }

              @Override
              public void onAdWillDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Interstitial ad will dismiss");
              }

              @Override
              public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Interstitial ad dismissed");
                  // Preload next ad
                  loadInterstitialAd();
              }

              @Override
              public void onAdFailedToShowFullScreen(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e("Adrop", "Interstitial ad failed to show: " + errorCode);
              }
          });

          // 2-1. Set back button callback listener
          interstitialAd.setCloseListener(new AdropInterstitialAdCloseListener() {
              @Override
              public void onBackPressed(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "Back button pressed");
              }
          });

          // 3. Load ad
          loadInterstitialAd();
      }

      private void loadInterstitialAd() {
          interstitialAd.load();
      }
  }
  ```
</CodeGroup>

***

## Loading Ad

Call the `load()` method to request an ad.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  private fun loadInterstitialAd() {
      interstitialAd?.load()
  }
  ```

  ```java Java theme={null}
  private void loadInterstitialAd() {
      interstitialAd.load();
  }
  ```
</CodeGroup>

The `onAdReceived` callback is called when the ad is successfully loaded, and `onAdFailedToReceive` is called when loading fails.

***

## Showing Ad

Call the `show()` method to display the ad after it's loaded.

### isLoaded Property

A property to check if the ad is loaded. It's recommended to check this value before calling `show()`.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  private fun showInterstitialAd() {
      if (interstitialAd?.isLoaded == true) {
          interstitialAd?.show(this)
      } else {
          Log.d("Adrop", "Ad is not loaded yet")
      }
  }
  ```

  ```java Java theme={null}
  private void showInterstitialAd() {
      if (interstitialAd != null && interstitialAd.isLoaded()) {
          interstitialAd.show(this);
      } else {
          Log.d("Adrop", "Ad is not loaded yet");
      }
  }
  ```
</CodeGroup>

### show Method

<ParamField body="fromActivity" type="Activity" required>
  Activity object to display the ad
</ParamField>

***

## AdropInterstitialAd Properties

### unitId

Returns the ad unit ID.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  val unitId: String = interstitialAd?.unitId ?: ""
  ```

  ```java Java theme={null}
  String unitId = interstitialAd.getUnitId();
  ```
</CodeGroup>

### isLoaded

Returns whether the ad is loaded.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  val isLoaded: Boolean = interstitialAd?.isLoaded ?: false
  ```

  ```java Java theme={null}
  boolean isLoaded = interstitialAd.isLoaded();
  ```
</CodeGroup>

### creativeId

Returns the creative ID of the currently loaded ad.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  val creativeId: String = interstitialAd?.creativeId ?: ""
  ```

  ```java Java theme={null}
  String creativeId = interstitialAd.getCreativeId();
  ```
</CodeGroup>

### txId

Returns the transaction ID of the currently loaded ad.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  val txId: String = interstitialAd?.txId ?: ""
  ```

  ```java Java theme={null}
  String txId = interstitialAd.getTxId();
  ```
</CodeGroup>

### campaignId

Returns the campaign ID of the currently loaded ad.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  val campaignId: String = interstitialAd?.campaignId ?: ""
  ```

  ```java Java theme={null}
  String campaignId = interstitialAd.getCampaignId();
  ```
</CodeGroup>

### isBackfilled

Returns whether the currently loaded ad is a backfill ad.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  val isBackfilled: Boolean = interstitialAd?.isBackfilled ?: false
  ```

  ```java Java theme={null}
  boolean isBackfilled = interstitialAd.isBackfilled();
  ```
</CodeGroup>

### close()

Programmatically closes the interstitial ad.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  interstitialAd?.close()
  ```

  ```java Java theme={null}
  interstitialAd.close();
  ```
</CodeGroup>

***

## AdropInterstitialAdListener Methods

### Required Methods

<ParamField body="onAdReceived" type="(AdropInterstitialAd) -> Unit">
  Called when ad is successfully received. You can call `show()` to display the ad from this point.
</ParamField>

<ParamField body="onAdFailedToReceive" type="(AdropInterstitialAd, AdropErrorCode) -> Unit">
  Called when ad fails to load. Check the error code for the failure reason.
</ParamField>

### Optional Methods

<ParamField body="onAdImpression" type="(AdropInterstitialAd) -> Unit">
  Called when an ad impression is recorded.
</ParamField>

<ParamField body="onAdClicked" type="(AdropInterstitialAd) -> Unit">
  Called when the user clicks the ad.
</ParamField>

<ParamField body="onAdWillPresentFullScreen" type="(AdropInterstitialAd) -> Unit">
  Called just before the interstitial ad is displayed. You can pause game logic here.
</ParamField>

<ParamField body="onAdDidPresentFullScreen" type="(AdropInterstitialAd) -> Unit">
  Called immediately after the interstitial ad is displayed on screen.
</ParamField>

<ParamField body="onAdWillDismissFullScreen" type="(AdropInterstitialAd) -> Unit">
  Called just before the interstitial ad is closed.
</ParamField>

<ParamField body="onAdDidDismissFullScreen" type="(AdropInterstitialAd) -> Unit">
  Called immediately after the interstitial ad is closed. Good time to preload the next ad.
</ParamField>

<ParamField body="onAdFailedToShowFullScreen" type="(AdropInterstitialAd, AdropErrorCode) -> Unit">
  Called when ad fails to show. Check the error code for the failure reason.
</ParamField>

***

## Back Button Callback

You can receive a callback when the user presses the back button while an interstitial ad is displayed by setting `AdropInterstitialAdCloseListener`.

### AdropInterstitialAdCloseListener

<ParamField body="onBackPressed" type="(AdropInterstitialAd) -> Unit">
  Called when the user presses the back button while the interstitial ad is displayed.
</ParamField>

### Usage

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import io.adrop.ads.interstitial.AdropInterstitialAd
  import io.adrop.ads.interstitial.AdropInterstitialAdCloseListener

  // 1. Define closeListener
  private val closeListener = object : AdropInterstitialAdCloseListener {
      override fun onBackPressed(ad: AdropInterstitialAd) {
          // Called when the user presses the back button
          Log.d("InterstitialAd", "Back button pressed")

          // Call close() to dismiss the ad
          ad.close()
      }
  }

  // 2. Set closeListener when creating the interstitial ad
  val interstitialAd = AdropInterstitialAd(context, "YOUR_UNIT_ID").apply {
      interstitialAdListener = yourAdListener
      closeListener = this@YourActivity.closeListener
      load()
  }
  ```

  ```java Java theme={null}
  import io.adrop.ads.interstitial.AdropInterstitialAd;
  import io.adrop.ads.interstitial.AdropInterstitialAdCloseListener;
  import io.adrop.ads.interstitial.AdropInterstitialAdListener;

  // 1. Define closeListener
  private final AdropInterstitialAdCloseListener closeListener = new AdropInterstitialAdCloseListener() {
      @Override
      public void onBackPressed(@NonNull AdropInterstitialAd ad) {
          // Called when the user presses the back button
          Log.d("InterstitialAd", "Back button pressed");

          // Call close() to dismiss the ad
          ad.close();
      }
  };

  // 2. Set closeListener when creating the interstitial ad
  AdropInterstitialAd interstitialAd = new AdropInterstitialAd(context, "YOUR_UNIT_ID");
  interstitialAd.setInterstitialAdListener(yourAdListener);
  interstitialAd.setCloseListener(closeListener);  // New
  interstitialAd.load();
  ```
</CodeGroup>

### Behavior

* **Back button callback**: When the user presses the back button, `closeListener.onBackPressed()` is called first.
* **Auto-close condition**: If more than 30 seconds have passed since the ad was displayed, or if there is no WebView, the ad is automatically closed when the back button is pressed.
* **Manual close**: You can programmatically close the ad at any time by calling `ad.close()`.
* **If closeListener is not set**: The existing behavior is maintained (auto-close after 30 seconds only).

### Android 15+ Compatibility

On Android 13 (Tiramisu) and above, `OnBackInvokedCallback` is used to support Predictive Back. It works correctly even if your app has `enableOnBackInvokedCallback="true"` set.

```xml theme={null}
<!-- AndroidManifest.xml -->
<application
    android:enableOnBackInvokedCallback="true"
    ... >
```

***

## Lifecycle Management

### destroy Method

You must call `destroy()` to release resources when the Activity or Fragment is destroyed.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onDestroy() {
      super.onDestroy()
      interstitialAd?.destroy()
      interstitialAd = null
  }
  ```

  ```java Java theme={null}
  @Override
  protected void onDestroy() {
      super.onDestroy();
      if (interstitialAd != null) {
          interstitialAd.destroy();
          interstitialAd = null;
      }
  }
  ```
</CodeGroup>

<Warning>
  Always call `destroy()` to prevent memory leaks.
</Warning>

***

## Preloading Strategy

It's recommended to preload ads for better user experience.

### Basic Preloading

<CodeGroup>
  ```kotlin Kotlin theme={null}
  class GameActivity : AppCompatActivity() {
      private var interstitialAd: AdropInterstitialAd? = null
      private var isAdReady = false

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_game)

          // Preload on screen entry
          preloadInterstitialAd()
      }

      private fun preloadInterstitialAd() {
          interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")
          interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
              override fun onAdReceived(ad: AdropInterstitialAd) {
                  isAdReady = true
                  Log.d("Adrop", "Interstitial ad ready")
              }

              override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  isAdReady = false
                  Log.e("Adrop", "Interstitial ad load failed: $errorCode")
              }

              override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
                  isAdReady = false
                  // Preload next ad
                  preloadInterstitialAd()
              }
          }
          interstitialAd?.load()
      }

      private fun onGameLevelComplete() {
          // Show immediately on level complete
          if (isAdReady) {
              interstitialAd?.show(this)
          }
      }
  }
  ```

  ```java Java theme={null}
  public class GameActivity extends AppCompatActivity {
      private AdropInterstitialAd interstitialAd;
      private boolean isAdReady = false;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_game);

          // Preload on screen entry
          preloadInterstitialAd();
      }

      private void preloadInterstitialAd() {
          interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");
          interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
              @Override
              public void onAdReceived(@NonNull AdropInterstitialAd ad) {
                  isAdReady = true;
                  Log.d("Adrop", "Interstitial ad ready");
              }

              @Override
              public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  isAdReady = false;
                  Log.e("Adrop", "Interstitial ad load failed: " + errorCode);
              }

              @Override
              public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  isAdReady = false;
                  // Preload next ad
                  preloadInterstitialAd();
              }
          });
          interstitialAd.load();
      }

      private void onGameLevelComplete() {
          // Show immediately on level complete
          if (isAdReady) {
              interstitialAd.show(this);
          }
      }
  }
  ```
</CodeGroup>

### Reload After Dismiss

Preload the next ad in the `onAdDidDismissFullScreen` callback after the ad is closed.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
      Log.d("Adrop", "Interstitial ad dismissed")
      // Immediately load next ad
      interstitialAd?.load()
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
      Log.d("Adrop", "Interstitial ad dismissed");
      // Immediately load next ad
      interstitialAd.load();
  }
  ```
</CodeGroup>

***

## Best Practices

### 1. Appropriate Display Timing

Show ads at natural transition points in the app.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  // Good: Game level transition
  fun onLevelComplete() {
      saveProgress()
      showInterstitialAd()
      loadNextLevel()
  }

  // Good: Content reading complete
  fun onArticleFinished() {
      showInterstitialAd()
  }

  // Bad: During user action
  fun onButtonClick() {
      showInterstitialAd() // Disrupts user experience
      performAction()
  }
  ```

  ```java Java theme={null}
  // Good: Game level transition
  private void onLevelComplete() {
      saveProgress();
      showInterstitialAd();
      loadNextLevel();
  }

  // Good: Content reading complete
  private void onArticleFinished() {
      showInterstitialAd();
  }

  // Bad: During user action
  private void onButtonClick() {
      showInterstitialAd(); // Disrupts user experience
      performAction();
  }
  ```
</CodeGroup>

### 2. Error Handling

Implement handling for ad load failures.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
      when (errorCode) {
          AdropErrorCode.ERROR_CODE_NETWORK -> {
              Log.e("Adrop", "Network error: try again later")
              retryAfterDelay()
          }
          AdropErrorCode.ERROR_CODE_AD_NO_FILL -> {
              Log.w("Adrop", "No ads available")
              continueWithoutAd()
          }
          else -> {
              Log.e("Adrop", "Ad load failed: $errorCode")
          }
      }
  }

  private fun retryAfterDelay() {
      Handler(Looper.getMainLooper()).postDelayed({
          interstitialAd?.load()
      }, 30000) // Retry after 30 seconds
  }

  private fun continueWithoutAd() {
      // Continue without ad
      proceedToNextScreen()
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
      switch (errorCode) {
          case ERROR_CODE_NETWORK:
              Log.e("Adrop", "Network error: try again later");
              retryAfterDelay();
              break;
          case ERROR_CODE_AD_NO_FILL:
              Log.w("Adrop", "No ads available");
              continueWithoutAd();
              break;
          default:
              Log.e("Adrop", "Ad load failed: " + errorCode);
              break;
      }
  }

  private void retryAfterDelay() {
      new Handler(Looper.getMainLooper()).postDelayed(() -> {
          interstitialAd.load();
      }, 30000); // Retry after 30 seconds
  }

  private void continueWithoutAd() {
      // Continue without ad
      proceedToNextScreen();
  }
  ```
</CodeGroup>

### 3. Frequency Capping

Don't show ads too frequently.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  class AdFrequencyManager {
      private var lastAdShownTime: Long = 0
      private val minimumInterval = 180_000L // 3 minutes

      fun canShowAd(): Boolean {
          val currentTime = System.currentTimeMillis()
          return currentTime - lastAdShownTime >= minimumInterval
      }

      fun recordAdShown() {
          lastAdShownTime = System.currentTimeMillis()
      }
  }

  // Usage example
  class MainActivity : AppCompatActivity() {
      private val frequencyManager = AdFrequencyManager()

      private fun showInterstitialIfAllowed() {
          if (!frequencyManager.canShowAd()) {
              Log.d("Adrop", "Ad display interval too short")
              return
          }

          interstitialAd?.show(this)
      }

      // Call in listener
      override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
          frequencyManager.recordAdShown()
      }
  }
  ```

  ```java Java theme={null}
  public class AdFrequencyManager {
      private long lastAdShownTime = 0;
      private final long minimumInterval = 180_000L; // 3 minutes

      public boolean canShowAd() {
          long currentTime = System.currentTimeMillis();
          return currentTime - lastAdShownTime >= minimumInterval;
      }

      public void recordAdShown() {
          lastAdShownTime = System.currentTimeMillis();
      }
  }

  // Usage example
  public class MainActivity extends AppCompatActivity {
      private final AdFrequencyManager frequencyManager = new AdFrequencyManager();

      private void showInterstitialIfAllowed() {
          if (!frequencyManager.canShowAd()) {
              Log.d("Adrop", "Ad display interval too short");
              return;
          }

          interstitialAd.show(this);
      }

      // Call in listener
      @Override
      public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
          frequencyManager.recordAdShown();
      }
  }
  ```
</CodeGroup>

### 4. Game Pause Handling

Pause games or animations when showing interstitial ads.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
      // Pause game
      pauseGame()
      // Stop background music
      pauseBackgroundMusic()
  }

  override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
      // Resume game
      resumeGame()
      // Resume background music
      resumeBackgroundMusic()
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
      // Pause game
      pauseGame();
      // Stop background music
      pauseBackgroundMusic();
  }

  @Override
  public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
      // Resume game
      resumeGame();
      // Resume background music
      resumeBackgroundMusic();
  }
  ```
</CodeGroup>

***

## Testing

### Using Test Unit ID

Use test unit IDs during development.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import io.adrop.ads.AdropAds

  class MainActivity : AppCompatActivity() {
      private val unitId = if (BuildConfig.DEBUG) {
          "PUBLIC_TEST_UNIT_ID_INTERSTITIAL"
      } else {
          "YOUR_PRODUCTION_UNIT_ID"
      }

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)

          interstitialAd = AdropInterstitialAd(this, unitId)
      }
  }
  ```

  ```java Java theme={null}
  public class MainActivity extends AppCompatActivity {
      private final String unitId = BuildConfig.DEBUG ?
          "PUBLIC_TEST_UNIT_ID_INTERSTITIAL" :
          "YOUR_PRODUCTION_UNIT_ID";

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);

          interstitialAd = new AdropInterstitialAd(this, unitId);
      }
  }
  ```
</CodeGroup>

### Verify Ad Load

Verify that ads are loading correctly.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdReceived(ad: AdropInterstitialAd) {
      Log.d("Adrop", "Interstitial ad load success")
      Log.d("Adrop", "Unit ID: ${ad.unitId}")
      Log.d("Adrop", "Creative ID: ${ad.creativeId}")
      Log.d("Adrop", "Is Backfilled: ${ad.isBackfilled}")
  }

  override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
      Log.e("Adrop", "Interstitial ad load failed: $errorCode")
      if (BuildConfig.DEBUG) {
          Toast.makeText(this, "Ad load failed: $errorCode", Toast.LENGTH_SHORT).show()
      }
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdReceived(@NonNull AdropInterstitialAd ad) {
      Log.d("Adrop", "Interstitial ad load success");
      Log.d("Adrop", "Unit ID: " + ad.getUnitId());
      Log.d("Adrop", "Creative ID: " + ad.getCreativeId());
      Log.d("Adrop", "Is Backfilled: " + ad.isBackfilled());
  }

  @Override
  public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
      Log.e("Adrop", "Interstitial ad load failed: " + errorCode);
      if (BuildConfig.DEBUG) {
          Toast.makeText(this, "Ad load failed: " + errorCode, Toast.LENGTH_SHORT).show();
      }
  }
  ```
</CodeGroup>

***

## Complete Implementation Example

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import android.os.Bundle
  import android.util.Log
  import android.widget.Button
  import android.widget.Toast
  import androidx.appcompat.app.AppCompatActivity
  import io.adrop.ads.interstitial.AdropInterstitialAd
  import io.adrop.ads.interstitial.AdropInterstitialAdListener
  import io.adrop.ads.model.AdropErrorCode

  class InterstitialAdActivity : AppCompatActivity() {
      private var interstitialAd: AdropInterstitialAd? = null
      private lateinit var loadButton: Button
      private lateinit var showButton: Button

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_interstitial_ad)

          loadButton = findViewById(R.id.btn_load_ad)
          showButton = findViewById(R.id.btn_show_ad)

          // Set initial button state
          showButton.isEnabled = false

          // Initialize interstitial ad
          setupInterstitialAd()

          // Button click listeners
          loadButton.setOnClickListener {
              loadInterstitialAd()
          }

          showButton.setOnClickListener {
              showInterstitialAd()
          }

          // Auto-load first ad
          loadInterstitialAd()
      }

      private fun setupInterstitialAd() {
          val unitId = if (BuildConfig.DEBUG) {
              "PUBLIC_TEST_UNIT_ID_INTERSTITIAL"
          } else {
              "YOUR_PRODUCTION_UNIT_ID"
          }

          interstitialAd = AdropInterstitialAd(this, unitId)
          interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
              override fun onAdReceived(ad: AdropInterstitialAd) {
                  Log.d(TAG, "Interstitial ad received")
                  showButton.isEnabled = true
                  loadButton.isEnabled = false
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "Ad is ready",
                      Toast.LENGTH_SHORT
                  ).show()
              }

              override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e(TAG, "Interstitial ad failed to receive: $errorCode")
                  showButton.isEnabled = false
                  loadButton.isEnabled = true
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "Ad load failed: $errorCode",
                      Toast.LENGTH_SHORT
                  ).show()
              }

              override fun onAdImpression(ad: AdropInterstitialAd) {
                  Log.d(TAG, "Interstitial ad impression")
              }

              override fun onAdClicked(ad: AdropInterstitialAd) {
                  Log.d(TAG, "Interstitial ad clicked")
              }

              override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "Interstitial ad will present")
              }

              override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "Interstitial ad did present")
              }

              override fun onAdWillDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "Interstitial ad will dismiss")
              }

              override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "Interstitial ad dismissed")
                  showButton.isEnabled = false
                  loadButton.isEnabled = true
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "Ad closed",
                      Toast.LENGTH_SHORT
                  ).show()

                  // Preload next ad
                  loadInterstitialAd()
              }

              override fun onAdFailedToShowFullScreen(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e(TAG, "Interstitial ad failed to show: $errorCode")
                  showButton.isEnabled = false
                  loadButton.isEnabled = true
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "Ad show failed: $errorCode",
                      Toast.LENGTH_SHORT
                  ).show()
              }
          }
      }

      private fun loadInterstitialAd() {
          Log.d(TAG, "Loading interstitial ad")
          loadButton.isEnabled = false
          interstitialAd?.load()
      }

      private fun showInterstitialAd() {
          if (interstitialAd?.isLoaded == true) {
              Log.d(TAG, "Showing interstitial ad")
              interstitialAd?.show(this)
          } else {
              Log.w(TAG, "Ad is not loaded yet")
              Toast.makeText(this, "Ad is not ready", Toast.LENGTH_SHORT).show()
          }
      }

      override fun onDestroy() {
          super.onDestroy()
          interstitialAd?.destroy()
          interstitialAd = null
      }

      companion object {
          private const val TAG = "InterstitialAdActivity"
      }
  }
  ```

  ```java Java theme={null}
  import android.os.Bundle;
  import android.util.Log;
  import android.widget.Button;
  import android.widget.Toast;
  import androidx.annotation.NonNull;
  import androidx.appcompat.app.AppCompatActivity;
  import io.adrop.ads.interstitial.AdropInterstitialAd;
  import io.adrop.ads.interstitial.AdropInterstitialAdListener;
  import io.adrop.ads.model.AdropErrorCode;

  public class InterstitialAdActivity extends AppCompatActivity {
      private static final String TAG = "InterstitialAdActivity";

      private AdropInterstitialAd interstitialAd;
      private Button loadButton;
      private Button showButton;

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_interstitial_ad);

          loadButton = findViewById(R.id.btn_load_ad);
          showButton = findViewById(R.id.btn_show_ad);

          // Set initial button state
          showButton.setEnabled(false);

          // Initialize interstitial ad
          setupInterstitialAd();

          // Button click listeners
          loadButton.setOnClickListener(v -> loadInterstitialAd());
          showButton.setOnClickListener(v -> showInterstitialAd());

          // Auto-load first ad
          loadInterstitialAd();
      }

      private void setupInterstitialAd() {
          String unitId = BuildConfig.DEBUG ?
              "PUBLIC_TEST_UNIT_ID_INTERSTITIAL" :
              "YOUR_PRODUCTION_UNIT_ID";

          interstitialAd = new AdropInterstitialAd(this, unitId);
          interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
              @Override
              public void onAdReceived(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "Interstitial ad received");
                  showButton.setEnabled(true);
                  loadButton.setEnabled(false);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "Ad is ready",
                      Toast.LENGTH_SHORT
                  ).show();
              }

              @Override
              public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e(TAG, "Interstitial ad failed to receive: " + errorCode);
                  showButton.setEnabled(false);
                  loadButton.setEnabled(true);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "Ad load failed: " + errorCode,
                      Toast.LENGTH_SHORT
                  ).show();
              }

              @Override
              public void onAdImpression(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "Interstitial ad impression");
              }

              @Override
              public void onAdClicked(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "Interstitial ad clicked");
              }

              @Override
              public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "Interstitial ad will present");
              }

              @Override
              public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "Interstitial ad did present");
              }

              @Override
              public void onAdWillDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "Interstitial ad will dismiss");
              }

              @Override
              public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "Interstitial ad dismissed");
                  showButton.setEnabled(false);
                  loadButton.setEnabled(true);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "Ad closed",
                      Toast.LENGTH_SHORT
                  ).show();

                  // Preload next ad
                  loadInterstitialAd();
              }

              @Override
              public void onAdFailedToShowFullScreen(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e(TAG, "Interstitial ad failed to show: " + errorCode);
                  showButton.setEnabled(false);
                  loadButton.setEnabled(true);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "Ad show failed: " + errorCode,
                      Toast.LENGTH_SHORT
                  ).show();
              }
          });
      }

      private void loadInterstitialAd() {
          Log.d(TAG, "Loading interstitial ad");
          loadButton.setEnabled(false);
          interstitialAd.load();
      }

      private void showInterstitialAd() {
          if (interstitialAd != null && interstitialAd.isLoaded()) {
              Log.d(TAG, "Showing interstitial ad");
              interstitialAd.show(this);
          } else {
              Log.w(TAG, "Ad is not loaded yet");
              Toast.makeText(this, "Ad is not ready", Toast.LENGTH_SHORT).show();
          }
      }

      @Override
      protected void onDestroy() {
          super.onDestroy();
          if (interstitialAd != null) {
              interstitialAd.destroy();
              interstitialAd = null;
          }
      }
  }
  ```
</CodeGroup>

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="onAdReceived is not called">
    * Verify SDK is initialized
    * Check unit ID is correct
    * Check network connection
    * Verify AndroidManifest.xml has internet permission
  </Accordion>

  <Accordion title="onAdFailedToReceive is called">
    * Check the error code to identify the issue
    * `ERROR_CODE_AD_NO_FILL`: No ad inventory, try again later
    * `ERROR_CODE_NETWORK`: Check network connection
    * `ERROR_CODE_INVALID_UNIT`: Verify unit ID
  </Accordion>

  <Accordion title="Nothing happens after show() is called">
    * Ensure `show()` is called after `onAdReceived` callback
    * Check `isLoaded` property is `true`
    * Verify Activity is valid
    * Ensure another interstitial ad is not already showing
  </Accordion>

  <Accordion title="Memory leak warning">
    * Verify `destroy()` is called in `onDestroy()`
    * Check Context reference is managed with WeakReference
    * Ensure listener is set to null
  </Accordion>
</AccordionGroup>

***

## Backfill Ads

When backfill ads are enabled, backfill ads are automatically loaded when direct ads are unavailable. Use the `isBackfilled` property to check if the ad is a backfill ad.

<CodeGroup>
  ```kotlin Kotlin theme={null}
  interstitialAd.interstitialAdListener = object : AdropInterstitialAdListener {
      override fun onAdReceived(ad: AdropInterstitialAd) {
          if (ad.isBackfilled) {
              println("Backfill ad loaded")
          } else {
              println("Direct ad loaded")
          }
      }

      override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
          when (errorCode) {
              AdropErrorCode.ERROR_CODE_AD_NO_FILL -> {
                  println("No direct ad, requesting backfill...")
              }
              AdropErrorCode.ERROR_CODE_AD_BACKFILL_NO_FILL -> {
                  println("Backfill ad also not available")
              }
              else -> {
                  println("Ad load failed: $errorCode")
              }
          }
      }
  }
  ```

  ```java Java theme={null}
  interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
      @Override
      public void onAdReceived(AdropInterstitialAd ad) {
          if (ad.isBackfilled()) {
              System.out.println("Backfill ad loaded");
          } else {
              System.out.println("Direct ad loaded");
          }
      }

      @Override
      public void onAdFailedToReceive(AdropInterstitialAd ad, AdropErrorCode errorCode) {
          if (errorCode == AdropErrorCode.ERROR_CODE_AD_NO_FILL) {
              System.out.println("No direct ad, requesting backfill...");
          } else if (errorCode == AdropErrorCode.ERROR_CODE_AD_BACKFILL_NO_FILL) {
              System.out.println("Backfill ad also not available");
          } else {
              System.out.println("Ad load failed: " + errorCode);
          }
      }
  });
  ```
</CodeGroup>

<Note>
  To use backfill ads, add the `io.adrop:adrop-ads-backfill` dependency. See [Getting Started](/sdk/android/overview).
</Note>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Rewarded Ads" href="/sdk/android/rewarded">
    Improve user engagement with rewarded ads
  </Card>

  <Card title="Banner Ads" href="/sdk/android/banner">
    Implement banner ads
  </Card>

  <Card title="Targeting Settings" href="/sdk/android/targeting">
    User properties and contextual targeting
  </Card>

  <Card title="Reference" href="/sdk/android/reference">
    API reference documentation
  </Card>
</CardGroup>
