本指南適用於使用 Google Mobile Ads Android SDK 整合應用程式開啟頁面廣告的發布商。
應用程式開啟頁面廣告是一種特殊廣告格式,適合想透過應用程式載入畫面營利的發布商,應用程式開啟頁面廣告隨時都可關閉,且會在使用者將應用程式移至前景時顯示。
應用程式開啟頁面廣告會自動顯示一個小型品牌宣傳區域,讓使用者知道在您的應用程式中。以下就是應用程式開啟頁面廣告的範例:
大致步驟如下:
- 擴充
Application
類別來初始化 Google Mobile Ads SDK。 - 建立一個公用程式類別,以便在顯示廣告之前載入廣告。
- 載入廣告。
- 聆聽「
ActivityLifecycleCallbacks.
」 - 顯示廣告並處理回呼。
- 導入並註冊
LifecycleObserver
介面,即可在前景事件中顯示廣告。
必要條件
- Google Mobile Ads SDK 19.4.0 或更新版本。
- 按照入門指南中的設定操作說明進行設定。
一律使用測試廣告進行測試
建構及測試應用程式時,請務必使用測試廣告,而非即時正式版的廣告。否則我們可能會將您的帳戶停權。
如要載入測試廣告,最簡單的方式就是使用應用程式開啟頁面廣告的專用測試廣告單元 ID:
ca-app-pub-3940256099942544/3419835294
它經過特別設定,可以針對每次要求傳回測試廣告,而您可以在編寫、測試和偵錯應用程式時,在自己的應用程式中使用它。發布應用程式前,請務必將其中的 ID 換成自己的廣告單元 ID。
如要進一步瞭解 Mobile Ads SDK 的測試廣告運作方式,請參閱「測試廣告」。
擴充 Application 類別
建立一個擴充 Application
類別的新類別,並新增下列程式碼來初始化 Google Mobile Ads SDK。
Java
/** Application class that initializes, loads and show ads when activities change states. */ public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); MobileAds.initialize( this, new OnInitializationCompleteListener() { @Override public void onInitializationComplete(InitializationStatus initializationStatus) {} }); } }
Kotlin
/** Application class that initializes, loads and show ads when activities change states. */ class MyApplication : Application() { override fun onCreate() { super.onCreate() MobileAds.initialize(this) {} } }
這會初始化 SDK,並提供一個架構,以便您稍後註冊應用程式前景事件。
接著,將下列程式碼新增到您的 AndroidManifest.xml
中:
<application
android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>
請務必提及您的實際套件名稱。
實作公用程式類別
廣告應迅速顯示,因此建議您在顯示廣告前載入廣告。這樣使用者進入應用程式時,您就能立即製作廣告。請導入公用程式類別,在需要顯示廣告前預先發出廣告請求。
在 MyApplication
類別中建立名為 AppOpenAdManager
的新類別,並依照下列方式填寫:
Java
public class MyApplication extends Application { ... /** Inner class that loads and shows app open ads. */ private class AppOpenAdManager { private static final String LOG_TAG = "AppOpenAdManager"; private static final String AD_UNIT_ID = "ca-app-pub-3940256099942544/3419835294"; private AppOpenAd appOpenAd = null; private boolean isLoadingAd = false; private boolean isShowingAd = false; /** Constructor. */ public AppOpenAdManager() {} /** Request an ad. */ private void loadAd(Context context) { // We will implement this below. } /** Check if ad exists and can be shown. */ private boolean isAdAvailable() { return appOpenAd != null; } } }
Kotlin
private const val String LOG_TAG = "AppOpenAdManager" private const val String AD_UNIT_ID = "ca-app-pub-3940256099942544/3419835294" public class MyApplication extends Application { ... /** Inner class that loads and shows app open ads. */ private inner class AppOpenAdManager { private var appOpenAd: AppOpenAd? = null private var isLoadingAd = false var isShowingAd = false /** Request an ad. */ fun loadAd(context: Context) { // We will implement this below. } /** Check if ad exists and can be shown. */ private fun isAdAvailable(): Boolean { return appOpenAd != null } } }
現在您擁有公用程式類別,可以在 MyApplication
類別中對該類別執行個體化:
Java
public class MyApplication extends Application { private AppOpenAdManager appOpenAdManager; @Override public void onCreate() { super.onCreate(); MobileAds.initialize( this, new OnInitializationCompleteListener() { @Override public void onInitializationComplete(InitializationStatus initializationStatus) {} }); appOpenAdManager = new AppOpenAdManager(this); } }
Kotlin
class MyApplication : Application() { private lateinit var appOpenAdManager: AppOpenAdManager override fun onCreate() { super.onCreate() MobileAds.initialize(this) {} appOpenAdManager = AppOpenAdManager() } }
載入廣告
下一步是填寫 loadAd()
方法。
Java
private class AppOpenAdManager { ... /** Request an ad. */ public void loadAd(Context context) { // Do not load ad if there is an unused ad or one is already loading. if (isLoadingAd || isAdAvailable()) { return; } isLoadingAd = true; AdRequest request = new AdRequest.Builder().build(); AppOpenAd.load( context, AD_UNIT_ID, request, AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, new AppOpenAdLoadCallback() { @Override public void onAdLoaded(AppOpenAd ad) { // Called when an app open ad has loaded. Log.d(LOG_TAG, "Ad was loaded."); appOpenAd = ad; isLoadingAd = false; } @Override public void onAdFailedToLoad(LoadAdError loadAdError) { // Called when an app open ad has failed to load. Log.d(LOG_TAG, loadAdError.getMessage()); isLoadingAd = false; } }); } ... }
Kotlin
private inner class AppOpenAdManager { ... /** Request an ad. */ fun loadAd(context: Context) { // Do not load ad if there is an unused ad or one is already loading. if (isLoadingAd || isAdAvailable()) { return } isLoadingAd = true val request = AdRequest.Builder().build() AppOpenAd.load( context, AD_UNIT_ID, request, AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, object : AppOpenAdLoadCallback() { override fun onAdLoaded(ad: AppOpenAd) { // Called when an app open ad has loaded. Log.d(LOG_TAG, "Ad was loaded.") appOpenAd = ad isLoadingAd = false } override fun onAdFailedToLoad(loadAdError: LoadAdError) { // Called when an app open ad has failed to load. Log.d(LOG_TAG, loadAdError.message) isLoadingAd = false; } }) } ... }
AppOpenAdLoadCallback
具有會在 AppOpenAd
載入完成時呼叫的方法。
追蹤目前的活動
您必須要有 Activity
結構定義,才能顯示廣告。如要追蹤使用者目前使用的活動,請在 Application
類別中實作 Application.ActivityLifecycleCallbacks
。
Java
public class MyApplication extends Application implements ActivityLifecycleCallbacks { private Activity currentActivity; ... /** ActivityLifecycleCallback methods. */ @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {} @Override public void onActivityStarted(Activity activity) { // Updating the currentActivity only when an ad is not showing. if (!appOpenAdManager.isShowingAd) { currentActivity = activity; } } @Override public void onActivityResumed(Activity activity) {} @Override public void onActivityStopped(Activity activity) {} @Override public void onActivityPaused(Activity activity) {} @Override public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {} @Override public void onActivityDestroyed(Activity activity) {} }
Kotlin
class MyApplication : Application(), Application.ActivityLifecycleCallbacks { private var currentActivity: Activity? = null ... /** ActivityLifecycleCallback methods. */ override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {} override fun onActivityStarted(activity: Activity) { // Updating the currentActivity only when an ad is not showing. 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
方法註冊這個介面。
Java
public class MyApplication extends Application { ... @Override public void onCreate() { super.onCreate(); this.registerActivityLifecycleCallbacks(this); MobileAds.initialize( this, new OnInitializationCompleteListener() { @Override public void onInitializationComplete(InitializationStatus initializationStatus) {} }); appOpenAdManager = new AppOpenAdManager(); } }
Kotlin
class MyApplication : Application() { ... override fun onCreate() { super.onCreate() registerActivityLifecycleCallbacks(this) MobileAds.initialize(this) {} appOpenAdManager = AppOpenAdManager() } }
registerActivityLifecycleCallbacks
可讓您監聽所有 Activity
事件。監聽活動開始和刪除時,您可以追蹤目前 Activity
的參照,以供日後使用。
顯示廣告並處理全螢幕回呼事件
以下程式碼示範如何在何時顯示及重新載入廣告。
Java
public class MyApplication extends Application { ... /** Interface definition for a callback to be invoked when an app open ad is complete. */ public interface OnShowAdCompleteListener { void onShowAdComplete(); } private class AppOpenAdManager { ... /** Shows the ad if one isn't already showing. */ 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(LOG_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 (!isAdAvailable()) { Log.d(LOG_TAG, "The app open ad is not ready yet."); onShowAdCompleteListener.onShowAdComplete(); loadAd(activity); return; } appOpenAd.fullScreenContentCallback( new FullScreenContentCallback { @Override public void onAdDismissedFullScreenContent() { // Called when fullscreen content is dismissed. // Set the reference to null so isAdAvailable() returns false. Log.d(LOG_TAG, "Ad dismissed fullscreen content."); appOpenAd = null; isShowingAd = false; onShowAdCompleteListener.onShowAdComplete(); loadAd(activity); } @Override public void onAdFailedToShowFullScreenContent(AdError adError) { // Called when fullscreen content failed to show. // Set the reference to null so isAdAvailable() returns false. Log.d(LOG_TAG, adError.getMessage()); appOpenAd = null; isShowingAd = false; onShowAdCompleteListener.onShowAdComplete(); loadAd(activity); } @Override public void onAdShowedFullScreenContent() { // Called when fullscreen content is shown. Log.d(LOG_TAG, "Ad showed fullscreen content."); } }); isShowingAd = true; appOpenAd.show(activity); } ... } }
Kotlin
class MyApplication : Application() { ... /** Interface definition for a callback to be invoked when an app open ad is complete. */ interface OnShowAdCompleteListener { fun onShowAdComplete() } private inner class AppOpenAdManager { ... /** Shows the ad if one isn't already showing. */ fun showAdIfAvailable( activity: Activity, onShowAdCompleteListener: OnShowAdCompleteListener) { // If the app open ad is already showing, do not show the ad again. if (isShowingAd) { Log.d(LOG_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 (!isAdAvailable()) { Log.d(LOG_TAG, "The app open ad is not ready yet.") onShowAdCompleteListener.onShowAdComplete() loadAd(activity) return } appOpenAd?.setFullScreenContentCallback( object : FullScreenContentCallback() { override fun onAdDismissedFullScreenContent() { // Called when full screen content is dismissed. // Set the reference to null so isAdAvailable() returns false. Log.d(LOG_TAG, "Ad dismissed fullscreen content.") appOpenAd = null isShowingAd = false onShowAdCompleteListener.onShowAdComplete() loadAd(activity) } override fun onAdFailedToShowFullScreenContent(adError: AdError) { // Called when fullscreen content failed to show. // Set the reference to null so isAdAvailable() returns false. Log.d(LOG_TAG, adError.message) appOpenAd = null isShowingAd = false onShowAdCompleteListener.onShowAdComplete() loadAd(activity) } override fun onAdShowedFullScreenContent() { // Called when fullscreen content is shown. Log.d(LOG_TAG, "Ad showed fullscreen content.") } }) isShowingAd = true appOpenAd?.show(activity) } ... } }
FullScreenContentCallback
會處理事件 (例如廣告顯示、呈現失敗或關閉時)。如果使用者在點選應用程式開啟頁面廣告後離開應用程式,請確認其不會隨著其他應用程式開啟頁面廣告出現。
監聽應用程式前景事件
將程式庫新增至 Gradle 檔案
您必須註冊 LifecycleObserver
,才能收到應用程式前景事件的通知。首先,請編輯應用程式層級的 build.gradle
檔案,以納入 LifecycleObserver
程式庫:
apply plugin: 'com.android.application'
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.google.android.gms:play-services-ads:21.1.0'
def lifecycle_version = "2.3.1"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
}
實作 LifecycleObserver 介面
您可以實作 LifecycleObserver
介面,來監聽 Application
類別中的前景事件。
Java
public class MyApplication extends Application implements ActivityLifecycleCallbacks, LifecycleObserver { { ... @Override public void onCreate() { super.onCreate(); this.registerActivityLifecycleCallbacks(this); MobileAds.initialize( this, new OnInitializationCompleteListener() { @Override public void onInitializationComplete(InitializationStatus initializationStatus) {} }); ProcessLifecycleOwner.get().getLifecycle().addObserver(this); appOpenAdManager = new AppOpenAdManager(); } /** LifecycleObserver method that shows the app open ad when the app moves to foreground. */ @OnLifecycleEvent(Event.ON_START) protected void onMoveToForeground() { // Show the ad (if available) when the app moves to foreground. appOpenAdManager.showAdIfAvailable(currentActivity); } /** Show the ad if one isn't already showing. */ private void showAdIfAvailable(@NonNull final Activity activity) { showAdIfAvailable( activity, new OnShowAdCompleteListener() { @Override public void onShowAdComplete() { // Empty because the user will go back to the activity that shows the ad. } }); } }
Kotlin
class MyApplication : Application(), Application.ActivityLifecycleCallbacks, LifecycleObserver { ... override fun onCreate() { super.onCreate() registerActivityLifecycleCallbacks(this) MobileAds.initialize(this) {} ProcessLifecycleOwner.get().lifecycle.addObserver(this) appOpenAdManager = AppOpenAdManager() } /** LifecycleObserver method that shows the app open ad when the app moves to foreground. */ @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onMoveToForeground() { // Show the ad (if available) when the app moves to foreground. currentActivity?.let { appOpenAdManager.showAdIfAvailable(it) } } /** Show the ad if one isn't already showing. */ fun showAdIfAvailable(activity: Activity) { showAdIfAvailable( activity, object : OnShowAdCompleteListener { override fun onShowAdComplete() { // Empty because the user will go back to the activity that shows the ad. } }) } }
註冊 LifecycleObserver
後,您的應用程式就會發出應用程式啟動和前景事件快訊,並在適當的時機顯示廣告。
考慮廣告效期
為避免顯示已失效的廣告,請在 AppOpenAdManager
中新增方法,藉此檢查廣告參照載入後已經過多久的時間。接著,使用該方法檢查廣告是否仍有效。
Java
private class AppOpenAdManager { ... /** Keep track of the time an app open ad is loaded to ensure you don't show an expired ad. */ private long loadTime = 0; /** Request an ad. */ public void loadAd(Context context) { // Do not load ad if there is an unused ad or one is already loading. if (isLoadingAd || isAdAvailable()) { return; } isLoadingAd = true; AdRequest request = new AdRequest.Builder().build(); AppOpenAd.load( context, AD_UNIT_ID, request, AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, new AppOpenAdLoadCallback() { @Override public void onAdLoaded(AppOpenAd ad) { // Called when an app open ad has loaded. Log.d(LOG_TAG, "Ad was 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, loadAdError.getMessage()); isLoadingAd = false; } }); } ... /** Utility method to check if ad was loaded more than n hours ago. */ private boolean wasLoadTimeLessThanNHoursAgo(long numHours) { long dateDifference = (new Date()).getTime() - this.loadTime; long numMilliSecondsPerHour = 3600000; return (dateDifference < (numMilliSecondsPerHour * numHours)); } /** Check if ad exists and can be shown. */ public boolean isAdAvailable() { return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4); } }
Kotlin
private inner class AppOpenAdManager { ... /** 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 /** Request an ad. */ fun loadAd(context: Context) { // Do not load ad if there is an unused ad or one is already loading. if (isLoadingAd || isAdAvailable()) { return } isLoadingAd = true val request = AdRequest.Builder().build() AppOpenAd.load( context, AD_UNIT_ID, request, AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT, object : AppOpenAdLoadCallback() { override fun onAdLoaded(ad: AppOpenAd) { // Called when an app open ad has loaded. Log.d(LOG_TAG, "Ad was 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, loadAdError.message) isLoadingAd = false; } }) } ... private fun wasLoadTimeLessThanNHoursAgo(numHours: Long): Boolean { val dateDifference: Long = Date().time - loadTime val numMilliSecondsPerHour: Long = 3600000 return dateDifference < numMilliSecondsPerHour * numHours } private fun isAdAvailable(): Boolean { return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4) } }
冷啟動和載入畫面
到目前為止,這份說明文件假設您僅在使用者暫停使用記憶體時,顯示應用程式開啟頁面廣告。"Cold start&tt:應用程式啟動後,先前並未在記憶體中遭到停權。
冷啟動的例子包括使用者首次開啟應用程式時。採用冷啟動後,您就不會載入先前載入的應用程式開啟頁面廣告。從您請求廣告到接收廣告回應之間的延遲時間,可能會產生許多情況,因為使用者可能會短暫地使用您的應用程式,而過程意外。應避免避免,因為這是不良的使用者體驗。
如要在冷啟動期間使用應用程式開啟頁面廣告,建議的方法是使用載入畫面來載入遊戲或應用程式資產,並且只從載入畫面顯示廣告。如果您的應用程式已完成載入,並將使用者導向應用程式的主要內容,請勿顯示廣告。
最佳做法
應用程式開啟頁面廣告可協助您透過應用程式的載入畫面營利,也就是應用程式首次啟動及啟動應用程式時,但請務必保持最佳做法,讓使用者隨時使用您的應用程式。建議:
- 在使用者第一次使用應用程式後,放送您的第一則應用程式開啟頁面廣告。
- 在使用者等待應用程式載入期間,顯示應用程式開啟頁面廣告。
- 如果應用程式開啟頁面廣告上有載入畫面,且載入畫面在廣告關閉前完成載入,您可能需要關閉
onAdDismissedFullScreenContent()
方法中的載入畫面。