アプリ起動時広告を設定する

アプリ起動時広告は、ユーザーがアプリを開いたとき、またはアプリに戻ったときに表示されます。ユーザーはいつでもアプリ起動時広告を閉じることができます。アプリの読み込み画面を収益化するには、アプリ起動時広告を使用します。詳しくは、アプリ起動時広告に関するガイドラインとベスト プラクティスをご覧ください。

このガイドでは、React Native アプリにアプリ起動時広告を組み込む方法について説明します。

前提条件

先に進む前に、次のことを実施してください。

Android

ca-app-pub-3940256099942544/9257395921

iOS

ca-app-pub-3940256099942544/5575463023

広告のプリロードについて

Google Mobile Ads SDK for React Native の広告のプリロード機能により、広告の読み込みとキャッシュが自動化されます。

広告のプリロードには、次のようなメリットがあります。

  • 参照管理: 広告が表示されるまで参照を維持します。
  • 自動リロード: キャッシュから広告が取得されると、新しい広告が読み込まれます。
  • マネージド再試行: 広告の読み込みに失敗した場合に、新しい広告を読み込みます。
  • 有効期限の処理: 有効期限が切れる前に広告を更新します。
  • キャッシュの最適化: キャッシュの順序を最適化して、優先度の最も高い広告を配信します。

広告を手動で読み込むには、単一のアプリ起動時広告を読み込むガイドをご覧ください。

プリロードを開始する

広告のプリロードを開始するには、AppOpenAdPreloader.start メソッドを呼び出し、preloadId 値、構成設定、イベント コールバックを渡して、バッファ状態の変化をモニタリングします。

export function startAppOpenAdPreloader(
  adUnitId: string,
  preloadId: string,
  customPreloadCallback?: PreloadCallback,
): boolean {
  const started = AppOpenAdPreloader.start(
    preloadId,
    {
      request: {adUnitId},
      bufferSize: 2,
    },
    {
      // Called when an ad is preloaded into the buffer.
      onAdPreloaded: (event) => {
        console.log(`App open ad preloaded for ${event.preloadId}`);
        customPreloadCallback?.onAdPreloaded?.(event);
      },
      // Called when an ad fails to preload.
      onAdFailedToPreload: (error: LoadAdError) => {
        console.error('Failed to preload app open ad:', error.message);
        customPreloadCallback?.onAdFailedToPreload?.(error);
      },
      // Called when all preloaded ads in the buffer have been shown.
      onAdsExhausted: () => {
        console.log('App open ad buffer exhausted.');
        customPreloadCallback?.onAdsExhausted?.();
      },
    },
  );
  return started;
}

preloadId は、広告のプリロード構成を一意に識別する文字列です。adUnitId がアプリ内の 1 つのプリロード設定にのみ使用されている場合は、その広告ユニット ID をプリロード ID として使用できます。アプリで同じ広告ユニット ID に複数のプリローダーが必要な場合は、プリロード ID ごとに異なる文字列を渡します。

アプリがバッファからプリロードされた広告をポーリングすると、Google Mobile Ads SDK for React Native はバックグラウンドで代替広告をリクエストしてバッファを補充します。バッファにプリロードされた広告が残っていない場合、Google Mobile Ads SDK for React Native は onAdsExhausted コールバックを呼び出します。

プリロード キャッシュの上限

Google Mobile Ads SDK for React Native では、プリロードされた広告の合計数にアプリ全体の上限が適用されます。

  • デフォルトの上限: Google は、プリロードされた広告を最大 6 つメモリに保持します。
  • プリロード ID ごとに 2 つのバッファサイズを維持することをおすすめします。

アプリがアプリ全体の上限に達すると、既存の広告がポーリングされて表示されるか、破棄されるまで、プリロードされた広告のバックグラウンド リクエストは一時停止されます。

ポーリングして広告を表示する

利用可能なプリロードされた広告を確認して広告インスタンスを取得するには、AppOpenAdPreloader.pollAd メソッドを呼び出します。

全画面表示イベントをリッスンするには、show メソッドを呼び出す前に、返された AppOpenAd インスタンスの adEventCallback プロパティにコールバックを登録します。

export function showPreloadedAppOpenAd(
  preloadId: string,
  customAdEventCallback?: FullScreenAdEventCallback,
) {
  if (!AppOpenAdPreloader.isAdAvailable(preloadId)) {
    console.log('No preloaded app open ad available right now.');
    return;
  }

  const ad = AppOpenAdPreloader.pollAd(preloadId);
  if (!ad) {
    return;
  }

  ad.adEventCallback = {
    // Called when the ad is presented on screen.
    onAdShowedFullScreenContent: () => {
      console.log('Preloaded app open ad showed full screen content.');
      customAdEventCallback?.onAdShowedFullScreenContent?.();
    },
    // Called when the ad is closed by the user.
    onAdDismissedFullScreenContent: () => {
      console.log('Preloaded app open ad dismissed full screen content.');
      customAdEventCallback?.onAdDismissedFullScreenContent?.();
      ad.destroy();
    },
    // Called when presentation fails.
    onAdFailedToShowFullScreenContent: (error) => {
      console.error('Failed to show preloaded app open ad:', error);
      customAdEventCallback?.onAdFailedToShowFullScreenContent?.(error);
      ad.destroy();
    },
    // Called when an impression is recorded.
    onAdImpression: () => {
      console.log('Preloaded app open ad recorded an impression.');
      customAdEventCallback?.onAdImpression?.();
    },
    // Called when the user taps the ad.
    onAdClicked: () => {
      console.log('Preloaded app open ad was clicked.');
      customAdEventCallback?.onAdClicked?.();
    },
    // Called when the ad is estimated to have earned money.
    onAdPaid: (adValue) => {
      console.log(
        `Preloaded app open ad paid: ${adValue.amountMicros}` +
          ` ${adValue.currencyCode}`,
      );
      customAdEventCallback?.onAdPaid?.(adValue);
    },
  };

  ad.show();
}

メモリとリソースを解放するには、ユーザーが広告を閉じたとき、または広告の表示に失敗したときに、onAdDismissedFullScreenContent コールバックと onAdFailedToShowFullScreenContent コールバックで ad.destroy メソッドを呼び出します。

レスポンス情報を読み取る

キャッシュから広告を削除せずに、次にプリロードされる広告の詳細を調べるには、AppOpenAdPreloader.peekAdResponseInfo メソッドを呼び出します。

export function peekAppOpenAdResponseInfo(
  preloadId: string,
): ResponseInfo | null {
  const responseInfo = AppOpenAdPreloader.peekAdResponseInfo(preloadId);
  if (responseInfo) {
    console.log('Next preloaded app open ad response info:', responseInfo);
  }
  return responseInfo;
}

アプリレベルのマネージャーでアプリ起動時広告を管理する

アプリ起動時広告は、アプリの起動時とフォアグラウンドへの移行時にグローバルに表示されるため、React コンポーネント ツリー外のアプリレベルのマネージャーでプリローダーのライフサイクル状態を管理することをおすすめします。

アプリレベルのマネージャーを使用すると、主に次のようなメリットがあります。

  • プリローダーの状態を、個々の画面ナビゲーションやコンポーネントのライフサイクルから独立させます。
  • 広告イベント コールバック、状態トラッキング、クリーンアップを、アプリ全体で 1 つの共有インスタンスに一元化します。
  • フォアグラウンド イベントをリッスンするタイミングを制御し、広告の終了時に重複して表示されないようにします。

次の例では、AppOpenAdPreloader オブジェクトを使用してアプリレベルのマネージャーを実装しています。

export class AppOpenAdManager {
  private adUnitId: string;
  private preloadId: string;
  private appStateSubscription?: NativeEventSubscription;
  private startTimeoutId?: ReturnType<typeof setTimeout>;

  constructor(adUnitId: string, preloadId: string) {
    this.adUnitId = adUnitId;
    this.preloadId = preloadId;
  }

  start(): boolean {
    if (!AppOpenAdPreloader.getConfiguration(this.preloadId)) {
      AppOpenAdPreloader.start(
        this.preloadId,
        {
          request: {adUnitId: this.adUnitId},
          bufferSize: 2,
        },
        {
          onAdPreloaded: (event) => {
            console.log(`App open ad preloaded for ${event.preloadId}`);
          },
          onAdFailedToPreload: (error: LoadAdError) => {
            console.error('Failed to preload app open ad:', error.message);
          },
          onAdsExhausted: () => {
            console.log('App open ad buffer exhausted.');
          },
        },
      );
    }

    if (!this.appStateSubscription && !this.startTimeoutId) {
      // Delay attaching the listener to ensure native dismissal transitions complete
      this.startTimeoutId = setTimeout(() => {
        this.startTimeoutId = undefined;
        if (!this.appStateSubscription) {
          this.appStateSubscription = AppState.addEventListener(
            'change',
            (nextAppState: AppStateStatus) => {
              if (nextAppState === 'active') {
                this.showAdIfAvailable();
              }
            },
          );
        }
      }, APP_STATE_LISTENER_DELAY_MS);
    }

    return true;
  }

  pause(): void {
    if (this.startTimeoutId) {
      clearTimeout(this.startTimeoutId);
      this.startTimeoutId = undefined;
    }
    this.appStateSubscription?.remove();
    this.appStateSubscription = undefined;
  }

  stop(): void {
    this.pause();
    AppOpenAdPreloader.destroy(this.preloadId);
  }

  showAdIfAvailable() {
    if (!AppOpenAdPreloader.isAdAvailable(this.preloadId)) {
      console.log('App open ad is not preloaded or available right now.');
      return;
    }

    const ad = AppOpenAdPreloader.pollAd(this.preloadId);
    if (!ad) {
      return;
    }

    // Pause listener while presenting the ad
    this.pause();

    ad.adEventCallback = {
      onAdShowedFullScreenContent: () => {
        console.log('Preloaded app open ad showed full screen content.');
      },
      onAdDismissedFullScreenContent: () => {
        console.log('Preloaded app open ad dismissed full screen content.');
        ad.destroy();
        this.start();
      },
      onAdFailedToShowFullScreenContent: (error) => {
        console.error('Failed to show preloaded app open ad:', error);
        ad.destroy();
        this.start();
      },
    };

    ad.show();
  }
}

アプリのフォアグラウンド イベントをリッスンする

アプリがフォアグラウンドに戻ったときに広告を表示するには、アプリのルート コンポーネント(App.tsx など)の AppState モジュールに change リスナーを登録します。状態が active に移行するタイミングを確認します。たとえば、App.tsx コンポーネントで広告マネージャー インスタンスの start メソッドを呼び出します。

広告オーバーレイやランディング ページを表示する(フルスクリーン広告を表示する、バナー広告をタップするなど)と、アプリはバックグラウンドに移動します。ユーザーがアプリに戻ると、アプリは新しい active 状態イベントを受け取ります。意図しない広告表示や、広告から戻ったときにキャッシュからアプリ起動時広告が表示されるループを防ぐには、次の操作を行います。

  1. フルスクリーン広告を表示する前に、AppState イベント リスナーを削除します。
  2. ユーザーが広告を閉じた場合や広告の表示に失敗した場合でも、音声認識が再開されるようにするには、onAdDismissedFullScreenContent コールバックと onAdFailedToShowFullScreenContent コールバックに AppState イベント リスナーを再度追加します。

フォアグラウンド イベント リスナーの一時停止と再開のタイミングを制御する実証済みの例については、AppOpenAdManager の実装をご覧ください。

コールド スタートと読み込み画面について

コールド スタートは、アプリがゼロから起動するときに発生します。たとえば、ユーザーが初めてアプリを開くときや、デバイスがメモリを解放するためにアプリを閉じた後に発生します。コールド スタートでは、次に表示する読み込み済みのアプリ起動時広告がありません。

広告リクエストの遅延により、広告が表示される前にユーザーがアプリを操作する可能性があります。コールド スタートでアプリ起動時広告を表示する場合は、アセットの読み込み中に読み込み画面からのみ表示します。アセットの読み込みが完了し、広告の読み込みが完了する前にユーザーがメイン コンテンツに到達した場合は、広告を表示しないでください。

リソースのクリーンアップ

画面または広告ユニット ID でプリロードが不要になった場合(広告をプリロードする画面から移動する場合など)は、AppOpenAdPreloader.destroy メソッドを呼び出してプリローダー リソースを解放し、未使用の広告オブジェクトがメモリに保持されないようにします。

export function destroyAppOpenAdPreloader(preloadId: string) {
  AppOpenAdPreloader.destroy(preloadId);
}

プリローダー キューを破棄するだけでなく、ユーザーが広告を閉じたときや広告の表示に失敗したときには、個々のポーリングされた広告インスタンスを破棄してください。詳細については、広告をポーリングして表示するをご覧ください。

サンプル全体を表示する

次のコンポーネントの例では、マウント時にプリロードを開始し、利用可能な広告数を追跡して、プリロードされたアプリ起動時広告を表示するコントロールを提供します。

export function AppOpenScreen() {
  const [numAdsAvailable, setNumAdsAvailable] = useState<number>(0);
  const [status, setStatus] = useState<string>('Preloader idle.');

  const refreshAdCount = () => {
    const count = AppOpenAdPreloader.getNumAdsAvailable(PRELOAD_ID);
    setNumAdsAvailable(count);
  };

  useEffect(() => {
    // Start preloading ads on component mount
    const started = startAppOpenAdPreloader(APP_OPEN_AD_UNIT_ID, PRELOAD_ID, {
      onAdPreloaded: () => {
        refreshAdCount();
        setStatus('App open ad preloaded into buffer.');
      },
      onAdFailedToPreload: (error) => {
        setStatus(`Failed to preload app open ad: ${error.message}`);
      },
      onAdsExhausted: () => {
        refreshAdCount();
        setStatus('Preload buffer exhausted for app open ads.');
      },
    });
    if (started) {
      setStatus('Preloader started.');
    }

    // Clean up preloader resources on component unmount
    return () => {
      destroyAppOpenAdPreloader(PRELOAD_ID);
    };
  }, []);

  const handleShowAd = () => {
    setStatus('Showing preloaded ad...');
    showPreloadedAppOpenAd(PRELOAD_ID, {
      onAdDismissedFullScreenContent: () => {
        setStatus('Ad dismissed.');
      },
      onAdFailedToShowFullScreenContent: (error) => {
        setStatus(`Failed to show preloaded ad: ${error.message}`);
      },
    });
    refreshAdCount();
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Preload App Open Ads</Text>
      <Text style={styles.status}>Status: {status}</Text>
      <Text style={styles.status}>Ads Available: {numAdsAvailable}</Text>
      <View style={styles.buttonGroup}>
        <Button
          title="Show Preloaded Ad"
          onPress={handleShowAd}
          disabled={numAdsAvailable === 0}
        />
      </View>
    </View>
  );
}

次のように置き換えます。

  • APP_OPEN_AD_UNIT_ID を実際の広告ユニット ID に置換。
  • PRELOAD_ID を実際のプリローダー ID に置換。

次のステップ

アプリ起動時広告を統合したら、次のトピックをご覧ください。