> ## 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アプリでポップアップ広告を実装する方法をご案内します。

## 概要

ポップアップ広告（Popup Ad）は、特定の瞬間に画面に表示される広告フォーマットです。アプリ起動時、コンテンツロード完了時、特定イベント発生時など、希望のタイミングで表示でき、ユーザーは閉じるボタンを押すか「今日は表示しない」を選択して終了できます。

### 特徴

* 画面中央または下部に表示されるポップアップ形式
* 画像および動画広告サポート
* 閉じる、ディム（背景）クリック、「今日は表示しない」オプション提供
* 背景色、テキスト色などカスタマイズ可能
* 非侵入的でありながら効果的な広告体験

<Note>
  開発環境ではテストユニットIDを使用してください。[テストユニットID](#テストユニットid)セクションを参照してください。
</Note>

***

## 実装手順

ポップアップ広告は以下の4ステップで実装します：

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

***

## 基本実装

### 基本的な使い方

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import io.adrop.ads.popupAd.AdropPopupAd
  import io.adrop.ads.popupAd.AdropPopupAdListener
  import io.adrop.ads.popupAd.AdropPopupAdCloseListener
  import io.adrop.ads.model.AdropErrorCode

  class MainActivity : AppCompatActivity() {
      private var popupAd: AdropPopupAd? = null

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

          // ポップアップ広告をロード
          loadPopupAd()
      }

      // 1. 広告の初期化とロード
      private fun loadPopupAd() {
          popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
          popupAd?.popupAdListener = popupAdListener
          popupAd?.closeListener = popupCloseListener
          popupAd?.load()
      }

      // 2. 広告を表示
      private fun showPopupAd() {
          popupAd?.let { ad ->
              if (ad.isLoaded) {
                  ad.show(this)
              }
          }
      }

      override fun onDestroy() {
          super.onDestroy()
          popupAd?.destroy()
      }
  }
  ```

  ```java Java theme={null}
  import io.adrop.ads.popupAd.AdropPopupAd;
  import io.adrop.ads.popupAd.AdropPopupAdListener;
  import io.adrop.ads.popupAd.AdropPopupAdCloseListener;
  import io.adrop.ads.model.AdropErrorCode;

  public class MainActivity extends AppCompatActivity {
      private AdropPopupAd popupAd;

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

          // ポップアップ広告をロード
          loadPopupAd();
      }

      // 1. 広告の初期化とロード
      private void loadPopupAd() {
          popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");
          popupAd.setPopupAdListener(popupAdListener);
          popupAd.setCloseListener(popupCloseListener);
          popupAd.load();
      }

      // 2. 広告を表示
      private void showPopupAd() {
          if (popupAd != null && popupAd.isLoaded()) {
              popupAd.show(this);
          }
      }

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

### リスナーの実装

<CodeGroup>
  ```kotlin Kotlin theme={null}
  // 広告リスナーの実装
  private val popupAdListener = object : AdropPopupAdListener {
      // 広告受信成功（必須）
      override fun onAdReceived(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告受信完了")
          // 広告が準備できたら表示
          showPopupAd()
      }

      // 広告受信失敗（必須）
      override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
          Log.d("Adrop", "ポップアップ広告受信失敗：$errorCode")
      }

      // 広告インプレッション（任意）
      override fun onAdImpression(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告インプレッション")
      }

      // 広告クリック（任意）
      override fun onAdClicked(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告クリック")
      }

      // ポップアップ広告表示直前（任意）
      override fun onAdWillPresentFullScreen(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告表示直前")
      }

      // ポップアップ広告表示直後（任意）
      override fun onAdDidPresentFullScreen(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告表示完了")
      }

      // ポップアップ広告閉じる直前（任意）
      override fun onAdWillDismissFullScreen(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告閉じる直前")
      }

      // ポップアップ広告閉じた直後（任意）
      override fun onAdDidDismissFullScreen(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告閉じました")
          // 次の広告を事前ロード
          loadPopupAd()
      }

      // ポップアップ広告表示失敗（任意）
      override fun onAdFailedToShowFullScreen(ad: AdropPopupAd, errorCode: AdropErrorCode) {
          Log.d("Adrop", "ポップアップ広告表示失敗：$errorCode")
      }

      // 動画再生開始（任意）
      override fun onAdVideoStart(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告動画再生開始")
      }

      // 動画再生終了（任意）
      override fun onAdVideoEnd(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告動画再生終了")
      }
  }

  // 閉じるリスナーの実装
  private val popupCloseListener = object : AdropPopupAdCloseListener {
      // 閉じるボタンクリック（任意）
      override fun onClosed(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告閉じるボタンクリック")
      }

      // ディム（背景）クリック（任意）
      override fun onDimClicked(ad: AdropPopupAd) {
          Log.d("Adrop", "ポップアップ広告ディム領域クリック")
      }

      // 「今日は表示しない」クリック（任意）
      override fun onTodayOffClicked(ad: AdropPopupAd) {
          Log.d("Adrop", "今日は表示しない選択")
          // 今日の日付を保存して次の表示を制御
          val prefs = getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
          prefs.edit().putLong("last_popup_hidden_date", System.currentTimeMillis()).apply()
      }
  }
  ```

  ```java Java theme={null}
  // 広告リスナーの実装
  private final AdropPopupAdListener popupAdListener = new AdropPopupAdListener() {
      // 広告受信成功（必須）
      @Override
      public void onAdReceived(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告受信完了");
          // 広告が準備できたら表示
          showPopupAd();
      }

      // 広告受信失敗（必須）
      @Override
      public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
          Log.d("Adrop", "ポップアップ広告受信失敗：" + errorCode);
      }

      // 広告インプレッション（任意）
      @Override
      public void onAdImpression(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告インプレッション");
      }

      // 広告クリック（任意）
      @Override
      public void onAdClicked(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告クリック");
      }

      // ポップアップ広告表示直前（任意）
      @Override
      public void onAdWillPresentFullScreen(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告表示直前");
      }

      // ポップアップ広告表示直後（任意）
      @Override
      public void onAdDidPresentFullScreen(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告表示完了");
      }

      // ポップアップ広告閉じる直前（任意）
      @Override
      public void onAdWillDismissFullScreen(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告閉じる直前");
      }

      // ポップアップ広告閉じた直後（任意）
      @Override
      public void onAdDidDismissFullScreen(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告閉じました");
          // 次の広告を事前ロード
          loadPopupAd();
      }

      // ポップアップ広告表示失敗（任意）
      @Override
      public void onAdFailedToShowFullScreen(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
          Log.d("Adrop", "ポップアップ広告表示失敗：" + errorCode);
      }

      // 動画再生開始（任意）
      @Override
      public void onAdVideoStart(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告動画再生開始");
      }

      // 動画再生終了（任意）
      @Override
      public void onAdVideoEnd(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告動画再生終了");
      }
  };

  // 閉じるリスナーの実装
  private final AdropPopupAdCloseListener popupCloseListener = new AdropPopupAdCloseListener() {
      // 閉じるボタンクリック（任意）
      @Override
      public void onClosed(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告閉じるボタンクリック");
      }

      // ディム（背景）クリック（任意）
      @Override
      public void onDimClicked(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "ポップアップ広告ディム領域クリック");
      }

      // 「今日は表示しない」クリック（任意）
      @Override
      public void onTodayOffClicked(@NotNull AdropPopupAd ad) {
          Log.d("Adrop", "今日は表示しない選択");
          // 今日の日付を保存して次の表示を制御
          SharedPreferences prefs = getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE);
          prefs.edit().putLong("last_popup_hidden_date", System.currentTimeMillis()).apply();
      }
  };
  ```
</CodeGroup>

***

## カスタマイズ

ポップアップ広告の外観をカスタマイズできます。

### 背景色とテキスト色の設定

<CodeGroup>
  ```kotlin Kotlin theme={null}
  private fun loadPopupAd() {
      popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
      popupAd?.popupAdListener = popupAdListener
      popupAd?.closeListener = popupCloseListener

      // 背景色を設定（ディム領域）
      popupAd?.backgroundColor = Color.parseColor("#CC000000")

      // 「今日は表示しない」テキスト色
      popupAd?.hideForTodayTextColor = Color.WHITE

      // 閉じるボタンテキスト色
      popupAd?.closeTextColor = Color.WHITE

      // CTAボタンテキスト色
      popupAd?.ctaTextColor = Color.BLUE

      popupAd?.load()
  }
  ```

  ```java Java theme={null}
  private void loadPopupAd() {
      popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");
      popupAd.setPopupAdListener(popupAdListener);
      popupAd.setCloseListener(popupCloseListener);

      // 背景色を設定（ディム領域）
      popupAd.setBackgroundColor(Color.parseColor("#CC000000"));

      // 「今日は表示しない」テキスト色
      popupAd.setHideForTodayTextColor(Color.WHITE);

      // 閉じるボタンテキスト色
      popupAd.setCloseTextColor(Color.WHITE);

      // CTAボタンテキスト色
      popupAd.setCtaTextColor(Color.BLUE);

      popupAd.load();
  }
  ```
</CodeGroup>

### カスタマイズオプション

| プロパティ                   | タイプ    | 説明              | デフォルト      |
| ----------------------- | ------ | --------------- | ---------- |
| `backgroundColor`       | `Int?` | ポップアップ背景（ディム）色  | 黒色（透明度0.8） |
| `hideForTodayTextColor` | `Int?` | 「今日は表示しない」テキスト色 | 白色         |
| `closeTextColor`        | `Int?` | 閉じるボタンテキスト色     | 白色         |
| `ctaTextColor`          | `Int?` | CTAボタンテキスト色     | システムデフォルト  |

***

## カスタムクリック処理

広告クリック時にデフォルトブラウザを開く代わりにカスタム処理をするには、`useCustomClick`プロパティを使用します。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  private fun loadPopupAd() {
      popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")

      // カスタムクリック処理を有効化
      popupAd?.useCustomClick = true

      popupAd?.popupAdListener = object : AdropPopupAdListener {
          override fun onAdReceived(ad: AdropPopupAd) {
              showPopupAd()
          }

          override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
              Log.d("Adrop", "広告受信失敗：$errorCode")
          }

          override fun onAdClicked(ad: AdropPopupAd) {
              // カスタムクリック処理
              Log.d("Adrop", "広告クリック：${ad.destinationURL}")

              // カスタムURLで開く
              popupAd?.open("https://your-custom-url.com")

              // またはアプリ内ブラウザで開く
              // openInAppBrowser(ad.destinationURL)
          }
      }

      popupAd?.load()
  }
  ```

  ```java Java theme={null}
  private void loadPopupAd() {
      popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");

      // カスタムクリック処理を有効化
      popupAd.setUseCustomClick(true);

      popupAd.setPopupAdListener(new AdropPopupAdListener() {
          @Override
          public void onAdReceived(@NotNull AdropPopupAd ad) {
              showPopupAd();
          }

          @Override
          public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
              Log.d("Adrop", "広告受信失敗：" + errorCode);
          }

          @Override
          public void onAdClicked(@NotNull AdropPopupAd ad) {
              // カスタムクリック処理
              Log.d("Adrop", "広告クリック：" + ad.getDestinationURL());

              // カスタムURLで開く
              popupAd.open("https://your-custom-url.com");

              // またはアプリ内ブラウザで開く
              // openInAppBrowser(ad.getDestinationURL());
          }
      });

      popupAd.load();
  }
  ```
</CodeGroup>

***

## 広告プロパティ

ポップアップ広告オブジェクトで以下のプロパティが使用できます：

<ParamField path="unitId" type="String">
  広告ユニットID
</ParamField>

<ParamField path="isLoaded" type="Boolean">
  広告がロードされたかどうか
</ParamField>

<ParamField path="creativeId" type="String">
  現在表示中の広告クリエイティブID
</ParamField>

<ParamField path="destinationURL" type="String">
  広告クリック時に移動するURL
</ParamField>

<ParamField path="txId" type="String">
  トランザクションID（広告インプレッション追跡用）
</ParamField>

<ParamField path="campaignId" type="String">
  キャンペーンID
</ParamField>

***

## リスナーメソッド

### AdropPopupAdListener（広告イベント）

#### 必須メソッド

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

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

#### 任意メソッド

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

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

<ParamField body="onAdWillPresentFullScreen" type="(AdropPopupAd) -> Unit">
  ポップアップ広告が表示される直前に呼び出されます。
</ParamField>

<ParamField body="onAdDidPresentFullScreen" type="(AdropPopupAd) -> Unit">
  ポップアップ広告が画面に表示された直後に呼び出されます。
</ParamField>

<ParamField body="onAdWillDismissFullScreen" type="(AdropPopupAd) -> Unit">
  ポップアップ広告が閉じる直前に呼び出されます。
</ParamField>

<ParamField body="onAdDidDismissFullScreen" type="(AdropPopupAd) -> Unit">
  ポップアップ広告が閉じた直後に呼び出されます。次の広告を事前ロードするのに良いタイミングです。
</ParamField>

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

<ParamField body="onAdVideoStart" type="(AdropPopupAd) -> Unit">
  動画ポップアップ広告で動画再生が開始された時に呼び出されます。
</ParamField>

<ParamField body="onAdVideoEnd" type="(AdropPopupAd) -> Unit">
  動画ポップアップ広告で動画再生が終了した時に呼び出されます。
</ParamField>

### AdropPopupAdCloseListener（閉じるイベント）

すべてのメソッドが任意です。

<ParamField body="onClosed" type="(AdropPopupAd) -> Unit">
  ユーザーが閉じるボタンをクリックした時に呼び出されます。
</ParamField>

<ParamField body="onDimClicked" type="(AdropPopupAd) -> Unit">
  ユーザーがポップアップ外部（ディム領域）をクリックした時に呼び出されます。
</ParamField>

<ParamField body="onTodayOffClicked" type="(AdropPopupAd) -> Unit">
  ユーザーが「今日は表示しない」を選択した時に呼び出されます。このコールバックで日付を保存して1日間広告を表示しないよう実装できます。
</ParamField>

***

## 「今日は表示しない」の実装

ユーザーが「今日は表示しない」を選択した時に適切に処理する方法です。

### SharedPreferencesを利用した実装

<CodeGroup>
  ```kotlin Kotlin theme={null}
  class PopupAdManager(private val context: Context) {
      private val prefs = context.getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
      private val todayOffKey = "popup_ad_today_off_date"
      private var popupAd: AdropPopupAd? = null

      // 今日広告を表示できるか確認
      fun canShowAdToday(): Boolean {
          val lastHiddenDate = prefs.getLong(todayOffKey, 0L)
          if (lastHiddenDate == 0L) return true

          val calendar = Calendar.getInstance()
          calendar.timeInMillis = lastHiddenDate
          val hiddenDay = calendar.get(Calendar.DAY_OF_YEAR)
          val hiddenYear = calendar.get(Calendar.YEAR)

          calendar.timeInMillis = System.currentTimeMillis()
          val currentDay = calendar.get(Calendar.DAY_OF_YEAR)
          val currentYear = calendar.get(Calendar.YEAR)

          // 保存した日付が今日でなければ表示可能
          return hiddenDay != currentDay || hiddenYear != currentYear
      }

      // 広告のロードと表示
      fun loadAndShowAd(activity: Activity, unitId: String) {
          if (!canShowAdToday()) {
              Log.d("Adrop", "今日は広告を表示しません")
              return
          }

          popupAd?.destroy()
          popupAd = AdropPopupAd(activity, unitId)
          popupAd?.popupAdListener = popupAdListener
          popupAd?.closeListener = popupCloseListener
          popupAd?.load()
      }

      private val popupAdListener = object : AdropPopupAdListener {
          override fun onAdReceived(ad: AdropPopupAd) {
              // 広告受信後に自動表示
              if (context is Activity) {
                  ad.show(context)
              }
          }

          override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
              Log.d("Adrop", "広告受信失敗：$errorCode")
          }
      }

      private val popupCloseListener = object : AdropPopupAdCloseListener {
          override fun onTodayOffClicked(ad: AdropPopupAd) {
              // 今日の日付を保存
              prefs.edit().putLong(todayOffKey, System.currentTimeMillis()).apply()
              Log.d("Adrop", "今日1日ポップアップ広告を表示しません")
          }
      }

      fun destroy() {
          popupAd?.destroy()
          popupAd = null
      }
  }
  ```

  ```java Java theme={null}
  public class PopupAdManager {
      private Context context;
      private SharedPreferences prefs;
      private static final String PREFS_NAME = "adrop_prefs";
      private static final String TODAY_OFF_KEY = "popup_ad_today_off_date";
      private AdropPopupAd popupAd;

      public PopupAdManager(Context context) {
          this.context = context;
          this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
      }

      // 今日広告を表示できるか確認
      public boolean canShowAdToday() {
          long lastHiddenDate = prefs.getLong(TODAY_OFF_KEY, 0L);
          if (lastHiddenDate == 0L) return true;

          Calendar calendar = Calendar.getInstance();
          calendar.setTimeInMillis(lastHiddenDate);
          int hiddenDay = calendar.get(Calendar.DAY_OF_YEAR);
          int hiddenYear = calendar.get(Calendar.YEAR);

          calendar.setTimeInMillis(System.currentTimeMillis());
          int currentDay = calendar.get(Calendar.DAY_OF_YEAR);
          int currentYear = calendar.get(Calendar.YEAR);

          // 保存した日付が今日でなければ表示可能
          return hiddenDay != currentDay || hiddenYear != currentYear;
      }

      // 広告のロードと表示
      public void loadAndShowAd(Activity activity, String unitId) {
          if (!canShowAdToday()) {
              Log.d("Adrop", "今日は広告を表示しません");
              return;
          }

          if (popupAd != null) {
              popupAd.destroy();
          }

          popupAd = new AdropPopupAd(activity, unitId);
          popupAd.setPopupAdListener(popupAdListener);
          popupAd.setCloseListener(popupCloseListener);
          popupAd.load();
      }

      private final AdropPopupAdListener popupAdListener = new AdropPopupAdListener() {
          @Override
          public void onAdReceived(@NotNull AdropPopupAd ad) {
              // 広告受信後に自動表示
              if (context instanceof Activity) {
                  ad.show((Activity) context);
              }
          }

          @Override
          public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
              Log.d("Adrop", "広告受信失敗：" + errorCode);
          }
      };

      private final AdropPopupAdCloseListener popupCloseListener = new AdropPopupAdCloseListener() {
          @Override
          public void onTodayOffClicked(@NotNull AdropPopupAd ad) {
              // 今日の日付を保存
              prefs.edit().putLong(TODAY_OFF_KEY, System.currentTimeMillis()).apply();
              Log.d("Adrop", "今日1日ポップアップ広告を表示しません");
          }
      };

      public void destroy() {
          if (popupAd != null) {
              popupAd.destroy();
              popupAd = null;
          }
      }
  }
  ```
</CodeGroup>

### 使用例

<CodeGroup>
  ```kotlin Kotlin theme={null}
  class MainActivity : AppCompatActivity() {
      private lateinit var popupAdManager: PopupAdManager

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

          popupAdManager = PopupAdManager(this)

          // アプリ起動時にポップアップ広告を表示
          popupAdManager.loadAndShowAd(this, "YOUR_POPUP_UNIT_ID")
      }

      override fun onDestroy() {
          super.onDestroy()
          popupAdManager.destroy()
      }
  }
  ```

  ```java Java theme={null}
  public class MainActivity extends AppCompatActivity {
      private PopupAdManager popupAdManager;

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

          popupAdManager = new PopupAdManager(this);

          // アプリ起動時にポップアップ広告を表示
          popupAdManager.loadAndShowAd(this, "YOUR_POPUP_UNIT_ID");
      }

      @Override
      protected void onDestroy() {
          super.onDestroy();
          popupAdManager.destroy();
      }
  }
  ```
</CodeGroup>

***

## ポップアップタイプ

ポップアップ広告は2つのタイプで提供されます：

| タイプ            | 説明       | 位置            |
| -------------- | -------- | ------------- |
| `POPUP_BOTTOM` | 下部ポップアップ | 画面下部からスライドアップ |
| `POPUP_CENTER` | 中央ポップアップ | 画面中央に表示       |

<Note>
  ポップアップタイプはAdropコンソールで広告ユニット作成時に設定されます。コードで別途指定する必要はありません。
</Note>

***

## ベストプラクティス

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

ポップアップ広告は以下のタイミングで表示すると効果的です：

```kotlin theme={null}
// 良い例：アプリ起動時
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    loadAndShowPopupAd()
}

// 良い例：コンテンツロード完了時
fun onContentLoaded() {
    if (shouldShowPopupAd()) {
        showPopupAd()
    }
}

// 良い例：特定イベント完了時
fun onAchievementUnlocked() {
    showPopupAd()
}

// 悪い例：ユーザーが作業中の時
fun onUserTyping() {
    showPopupAd() // ユーザー体験を阻害
}
```

### 2. 「今日は表示しない」を尊重

ユーザーが「今日は表示しない」を選択したら必ず遵守してください。

```kotlin theme={null}
fun shouldShowPopupAd(): Boolean {
    // 今日は表示しない確認
    if (!canShowAdToday()) {
        return false
    }

    // 他の条件確認
    return true
}
```

### 3. 頻度制限

ポップアップ広告を頻繁に表示しすぎないでください。

<CodeGroup>
  ```kotlin Kotlin theme={null}
  class PopupAdFrequencyManager(private val context: Context) {
      private val prefs = context.getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
      private val lastShownKey = "popup_ad_last_shown"
      private val minimumInterval = 3600000L // 1時間（ミリ秒）

      fun canShowAd(): Boolean {
          // 今日は表示しない確認
          if (!canShowAdToday()) {
              return false
          }

          // 最小時間間隔確認
          val lastShown = prefs.getLong(lastShownKey, 0L)
          if (lastShown == 0L) return true

          val currentTime = System.currentTimeMillis()
          return currentTime - lastShown >= minimumInterval
      }

      fun recordAdShown() {
          prefs.edit().putLong(lastShownKey, System.currentTimeMillis()).apply()
      }

      private fun canShowAdToday(): Boolean {
          // 上記の「今日は表示しない」実装を参照
          return true
      }
  }
  ```

  ```java Java theme={null}
  public class PopupAdFrequencyManager {
      private SharedPreferences prefs;
      private static final String PREFS_NAME = "adrop_prefs";
      private static final String LAST_SHOWN_KEY = "popup_ad_last_shown";
      private static final long MINIMUM_INTERVAL = 3600000L; // 1時間（ミリ秒）

      public PopupAdFrequencyManager(Context context) {
          this.prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
      }

      public boolean canShowAd() {
          // 今日は表示しない確認
          if (!canShowAdToday()) {
              return false;
          }

          // 最小時間間隔確認
          long lastShown = prefs.getLong(LAST_SHOWN_KEY, 0L);
          if (lastShown == 0L) return true;

          long currentTime = System.currentTimeMillis();
          return currentTime - lastShown >= MINIMUM_INTERVAL;
      }

      public void recordAdShown() {
          prefs.edit().putLong(LAST_SHOWN_KEY, System.currentTimeMillis()).apply();
      }

      private boolean canShowAdToday() {
          // 上記の「今日は表示しない」実装を参照
          return true;
      }
  }
  ```
</CodeGroup>

### 4. 広告の事前ロード

ユーザー体験のために広告を事前ロードしてください。

```kotlin theme={null}
class MainActivity : AppCompatActivity() {
    private var popupAd: AdropPopupAd? = null
    private var isAdReady = false

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

        // 事前ロード
        preloadPopupAd()
    }

    private fun preloadPopupAd() {
        popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")
        popupAd?.popupAdListener = object : AdropPopupAdListener {
            override fun onAdReceived(ad: AdropPopupAd) {
                isAdReady = true
            }

            override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
                Log.d("Adrop", "広告受信失敗：$errorCode")
            }
        }
        popupAd?.load()
    }

    fun showPopupAdIfReady() {
        if (isAdReady) {
            popupAd?.show(this)
        }
    }
}
```

### 5. 横画面モード処理

ポップアップ広告は縦画面モードでのみサポートされます。横画面モードでは`onAdFailedToShowFullScreen`が呼び出されます。

```kotlin theme={null}
private val popupAdListener = object : AdropPopupAdListener {
    override fun onAdReceived(ad: AdropPopupAd) {
        // 縦画面モードの時のみ表示
        if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
            ad.show(this@MainActivity)
        }
    }

    override fun onAdFailedToShowFullScreen(ad: AdropPopupAd, errorCode: AdropErrorCode) {
        if (errorCode == AdropErrorCode.ERROR_CODE_LANDSCAPE_UNSUPPORTED) {
            Log.d("Adrop", "ポップアップ広告は縦画面モードでのみサポートされます")
        }
    }

    override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
        Log.d("Adrop", "広告受信失敗：$errorCode")
    }
}
```

***

## テストユニットID

開発およびテスト時に以下のテストユニットIDを使用してください。

| 広告タイプ            | テストユニットID                                     |
| ---------------- | --------------------------------------------- |
| ポップアップ（下部画像）     | `PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM`            |
| ポップアップ（中央画像）     | `PUBLIC_TEST_UNIT_ID_POPUP_CENTER`            |
| ポップアップ動画（下部16:9） | `PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_16_9` |
| ポップアップ動画（下部9:16） | `PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_9_16` |
| ポップアップ動画（中央16:9） | `PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_16_9` |
| ポップアップ動画（中央9:16） | `PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_9_16` |

### テスト広告の使用例

<CodeGroup>
  ```kotlin Kotlin theme={null}
  // テスト環境とプロダクション環境を分離
  val popupUnitId = if (BuildConfig.DEBUG) {
      "PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM"
  } else {
      "YOUR_PRODUCTION_UNIT_ID"
  }

  popupAd = AdropPopupAd(this, popupUnitId)
  ```

  ```java Java theme={null}
  // テスト環境とプロダクション環境を分離
  String popupUnitId;
  if (BuildConfig.DEBUG) {
      popupUnitId = "PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM";
  } else {
      popupUnitId = "YOUR_PRODUCTION_UNIT_ID";
  }

  popupAd = new AdropPopupAd(this, popupUnitId);
  ```
</CodeGroup>

<Warning>
  実際のリリース時には必ずAdropコンソールで作成した実際のユニットIDを使用してください。
</Warning>

***

## 完全な例

<CodeGroup>
  ```kotlin Kotlin theme={null}
  import android.graphics.Color
  import android.os.Bundle
  import android.util.Log
  import androidx.appcompat.app.AppCompatActivity
  import io.adrop.ads.model.AdropErrorCode
  import io.adrop.ads.popupAd.AdropPopupAd
  import io.adrop.ads.popupAd.AdropPopupAdCloseListener
  import io.adrop.ads.popupAd.AdropPopupAdListener

  class PopupAdActivity : AppCompatActivity() {
      private var popupAd: AdropPopupAd? = null

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

          // ボタンクリックで広告をロードして表示
          findViewById<Button>(R.id.btn_show_popup).setOnClickListener {
              loadPopupAd()
          }
      }

      private fun loadPopupAd() {
          // 既存の広告をクリーンアップ
          popupAd?.destroy()

          // ポップアップ広告を作成
          popupAd = AdropPopupAd(this, "YOUR_POPUP_UNIT_ID")

          // カスタマイズ
          popupAd?.apply {
              backgroundColor = Color.parseColor("#CC000000")
              hideForTodayTextColor = Color.WHITE
              closeTextColor = Color.WHITE
              ctaTextColor = Color.BLUE
              useCustomClick = false
          }

          // リスナーを設定
          popupAd?.popupAdListener = object : AdropPopupAdListener {
              override fun onAdReceived(ad: AdropPopupAd) {
                  Log.d("Adrop", "ポップアップ広告受信完了")
                  showPopupAd()
              }

              override fun onAdFailedToReceive(ad: AdropPopupAd, errorCode: AdropErrorCode) {
                  Log.d("Adrop", "ポップアップ広告受信失敗：$errorCode")
              }

              override fun onAdImpression(ad: AdropPopupAd) {
                  Log.d("Adrop", "ポップアップ広告インプレッション")
                  Log.d("Adrop", "txId: ${ad.txId}, campaignId: ${ad.campaignId}")
              }

              override fun onAdClicked(ad: AdropPopupAd) {
                  Log.d("Adrop", "ポップアップ広告クリック：${ad.destinationURL}")
              }

              override fun onAdDidPresentFullScreen(ad: AdropPopupAd) {
                  Log.d("Adrop", "ポップアップ広告表示")
              }

              override fun onAdDidDismissFullScreen(ad: AdropPopupAd) {
                  Log.d("Adrop", "ポップアップ広告閉じました")
                  // 次の広告を事前ロード
                  loadPopupAd()
              }

              override fun onAdFailedToShowFullScreen(ad: AdropPopupAd, errorCode: AdropErrorCode) {
                  Log.d("Adrop", "ポップアップ広告表示失敗：$errorCode")
              }
          }

          popupAd?.closeListener = object : AdropPopupAdCloseListener {
              override fun onClosed(ad: AdropPopupAd) {
                  Log.d("Adrop", "閉じるボタンクリック")
              }

              override fun onDimClicked(ad: AdropPopupAd) {
                  Log.d("Adrop", "ディム領域クリック")
              }

              override fun onTodayOffClicked(ad: AdropPopupAd) {
                  Log.d("Adrop", "今日は表示しない選択")
                  saveHiddenDate()
              }
          }

          // 広告をロード
          popupAd?.load()
      }

      private fun showPopupAd() {
          popupAd?.let { ad ->
              if (ad.isLoaded) {
                  ad.show(this)
              }
          }
      }

      private fun saveHiddenDate() {
          val prefs = getSharedPreferences("adrop_prefs", MODE_PRIVATE)
          prefs.edit().putLong("last_popup_hidden_date", System.currentTimeMillis()).apply()
      }

      override fun onDestroy() {
          super.onDestroy()
          popupAd?.destroy()
      }
  }
  ```

  ```java Java theme={null}
  import android.graphics.Color;
  import android.os.Bundle;
  import android.util.Log;
  import android.widget.Button;
  import androidx.appcompat.app.AppCompatActivity;
  import io.adrop.ads.model.AdropErrorCode;
  import io.adrop.ads.popupAd.AdropPopupAd;
  import io.adrop.ads.popupAd.AdropPopupAdCloseListener;
  import io.adrop.ads.popupAd.AdropPopupAdListener;
  import org.jetbrains.annotations.NotNull;

  public class PopupAdActivity extends AppCompatActivity {
      private AdropPopupAd popupAd;

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

          // ボタンクリックで広告をロードして表示
          findViewById(R.id.btn_show_popup).setOnClickListener(v -> loadPopupAd());
      }

      private void loadPopupAd() {
          // 既存の広告をクリーンアップ
          if (popupAd != null) {
              popupAd.destroy();
          }

          // ポップアップ広告を作成
          popupAd = new AdropPopupAd(this, "YOUR_POPUP_UNIT_ID");

          // カスタマイズ
          popupAd.setBackgroundColor(Color.parseColor("#CC000000"));
          popupAd.setHideForTodayTextColor(Color.WHITE);
          popupAd.setCloseTextColor(Color.WHITE);
          popupAd.setCtaTextColor(Color.BLUE);
          popupAd.setUseCustomClick(false);

          // リスナーを設定
          popupAd.setPopupAdListener(new AdropPopupAdListener() {
              @Override
              public void onAdReceived(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "ポップアップ広告受信完了");
                  showPopupAd();
              }

              @Override
              public void onAdFailedToReceive(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
                  Log.d("Adrop", "ポップアップ広告受信失敗：" + errorCode);
              }

              @Override
              public void onAdImpression(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "ポップアップ広告インプレッション");
                  Log.d("Adrop", "txId: " + ad.getTxId() + ", campaignId: " + ad.getCampaignId());
              }

              @Override
              public void onAdClicked(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "ポップアップ広告クリック：" + ad.getDestinationURL());
              }

              @Override
              public void onAdDidPresentFullScreen(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "ポップアップ広告表示");
              }

              @Override
              public void onAdDidDismissFullScreen(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "ポップアップ広告閉じました");
                  // 次の広告を事前ロード
                  loadPopupAd();
              }

              @Override
              public void onAdFailedToShowFullScreen(@NotNull AdropPopupAd ad, @NotNull AdropErrorCode errorCode) {
                  Log.d("Adrop", "ポップアップ広告表示失敗：" + errorCode);
              }
          });

          popupAd.setCloseListener(new AdropPopupAdCloseListener() {
              @Override
              public void onClosed(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "閉じるボタンクリック");
              }

              @Override
              public void onDimClicked(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "ディム領域クリック");
              }

              @Override
              public void onTodayOffClicked(@NotNull AdropPopupAd ad) {
                  Log.d("Adrop", "今日は表示しない選択");
                  saveHiddenDate();
              }
          });

          // 広告をロード
          popupAd.load();
      }

      private void showPopupAd() {
          if (popupAd != null && popupAd.isLoaded()) {
              popupAd.show(this);
          }
      }

      private void saveHiddenDate() {
          getSharedPreferences("adrop_prefs", MODE_PRIVATE)
                  .edit()
                  .putLong("last_popup_hidden_date", System.currentTimeMillis())
                  .apply();
      }

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

***

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

### 広告が表示されない

<AccordionGroup>
  <Accordion title="onAdReceivedが呼び出されない">
    * SDKが初期化されているか確認
    * ユニットIDが正しいか確認
    * ネットワーク接続状態を確認
    * Adrop SDK初期化時の`production`設定を確認
  </Accordion>

  <Accordion title="onAdFailedToReceiveが呼び出される">
    * エラーコードを確認して原因を把握
    * テスト環境ではテストユニットIDを使用
    * 広告インベントリ不足時は後で再試行
    * `ERROR_CODE_AD_HIDE_FOR_TODAY`：「今日は表示しない」が有効な状態
  </Accordion>

  <Accordion title="show()呼び出し後に何も起こらない">
    * `onAdReceived`コールバック後に`show()`を呼び出したか確認
    * Activityが有効な状態か確認
    * `isLoaded`プロパティを確認して広告がロードされたか確認
    * 縦画面モードか確認（横画面モードはサポートされません）
  </Accordion>

  <Accordion title="横画面モードで広告が表示されない">
    ポップアップ広告は縦画面モードでのみサポートされます。横画面モードで`show()`を呼び出すと、`onAdFailedToShowFullScreen`が`ERROR_CODE_LANDSCAPE_UNSUPPORTED`エラーコードと共に呼び出されます。
  </Accordion>
</AccordionGroup>

### 「今日は表示しない」が動作しない

```kotlin theme={null}
// 日付比較ロジックを確認
fun isToday(timestamp: Long): Boolean {
    val calendar = Calendar.getInstance()
    val today = calendar.apply {
        timeInMillis = System.currentTimeMillis()
    }

    val targetDay = Calendar.getInstance().apply {
        timeInMillis = timestamp
    }

    return today.get(Calendar.YEAR) == targetDay.get(Calendar.YEAR) &&
           today.get(Calendar.DAY_OF_YEAR) == targetDay.get(Calendar.DAY_OF_YEAR)
}

// 使用
fun canShowAdToday(): Boolean {
    val prefs = getSharedPreferences("adrop_prefs", Context.MODE_PRIVATE)
    val lastHiddenDate = prefs.getLong("last_popup_hidden_date", 0L)

    return lastHiddenDate == 0L || !isToday(lastHiddenDate)
}
```

***

## 関連ドキュメント

<CardGroup cols={2}>
  <Card title="はじめに" href="/ja/sdk/android">
    SDKのインストールと初期化
  </Card>

  <Card title="インタースティシャル広告" href="/ja/sdk/android/interstitial">
    インタースティシャル広告を実装
  </Card>

  <Card title="リワード広告" href="/ja/sdk/android/rewarded">
    リワード広告を実装
  </Card>

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