> ## 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.

# インタースティシャル広告

> Androidアプリでインタースティシャル広告を実装する方法をご案内します。

## 概要

インタースティシャル広告は、アプリの画面全体を覆う形式で表示される広告です。ゲームのレベル遷移やコンテンツページの切り替えなど、アプリの自然な遷移ポイントで表示するのに適しています。

### 特徴

* 全画面を覆う没入型広告
* ユーザーが明示的に閉じるまで表示を維持
* 画像および動画広告に対応
* 高い視覚的注目度

<Note>
  開発環境ではテストユニットIDを使用してください：`PUBLIC_TEST_UNIT_ID_INTERSTITIAL`
</Note>

***

## 実装ステップ

インタースティシャル広告は以下の4ステップで実装します：

1. **初期化** - AdropInterstitialAdインスタンスを作成
2. **リスナー設定** - 広告イベント受信のためのリスナーを設定
3. **広告ロード** - 広告をリクエストして受信
4. **広告表示** - 画面に広告を表示

***

## 基本実装

### AdropInterstitialAdインスタンスの作成

<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. インタースティシャル広告インスタンスを作成
          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. インタースティシャル広告インスタンスを作成
          interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");
      }
  }
  ```
</CodeGroup>

### AdropInterstitialAdコンストラクタ

<ParamField body="context" type="Context" required>
  Android Contextオブジェクト（ActivityまたはApplication Context）
</ParamField>

<ParamField body="unitId" type="String" required>
  広告ユニットID（コンソールで発行）
</ParamField>

***

## リスナー設定

広告イベントを受信するには、`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. インタースティシャル広告インスタンスを作成
          interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")

          // 2. リスナー設定
          interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
              override fun onAdReceived(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "インタースティシャル広告受信完了")
              }

              override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e("Adrop", "インタースティシャル広告受信失敗: $errorCode")
              }

              override fun onAdImpression(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "インタースティシャル広告インプレッション")
              }

              override fun onAdClicked(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "インタースティシャル広告クリック")
              }

              override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "インタースティシャル広告表示直前")
              }

              override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "インタースティシャル広告表示完了")
              }

              override fun onAdWillDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "インタースティシャル広告終了直前")
              }

              override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "インタースティシャル広告終了")
                  // 次の広告を事前ロード
                  loadInterstitialAd()
              }

              override fun onAdFailedToShowFullScreen(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e("Adrop", "インタースティシャル広告表示失敗: $errorCode")
              }
          }

          // 2-1. 戻るボタンコールバックリスナー設定
          interstitialAd?.closeListener = object : AdropInterstitialAdCloseListener {
              override fun onBackPressed(ad: AdropInterstitialAd) {
                  Log.d("Adrop", "戻るボタンが押されました")
              }
          }

          // 3. 広告ロード
          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. インタースティシャル広告インスタンスを作成
          interstitialAd = new AdropInterstitialAd(this, "YOUR_UNIT_ID");

          // 2. リスナー設定
          interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
              @Override
              public void onAdReceived(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "インタースティシャル広告受信完了");
              }

              @Override
              public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e("Adrop", "インタースティシャル広告受信失敗: " + errorCode);
              }

              @Override
              public void onAdImpression(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "インタースティシャル広告インプレッション");
              }

              @Override
              public void onAdClicked(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "インタースティシャル広告クリック");
              }

              @Override
              public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "インタースティシャル広告表示直前");
              }

              @Override
              public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "インタースティシャル広告表示完了");
              }

              @Override
              public void onAdWillDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "インタースティシャル広告終了直前");
              }

              @Override
              public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "インタースティシャル広告終了");
                  // 次の広告を事前ロード
                  loadInterstitialAd();
              }

              @Override
              public void onAdFailedToShowFullScreen(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e("Adrop", "インタースティシャル広告表示失敗: " + errorCode);
              }
          });

          // 2-1. 戻るボタンコールバックリスナー設定
          interstitialAd.setCloseListener(new AdropInterstitialAdCloseListener() {
              @Override
              public void onBackPressed(@NonNull AdropInterstitialAd ad) {
                  Log.d("Adrop", "戻るボタンが押されました");
              }
          });

          // 3. 広告ロード
          loadInterstitialAd();
      }

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

***

## 広告のロード

`load()`メソッドを呼び出して広告をリクエストします。

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

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

広告ロード完了時に`onAdReceived`コールバックが呼び出され、失敗時には`onAdFailedToReceive`コールバックが呼び出されます。

***

## 広告の表示

広告がロードされた後、`show()`メソッドを呼び出して広告を表示します。

### isLoadedプロパティ

広告がロードされているかどうかを確認するプロパティです。`show()`を呼び出す前にこの値を確認することをお勧めします。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  private fun showInterstitialAd() {
      if (interstitialAd?.isLoaded == true) {
          interstitialAd?.show(this)
      } else {
          Log.d("Adrop", "広告がまだロードされていません")
      }
  }
  ```

  ```java Java theme={null}
  private void showInterstitialAd() {
      if (interstitialAd != null && interstitialAd.isLoaded()) {
          interstitialAd.show(this);
      } else {
          Log.d("Adrop", "広告がまだロードされていません");
      }
  }
  ```
</CodeGroup>

### showメソッド

<ParamField body="fromActivity" type="Activity" required>
  広告を表示するActivityオブジェクト
</ParamField>

***

## AdropInterstitialAdプロパティ

### unitId

広告ユニットIDを返します。

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

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

### isLoaded

広告がロードされているかどうかを返します。

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

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

### creativeId

現在ロードされている広告のクリエイティブIDを返します。

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

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

### txId

現在ロードされている広告のトランザクションIDを返します。

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

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

### campaignId

現在ロードされている広告のキャンペーンIDを返します。

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

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

### isBackfilled

現在ロードされている広告がバックフィル広告かどうかを返します。

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

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

### close()

プログラムでインタースティシャル広告を閉じます。

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

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

***

## AdropInterstitialAdListenerメソッド

### 必須メソッド

<ParamField body="onAdReceived" type="(AdropInterstitialAd) -> Unit">
  広告受信成功時に呼び出されます。この時点で`show()`を呼び出して広告を表示できます。
</ParamField>

<ParamField body="onAdFailedToReceive" type="(AdropInterstitialAd, AdropErrorCode) -> Unit">
  広告受信失敗時に呼び出されます。エラーコードで失敗原因を確認できます。
</ParamField>

### オプションメソッド

<ParamField body="onAdImpression" type="(AdropInterstitialAd) -> Unit">
  広告インプレッションが記録された時に呼び出されます。
</ParamField>

<ParamField body="onAdClicked" type="(AdropInterstitialAd) -> Unit">
  ユーザーが広告をクリックした時に呼び出されます。
</ParamField>

<ParamField body="onAdWillPresentFullScreen" type="(AdropInterstitialAd) -> Unit">
  インタースティシャル広告が表示される直前に呼び出されます。ゲームの一時停止などの処理ができます。
</ParamField>

<ParamField body="onAdDidPresentFullScreen" type="(AdropInterstitialAd) -> Unit">
  インタースティシャル広告が画面に表示された直後に呼び出されます。
</ParamField>

<ParamField body="onAdWillDismissFullScreen" type="(AdropInterstitialAd) -> Unit">
  インタースティシャル広告が閉じる直前に呼び出されます。
</ParamField>

<ParamField body="onAdDidDismissFullScreen" type="(AdropInterstitialAd) -> Unit">
  インタースティシャル広告が閉じた直後に呼び出されます。次の広告を事前ロードするのに適したタイミングです。
</ParamField>

<ParamField body="onAdFailedToShowFullScreen" type="(AdropInterstitialAd, AdropErrorCode) -> Unit">
  広告表示失敗時に呼び出されます。エラーコードで失敗原因を確認できます。
</ParamField>

***

## 戻るボタンコールバック

インタースティシャル広告が表示されている状態で、ユーザーが戻るボタンを押した時に`AdropInterstitialAdCloseListener`を通じてコールバックを受け取ることができます。

### AdropInterstitialAdCloseListener

<ParamField body="onBackPressed" type="(AdropInterstitialAd) -> Unit">
  ユーザーがインタースティシャル広告で戻るボタンを押した時に呼び出されます。
</ParamField>

### 使用例

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

  // 1. closeListenerを定義
  private val closeListener = object : AdropInterstitialAdCloseListener {
      override fun onBackPressed(ad: AdropInterstitialAd) {
          // ユーザーが戻るボタンを押した時に呼び出されます
          Log.d("InterstitialAd", "Back button pressed")

          // 広告を閉じるにはclose()を呼び出します
          ad.close()
      }
  }

  // 2. インタースティシャル広告作成時にcloseListenerを設定
  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. closeListenerを定義
  private final AdropInterstitialAdCloseListener closeListener = new AdropInterstitialAdCloseListener() {
      @Override
      public void onBackPressed(@NonNull AdropInterstitialAd ad) {
          // ユーザーが戻るボタンを押した時に呼び出されます
          Log.d("InterstitialAd", "Back button pressed");

          // 広告を閉じるにはclose()を呼び出します
          ad.close();
      }
  };

  // 2. インタースティシャル広告作成時にcloseListenerを設定
  AdropInterstitialAd interstitialAd = new AdropInterstitialAd(context, "YOUR_UNIT_ID");
  interstitialAd.setInterstitialAdListener(yourAdListener);
  interstitialAd.setCloseListener(closeListener);  // 新規追加
  interstitialAd.load();
  ```
</CodeGroup>

### 動作説明

* **戻るボタンコールバック**: ユーザーが戻るボタンを押すと、`closeListener.onBackPressed()`が先に呼び出されます。
* **自動クローズ条件**: 広告が表示されてから30秒以上経過した場合、またはWebViewがない場合、戻るボタンで自動的に広告が閉じられます。
* **手動クローズ**: `ad.close()`を呼び出すことで、いつでもプログラムで広告を閉じることができます。
* **closeListenerを設定しない場合**: 従来の動作と同じく、30秒後の自動クローズのみ動作します。

### Android 15+互換性

Android 13（Tiramisu）以上では、`OnBackInvokedCallback`を使用して予測型バックナビゲーション（Predictive Back）をサポートします。アプリで`enableOnBackInvokedCallback="true"`を設定している場合でも正常に動作します。

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

***

## ライフサイクル管理

### destroyメソッド

ActivityやFragmentが終了する時は、`destroy()`メソッドを呼び出してリソースを解放する必要があります。

<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>
  メモリリークを防ぐため、必ず`destroy()`を呼び出してください。
</Warning>

***

## 事前ロード戦略

ユーザー体験を向上させるため、広告を事前にロードすることをお勧めします。

### 基本的な事前ロード

<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)

          // 画面進入時に事前ロード
          preloadInterstitialAd()
      }

      private fun preloadInterstitialAd() {
          interstitialAd = AdropInterstitialAd(this, "YOUR_UNIT_ID")
          interstitialAd?.interstitialAdListener = object : AdropInterstitialAdListener {
              override fun onAdReceived(ad: AdropInterstitialAd) {
                  isAdReady = true
                  Log.d("Adrop", "インタースティシャル広告準備完了")
              }

              override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  isAdReady = false
                  Log.e("Adrop", "インタースティシャル広告ロード失敗: $errorCode")
              }

              override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
                  isAdReady = false
                  // 次の広告を事前ロード
                  preloadInterstitialAd()
              }
          }
          interstitialAd?.load()
      }

      private fun onGameLevelComplete() {
          // レベル完了時に即座に表示
          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);

          // 画面進入時に事前ロード
          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", "インタースティシャル広告準備完了");
              }

              @Override
              public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  isAdReady = false;
                  Log.e("Adrop", "インタースティシャル広告ロード失敗: " + errorCode);
              }

              @Override
              public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  isAdReady = false;
                  // 次の広告を事前ロード
                  preloadInterstitialAd();
              }
          });
          interstitialAd.load();
      }

      private void onGameLevelComplete() {
          // レベル完了時に即座に表示
          if (isAdReady) {
              interstitialAd.show(this);
          }
      }
  }
  ```
</CodeGroup>

### 終了後の再ロード

広告が閉じた後、`onAdDidDismissFullScreen`コールバックで次の広告を事前にロードします。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
      Log.d("Adrop", "インタースティシャル広告終了")
      // 即座に次の広告をロード
      interstitialAd?.load()
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
      Log.d("Adrop", "インタースティシャル広告終了");
      // 即座に次の広告をロード
      interstitialAd.load();
  }
  ```
</CodeGroup>

***

## ベストプラクティス

### 1. 適切な表示タイミング

アプリの自然な遷移ポイントで広告を表示してください。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  // 良い例：ゲームレベル遷移
  fun onLevelComplete() {
      saveProgress()
      showInterstitialAd()
      loadNextLevel()
  }

  // 良い例：コンテンツ読了完了
  fun onArticleFinished() {
      showInterstitialAd()
  }

  // 悪い例：ユーザーアクション中
  fun onButtonClick() {
      showInterstitialAd() // ユーザー体験を阻害
      performAction()
  }
  ```

  ```java Java theme={null}
  // 良い例：ゲームレベル遷移
  private void onLevelComplete() {
      saveProgress();
      showInterstitialAd();
      loadNextLevel();
  }

  // 良い例：コンテンツ読了完了
  private void onArticleFinished() {
      showInterstitialAd();
  }

  // 悪い例：ユーザーアクション中
  private void onButtonClick() {
      showInterstitialAd(); // ユーザー体験を阻害
      performAction();
  }
  ```
</CodeGroup>

### 2. エラー処理

広告ロード失敗に対する処理を実装してください。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
      when (errorCode) {
          AdropErrorCode.ERROR_CODE_NETWORK -> {
              Log.e("Adrop", "ネットワークエラー：後でリトライ")
              retryAfterDelay()
          }
          AdropErrorCode.ERROR_CODE_AD_NO_FILL -> {
              Log.w("Adrop", "表示可能な広告なし")
              continueWithoutAd()
          }
          else -> {
              Log.e("Adrop", "広告ロード失敗: $errorCode")
          }
      }
  }

  private fun retryAfterDelay() {
      Handler(Looper.getMainLooper()).postDelayed({
          interstitialAd?.load()
      }, 30000) // 30秒後にリトライ
  }

  private fun continueWithoutAd() {
      // 広告なしで続行
      proceedToNextScreen()
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
      switch (errorCode) {
          case ERROR_CODE_NETWORK:
              Log.e("Adrop", "ネットワークエラー：後でリトライ");
              retryAfterDelay();
              break;
          case ERROR_CODE_AD_NO_FILL:
              Log.w("Adrop", "表示可能な広告なし");
              continueWithoutAd();
              break;
          default:
              Log.e("Adrop", "広告ロード失敗: " + errorCode);
              break;
      }
  }

  private void retryAfterDelay() {
      new Handler(Looper.getMainLooper()).postDelayed(() -> {
          interstitialAd.load();
      }, 30000); // 30秒後にリトライ
  }

  private void continueWithoutAd() {
      // 広告なしで続行
      proceedToNextScreen();
  }
  ```
</CodeGroup>

### 3. 頻度制限

広告を頻繁に表示しないようにしてください。

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

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

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

  // 使用例
  class MainActivity : AppCompatActivity() {
      private val frequencyManager = AdFrequencyManager()

      private fun showInterstitialIfAllowed() {
          if (!frequencyManager.canShowAd()) {
              Log.d("Adrop", "広告表示間隔が短すぎます")
              return
          }

          interstitialAd?.show(this)
      }

      // リスナーで呼び出し
      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分

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

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

  // 使用例
  public class MainActivity extends AppCompatActivity {
      private final AdFrequencyManager frequencyManager = new AdFrequencyManager();

      private void showInterstitialIfAllowed() {
          if (!frequencyManager.canShowAd()) {
              Log.d("Adrop", "広告表示間隔が短すぎます");
              return;
          }

          interstitialAd.show(this);
      }

      // リスナーで呼び出し
      @Override
      public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
          frequencyManager.recordAdShown();
      }
  }
  ```
</CodeGroup>

### 4. ゲーム一時停止処理

インタースティシャル広告表示時にゲームやアニメーションを一時停止してください。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
      // ゲーム一時停止
      pauseGame()
      // BGM停止
      pauseBackgroundMusic()
  }

  override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
      // ゲーム再開
      resumeGame()
      // BGM再生
      resumeBackgroundMusic()
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
      // ゲーム一時停止
      pauseGame();
      // BGM停止
      pauseBackgroundMusic();
  }

  @Override
  public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
      // ゲーム再開
      resumeGame();
      // BGM再生
      resumeBackgroundMusic();
  }
  ```
</CodeGroup>

***

## テスト

### テストユニットIDの使用

開発中はテストユニットIDを使用してください。

<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>

### 広告ロードの確認

広告が正常にロードされているか確認してください。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  override fun onAdReceived(ad: AdropInterstitialAd) {
      Log.d("Adrop", "インタースティシャル広告ロード成功")
      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", "インタースティシャル広告ロード失敗: $errorCode")
      if (BuildConfig.DEBUG) {
          Toast.makeText(this, "広告ロード失敗: $errorCode", Toast.LENGTH_SHORT).show()
      }
  }
  ```

  ```java Java theme={null}
  @Override
  public void onAdReceived(@NonNull AdropInterstitialAd ad) {
      Log.d("Adrop", "インタースティシャル広告ロード成功");
      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", "インタースティシャル広告ロード失敗: " + errorCode);
      if (BuildConfig.DEBUG) {
          Toast.makeText(this, "広告ロード失敗: " + errorCode, Toast.LENGTH_SHORT).show();
      }
  }
  ```
</CodeGroup>

***

## 完全な実装例

<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)

          // ボタンの初期状態を設定
          showButton.isEnabled = false

          // インタースティシャル広告を初期化
          setupInterstitialAd()

          // ボタンクリックリスナー
          loadButton.setOnClickListener {
              loadInterstitialAd()
          }

          showButton.setOnClickListener {
              showInterstitialAd()
          }

          // 最初の広告を自動ロード
          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, "インタースティシャル広告受信完了")
                  showButton.isEnabled = true
                  loadButton.isEnabled = false
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "広告の準備ができました",
                      Toast.LENGTH_SHORT
                  ).show()
              }

              override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e(TAG, "インタースティシャル広告受信失敗: $errorCode")
                  showButton.isEnabled = false
                  loadButton.isEnabled = true
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "広告ロード失敗: $errorCode",
                      Toast.LENGTH_SHORT
                  ).show()
              }

              override fun onAdImpression(ad: AdropInterstitialAd) {
                  Log.d(TAG, "インタースティシャル広告インプレッション")
              }

              override fun onAdClicked(ad: AdropInterstitialAd) {
                  Log.d(TAG, "インタースティシャル広告クリック")
              }

              override fun onAdWillPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "インタースティシャル広告表示直前")
              }

              override fun onAdDidPresentFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "インタースティシャル広告表示完了")
              }

              override fun onAdWillDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "インタースティシャル広告終了直前")
              }

              override fun onAdDidDismissFullScreen(ad: AdropInterstitialAd) {
                  Log.d(TAG, "インタースティシャル広告終了")
                  showButton.isEnabled = false
                  loadButton.isEnabled = true
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "広告が閉じられました",
                      Toast.LENGTH_SHORT
                  ).show()

                  // 次の広告を事前ロード
                  loadInterstitialAd()
              }

              override fun onAdFailedToShowFullScreen(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
                  Log.e(TAG, "インタースティシャル広告表示失敗: $errorCode")
                  showButton.isEnabled = false
                  loadButton.isEnabled = true
                  Toast.makeText(
                      this@InterstitialAdActivity,
                      "広告表示失敗: $errorCode",
                      Toast.LENGTH_SHORT
                  ).show()
              }
          }
      }

      private fun loadInterstitialAd() {
          Log.d(TAG, "インタースティシャル広告ロード開始")
          loadButton.isEnabled = false
          interstitialAd?.load()
      }

      private fun showInterstitialAd() {
          if (interstitialAd?.isLoaded == true) {
              Log.d(TAG, "インタースティシャル広告表示")
              interstitialAd?.show(this)
          } else {
              Log.w(TAG, "広告がまだロードされていません")
              Toast.makeText(this, "広告の準備ができていません", 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);

          // ボタンの初期状態を設定
          showButton.setEnabled(false);

          // インタースティシャル広告を初期化
          setupInterstitialAd();

          // ボタンクリックリスナー
          loadButton.setOnClickListener(v -> loadInterstitialAd());
          showButton.setOnClickListener(v -> showInterstitialAd());

          // 最初の広告を自動ロード
          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, "インタースティシャル広告受信完了");
                  showButton.setEnabled(true);
                  loadButton.setEnabled(false);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "広告の準備ができました",
                      Toast.LENGTH_SHORT
                  ).show();
              }

              @Override
              public void onAdFailedToReceive(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e(TAG, "インタースティシャル広告受信失敗: " + errorCode);
                  showButton.setEnabled(false);
                  loadButton.setEnabled(true);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "広告ロード失敗: " + errorCode,
                      Toast.LENGTH_SHORT
                  ).show();
              }

              @Override
              public void onAdImpression(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "インタースティシャル広告インプレッション");
              }

              @Override
              public void onAdClicked(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "インタースティシャル広告クリック");
              }

              @Override
              public void onAdWillPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "インタースティシャル広告表示直前");
              }

              @Override
              public void onAdDidPresentFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "インタースティシャル広告表示完了");
              }

              @Override
              public void onAdWillDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "インタースティシャル広告終了直前");
              }

              @Override
              public void onAdDidDismissFullScreen(@NonNull AdropInterstitialAd ad) {
                  Log.d(TAG, "インタースティシャル広告終了");
                  showButton.setEnabled(false);
                  loadButton.setEnabled(true);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "広告が閉じられました",
                      Toast.LENGTH_SHORT
                  ).show();

                  // 次の広告を事前ロード
                  loadInterstitialAd();
              }

              @Override
              public void onAdFailedToShowFullScreen(@NonNull AdropInterstitialAd ad, @NonNull AdropErrorCode errorCode) {
                  Log.e(TAG, "インタースティシャル広告表示失敗: " + errorCode);
                  showButton.setEnabled(false);
                  loadButton.setEnabled(true);
                  Toast.makeText(
                      InterstitialAdActivity.this,
                      "広告表示失敗: " + errorCode,
                      Toast.LENGTH_SHORT
                  ).show();
              }
          });
      }

      private void loadInterstitialAd() {
          Log.d(TAG, "インタースティシャル広告ロード開始");
          loadButton.setEnabled(false);
          interstitialAd.load();
      }

      private void showInterstitialAd() {
          if (interstitialAd != null && interstitialAd.isLoaded()) {
              Log.d(TAG, "インタースティシャル広告表示");
              interstitialAd.show(this);
          } else {
              Log.w(TAG, "広告がまだロードされていません");
              Toast.makeText(this, "広告の準備ができていません", Toast.LENGTH_SHORT).show();
          }
      }

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

***

## トラブルシューティング

<AccordionGroup>
  <Accordion title="onAdReceivedが呼び出されない">
    * SDKが初期化されているか確認
    * ユニットIDが正しいか確認
    * ネットワーク接続状態を確認
    * AndroidManifest.xmlにインターネット権限があるか確認
  </Accordion>

  <Accordion title="onAdFailedToReceiveが呼び出される">
    * エラーコードを確認して原因を把握
    * `ERROR_CODE_AD_NO_FILL`：広告インベントリ不足、後で再試行
    * `ERROR_CODE_NETWORK`：ネットワーク接続を確認
    * `ERROR_CODE_INVALID_UNIT`：ユニットIDを確認
  </Accordion>

  <Accordion title="show()呼び出し後に何も起こらない">
    * `onAdReceived`コールバック後に`show()`を呼び出しているか確認
    * `isLoaded`プロパティが`true`か確認
    * Activityが有効か確認
    * 他のインタースティシャル広告が既に表示中でないか確認
  </Accordion>

  <Accordion title="メモリリーク警告">
    * `onDestroy()`で`destroy()`メソッドを呼び出しているか確認
    * Context参照がWeakReferenceで管理されているか確認
    * リスナーをnullに設定しているか確認
  </Accordion>
</AccordionGroup>

***

## バックフィル広告

バックフィル広告が有効な場合、ダイレクト広告がない時に自動的にバックフィル広告がロードされます。`isBackfilled`プロパティでバックフィル広告かどうかを確認できます。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  interstitialAd.interstitialAdListener = object : AdropInterstitialAdListener {
      override fun onAdReceived(ad: AdropInterstitialAd) {
          if (ad.isBackfilled) {
              println("バックフィル広告がロードされました")
          } else {
              println("ダイレクト広告がロードされました")
          }
      }

      override fun onAdFailedToReceive(ad: AdropInterstitialAd, errorCode: AdropErrorCode) {
          when (errorCode) {
              AdropErrorCode.ERROR_CODE_AD_NO_FILL -> {
                  println("ダイレクト広告なし、バックフィル広告をリクエスト中...")
              }
              AdropErrorCode.ERROR_CODE_AD_BACKFILL_NO_FILL -> {
                  println("バックフィル広告も利用不可")
              }
              else -> {
                  println("広告ロード失敗: $errorCode")
              }
          }
      }
  }
  ```

  ```java Java theme={null}
  interstitialAd.setInterstitialAdListener(new AdropInterstitialAdListener() {
      @Override
      public void onAdReceived(AdropInterstitialAd ad) {
          if (ad.isBackfilled()) {
              System.out.println("バックフィル広告がロードされました");
          } else {
              System.out.println("ダイレクト広告がロードされました");
          }
      }

      @Override
      public void onAdFailedToReceive(AdropInterstitialAd ad, AdropErrorCode errorCode) {
          if (errorCode == AdropErrorCode.ERROR_CODE_AD_NO_FILL) {
              System.out.println("ダイレクト広告なし、バックフィル広告をリクエスト中...");
          } else if (errorCode == AdropErrorCode.ERROR_CODE_AD_BACKFILL_NO_FILL) {
              System.out.println("バックフィル広告も利用不可");
          } else {
              System.out.println("広告ロード失敗: " + errorCode);
          }
      }
  });
  ```
</CodeGroup>

<Note>
  バックフィル広告を使用するには、`io.adrop:adrop-ads-backfill`依存関係を追加する必要があります。[はじめに](/ja/sdk/android/overview)を参照してください。
</Note>

***

## 次のステップ

<CardGroup cols={2}>
  <Card title="リワード広告" href="/ja/sdk/android/rewarded">
    リワード広告でユーザーエンゲージメントを向上
  </Card>

  <Card title="バナー広告" href="/ja/sdk/android/banner">
    バナー広告を実装
  </Card>

  <Card title="ターゲティング設定" href="/ja/sdk/android/targeting">
    ユーザー属性とコンテキストターゲティング
  </Card>

  <Card title="リファレンス" href="/ja/sdk/android/reference">
    APIリファレンスドキュメント
  </Card>
</CardGroup>
