應用程式開啟頁面廣告

選取平台: Android iOS Unity Flutter

本指南適用於使用 Google Mobile Ads SDK 整合應用程式開啟廣告的發布商。

應用程式開啟頁面廣告是一種特殊廣告格式,適合想藉由應用程式載入畫面賺取收益的發布商。這類廣告會在使用者將應用程式切換至前景時出現,而且使用者隨時可以關閉。

應用程式開啟頁面廣告會自動顯示一小塊品牌區域,讓使用者知道他們仍在您的應用程式中。以下是這類廣告的範例:

必要條件

請一律使用測試廣告進行測試

建構及測試應用程式時,請務必使用測試廣告,而非實際的正式廣告;違反者帳戶將可能遭到停權。

如要載入測試廣告,最簡單的方法是使用應用程式開啟廣告專用的測試廣告單元 ID:

ca-app-pub-3940256099942544/9257395921

這個 ID 經過特別設定,可針對每項要求傳回測試廣告。您編寫程式碼、測試及偵錯時,可以在自己的應用程式中自由使用。但請務必留意,在發布應用程式前,將這個 ID 換成您自己的廣告單元 ID。

如要進一步瞭解 Google Mobile Ads SDK 測試廣告的運作方式,請參閱「啟用測試廣告」。

擴充 Application 類別

建立擴充 Application 類別的新類別。這樣一來,您就能以生命週期感知的方式管理與應用程式狀態相關聯的廣告,而不是單一 Activity

Java

public class MyApplication extends Application
    implements ActivityLifecycleCallbacks, DefaultLifecycleObserver {

  private AppOpenAdManager appOpenAdManager;
  private Activity currentActivity;

  @Override
  public void onCreate() {
    super.onCreate();
    this.registerActivityLifecycleCallbacks(this);

    ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    appOpenAdManager = new AppOpenAdManager();
  }

Kotlin

class MyApplication :
  MultiDexApplication(), Application.ActivityLifecycleCallbacks, DefaultLifecycleObserver {

  private lateinit var appOpenAdManager: AppOpenAdManager
  private var currentActivity: Activity? = null

  override fun onCreate() {
    super<MultiDexApplication>.onCreate()
    registerActivityLifecycleCallbacks(this)

    ProcessLifecycleOwner.get().lifecycle.addObserver(this)
    appOpenAdManager = AppOpenAdManager()
  }

接著,將下列程式碼新增至 AndroidManifest.xml

<!-- TODO: Update to reference your actual package name. -->
<application
    android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>

實作公用程式元件

廣告應能快速顯示,因此最好在需要顯示廣告前載入廣告。這樣一來,使用者進入應用程式後,您就能立即放送廣告。

導入公用程式元件 AppOpenAdManager,封裝與載入及顯示應用程式開啟頁面廣告相關的工作:

Java

private class AppOpenAdManager {

  private static final String LOG_TAG = "AppOpenAdManager";
  private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/9257395921";

  private AppOpenAd appOpenAd = null;
  private boolean isLoadingAd = false;
  private boolean isShowingAd = false;

  /** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
  private long loadTime = 0;

  /** Constructor. */
  public AppOpenAdManager() {}

Kotlin

private inner class AppOpenAdManager {

  private var appOpenAd: AppOpenAd? = null
  private var isLoadingAd = false
  var isShowingAd = false

  /** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */
  private var loadTime: Long = 0

如要使用 AppOpenAdManager,請在單例模式 MyApplication 執行個體上呼叫公開包裝函式方法。Application 類別會與其餘程式碼介面互動,將載入及顯示廣告的工作委派給管理工具。

載入廣告

下一步是填寫 loadAd() 方法,並處理廣告載入回呼。

Java

AppOpenAd.load(
    context,
    "AD_UNIT_ID",
    new AdRequest.Builder().build(),
    new AppOpenAdLoadCallback() {
      @Override
      public void onAdLoaded(AppOpenAd ad) {
        // Called when an app open ad has loaded.
        Log.d(LOG_TAG, "App open ad loaded.");

        appOpenAd = ad;
        isLoadingAd = false;
        loadTime = (new Date()).getTime();
      }

      @Override
      public void onAdFailedToLoad(LoadAdError loadAdError) {
        // Called when an app open ad has failed to load.
        Log.d(LOG_TAG, "App open ad failed to load with error: " + loadAdError.getMessage());

        isLoadingAd = false;
      }
    });

Kotlin

AppOpenAd.load(
  context,
  "AD_UNIT_ID",
  AdRequest.Builder().build(),
  object : AppOpenAdLoadCallback() {
    override fun onAdLoaded(ad: AppOpenAd) {
      // Called when an app open ad has loaded.
      Log.d(LOG_TAG, "App open ad loaded.")

      appOpenAd = ad
      isLoadingAd = false
      loadTime = Date().time
    }

    override fun onAdFailedToLoad(loadAdError: LoadAdError) {
      // Called when an app open ad has failed to load.
      Log.d(LOG_TAG, "App open ad failed to load with error: " + loadAdError.message)

      isLoadingAd = false
    }
  },
)

AD_UNIT_ID 替換為您自己的廣告單元 ID。

顯示廣告

最常見的應用程式開啟頁面廣告導入做法,是在應用程式啟動時嘗試顯示應用程式開啟頁面廣告,如果廣告尚未準備就緒,則啟動應用程式內容,並預先載入下一次應用程式開啟頁面廣告的機會。如需導入範例,請參閱應用程式開啟頁面廣告指南

下列程式碼會顯示廣告,然後重新載入:

Java

public void showAdIfAvailable(
    @NonNull final Activity activity,
    @NonNull OnShowAdCompleteListener onShowAdCompleteListener) {
  // If the app open ad is already showing, do not show the ad again.
  if (isShowingAd) {
    Log.d(TAG, "The app open ad is already showing.");
    return;
  }

  // If the app open ad is not available yet, invoke the callback then load the ad.
  if (appOpenAd == null) {
    Log.d(TAG, "The app open ad is not ready yet.");
    onShowAdCompleteListener.onShowAdComplete();
    // Load an ad.
    return;
  }

  isShowingAd = true;
  appOpenAd.show(activity);
}

Kotlin

fun showAdIfAvailable(activity: Activity, onShowAdCompleteListener: OnShowAdCompleteListener) {
  // If the app open ad is already showing, do not show the ad again.
  if (isShowingAd) {
    Log.d(TAG, "The app open ad is already showing.")
    return
  }

  // If the app open ad is not available yet, invoke the callback then load the ad.
  if (appOpenAd == null) {
    Log.d(TAG, "The app open ad is not ready yet.")
    onShowAdCompleteListener.onShowAdComplete()
    // Load an ad.
    return
  }

  isShowingAd = true
  appOpenAd?.show(activity)
}

設定 FullScreenContentCallback

FullScreenContentCallback 會處理與顯示 AppOpenAd 相關的事件。顯示 AppOpenAd 前,請務必設定回呼:

Java

appOpenAd.setFullScreenContentCallback(
    new FullScreenContentCallback() {
      @Override
      public void onAdDismissedFullScreenContent() {
        // Called when full screen content is dismissed.
        Log.d(TAG, "Ad dismissed fullscreen content.");
        // Don't forget to set the ad reference to null so you
        // don't show the ad a second time.
        appOpenAd = null;
        isShowingAd = false;

        onShowAdCompleteListener.onShowAdComplete();
        // Load an ad.
      }

      @Override
      public void onAdFailedToShowFullScreenContent(@NonNull AdError adError) {
        // Called when full screen content failed to show.
        Log.d(TAG, adError.getMessage());
        appOpenAd = null;
        // Don't forget to set the ad reference to null so you
        // don't show the ad a second time.
        isShowingAd = false;

        onShowAdCompleteListener.onShowAdComplete();
        // Load an ad.
      }

      @Override
      public void onAdShowedFullScreenContent() {
        Log.d(TAG, "Ad showed fullscreen content.");
      }

      @Override
      public void onAdImpression() {
        // Called when an impression is recorded for an ad.
        Log.d(TAG, "The ad recorded an impression.");
      }

      @Override
      public void onAdClicked() {
        // Called when ad is clicked.
        Log.d(TAG, "The ad was clicked.");
      }
    });

Kotlin

appOpenAd?.fullScreenContentCallback =
  object : FullScreenContentCallback() {
    override fun onAdDismissedFullScreenContent() {
      // Called when full screen content is dismissed.
      Log.d(TAG, "Ad dismissed fullscreen content.")
      // Don't forget to set the ad reference to null so you
      // don't show the ad a second time.
      appOpenAd = null
      isShowingAd = false

      onShowAdCompleteListener.onShowAdComplete()
      // Load an ad.
    }

    override fun onAdFailedToShowFullScreenContent(adError: AdError) {
      // Called when full screen content failed to show.
      Log.d(TAG, adError.message)
      // Don't forget to set the ad reference to null so you
      // don't show the ad a second time.
      appOpenAd = null
      isShowingAd = false

      onShowAdCompleteListener.onShowAdComplete()
      // Load an ad.
    }

    override fun onAdShowedFullScreenContent() {
      Log.d(TAG, "Ad showed fullscreen content.")
    }

    override fun onAdImpression() {
      // Called when an impression is recorded for an ad.
      Log.d(TAG, "The ad recorded an impression.")
    }

    override fun onAdClicked() {
      // Called when ad is clicked.
      Log.d(TAG, "The ad was clicked.")
    }
  }

考慮廣告效期

為避免顯示已失效的廣告,請在 AppOpenAdManager 中加入方法,檢查廣告參照目前已載入多久。並使用該方法檢查廣告是否仍有效。

Java

/** Check if ad was loaded more than n hours ago. */
private boolean wasLoadTimeLessThanNHoursAgo(long numHours) {
  long dateDifference = (new Date()).getTime() - loadTime;
  long numMilliSecondsPerHour = 3600000;
  return (dateDifference < (numMilliSecondsPerHour * numHours));
}

/** Check if ad exists and can be shown. */
private boolean isAdAvailable() {
  // For time interval details, see: https://support.google.com/admob/answer/9341964
  return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4);
}

Kotlin

/** Check if ad was loaded more than n hours ago. */
private fun wasLoadTimeLessThanNHoursAgo(numHours: Long): Boolean {
  val dateDifference: Long = Date().time - loadTime
  val numMilliSecondsPerHour: Long = 3600000
  return dateDifference < numMilliSecondsPerHour * numHours
}

/** Check if ad exists and can be shown. */
private fun isAdAvailable(): Boolean {
  // For time interval details, see: https://support.google.com/admob/answer/9341964
  return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4)
}

追蹤目前的活動

如要顯示廣告,您需要 Activity 環境。如要追蹤目前使用的最新活動,請註冊並實作 Application.ActivityLifecycleCallbacks

Java

@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {}

@Override
public void onActivityStarted(@NonNull Activity activity) {
  // An ad activity is started when an ad is showing, which could be AdActivity class from Google
  // SDK or another activity class implemented by a third party mediation partner. Updating the
  // currentActivity only when an ad is not showing will ensure it is not an ad activity, but the
  // one that shows the ad.
  if (!appOpenAdManager.isShowingAd) {
    currentActivity = activity;
  }
}

@Override
public void onActivityResumed(@NonNull Activity activity) {}

@Override
public void onActivityPaused(@NonNull Activity activity) {}

@Override
public void onActivityStopped(@NonNull Activity activity) {}

@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {}

@Override
public void onActivityDestroyed(@NonNull Activity activity) {}

Kotlin

override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}

override fun onActivityStarted(activity: Activity) {
  // An ad activity is started when an ad is showing, which could be AdActivity class from Google
  // SDK or another activity class implemented by a third party mediation partner. Updating the
  // currentActivity only when an ad is not showing will ensure it is not an ad activity, but the
  // one that shows the ad.
  if (!appOpenAdManager.isShowingAd) {
    currentActivity = activity
  }
}

override fun onActivityResumed(activity: Activity) {}

override fun onActivityPaused(activity: Activity) {}

override fun onActivityStopped(activity: Activity) {}

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}

override fun onActivityDestroyed(activity: Activity) {}

registerActivityLifecycleCallbacks 可監聽所有 Activity 事件。監聽活動的啟動和終止時間,即可追蹤目前 Activity 的參照,然後用於顯示應用程式開啟廣告。

監聽應用程式前景事件

如要監聽應用程式前景事件,請按照下列步驟操作:

將程式庫新增至 Gradle 檔案

如要接收應用程式前景事件的通知,請註冊 DefaultLifecycleObserver。將依附元件新增至應用程式層級的建構檔案:

Kotlin

  dependencies {
    implementation("com.google.android.gms:play-services-ads:24.5.0")
    implementation("androidx.lifecycle:lifecycle-process:2.8.3")
  }

Groovy

  dependencies {
    implementation 'com.google.android.gms:play-services-ads:24.5.0'
    implementation 'androidx.lifecycle:lifecycle-process:2.8.3'
  }

導入生命週期觀察器介面

您可以實作 DefaultLifecycleObserver 介面,監聽前景事件。

導入 onStart() 顯示應用程式開啟頁面廣告。

Java

@Override
public void onStart(@NonNull LifecycleOwner owner) {
  DefaultLifecycleObserver.super.onStart(owner);
  // Show the ad (if available) when the app moves to foreground.
  appOpenAdManager.showAdIfAvailable(currentActivity);
}

Kotlin

override fun onStart(owner: LifecycleOwner) {
  super.onStart(owner)
  currentActivity?.let {
    // Show the ad (if available) when the app moves to foreground.
    appOpenAdManager.showAdIfAvailable(it)
  }
}

冷啟動和載入畫面

目前為止,本文都假設您只會在使用者將應用程式從記憶體恢復到前景時,顯示應用程式開啟頁面廣告。若應用程式啟動,但不是從記憶體暫停狀態下恢復到前景,就會發生「冷啟動」。

舉例來說,使用者第一次開啟應用程式時,就是冷啟動。 在這種情況下,您不會有先前載入的應用程式開啟頁面廣告,因此無法立即顯示。在您要求廣告與接收到廣告的延遲期間,使用者可能得以短暫使用您的應用程式,接著才會突然看到與內容無關的廣告。這種情況會造成使用者體驗不佳,建議避免。

要在冷啟動時放送應用程式開啟頁面廣告,建議使用載入畫面,載入遊戲或應用程式素材資源,並只在載入畫面中顯示廣告。如果應用程式已完成載入,並將使用者帶往應用程式的主要內容,請勿顯示廣告。

最佳做法

應用程式開啟頁面廣告可協助您在應用程式首次啟動及切換期間,透過應用程式的載入畫面營利,但為了確保使用者享有良好使用體驗,牢記最佳做法非常重要。建議您:

  • 等使用者用過應用程式幾次之後,再放送第一則應用程式開啟頁面廣告。
  • 在使用者原本會等待應用程式載入的時間段內,放送應用程式開啟頁面廣告。
  • 如果應用程式開啟頁面廣告下方有載入畫面,且載入畫面在廣告關閉前就完成載入,建議您在 onAdDismissedFullScreenContent() 方法中關閉載入畫面。

GitHub 上的範例

  • 應用程式開啟頁面廣告範例: Java | Kotlin

後續步驟

請參閱下列主題: