המדריך הזה מיועד לבעלי אפליקציות שמשלבים מודעות בפתיחת אפליקציה באמצעות Google Mobile Ads SDK.
מודעות בפתיחת האפליקציה הן פורמט מיוחד של מודעות שמיועדות לבעלי תוכן דיגיטלי שרוצים לייצר הכנסות את מסך טעינת האפליקציות שלהם. אפשר לסגור את המודעות בפתיחת האפליקציה בכל שלב, והן מיועדות יוצג כשהמשתמשים מציבים את האפליקציה לחזית העסק.
מודעות בפתיחת אפליקציה מציגות באופן אוטומטי אזור מיתוג קטן כדי שהמשתמשים ידעו שהם נמצאים בו באפליקציה שלך. כך נראית מודעה בפתיחת אפליקציה:
דרישות מוקדמות
- מבצעים את ההוראות במדריך לתחילת העבודה.
ביצוע בדיקות באמצעות מודעות בדיקה תמיד
כשיוצרים ובודקים אפליקציות, חשוב להשתמש במודעות בדיקה במקום במודעות בדיקה של מודעות בשידור חי. אם לא תעשו זאת, ייתכן שהחשבון שלכם יושעה.
הדרך הקלה ביותר לטעון מודעות בדיקה היא להשתמש במזהה הייעודי של יחידת המודעות לבדיקה של מודעות פתיחה באפליקציות:
ca-app-pub-3940256099942544/9257395921
הוא הוגדר במיוחד להחזרת מודעות בדיקה עבור כל בקשה, לשימוש בחינם באפליקציות שלכם תוך כדי תכנות, בדיקות וניפוי באגים. צריך רק ליצור יש להחליף אותו במזהה יחידת המודעות שלך לפני פרסום האפליקציה.
מידע נוסף על אופן הפעולה של מודעות הבדיקה של Google Mobile Ads SDK מפעילים מודעות בדיקה.
הרחבת סיווג האפליקציות
צריך ליצור כיתה חדשה שמרחיבה את הכיתה 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();
new Thread(
() -> {
// Initialize the Google Mobile Ads SDK on a background thread.
MobileAds.initialize(this, initializationStatus -> {});
})
.start();
}
}
Kotlin
/** Application class that initializes, loads and show ads when activities change states. */
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
val backgroundScope = CoroutineScope(Dispatchers.IO)
backgroundScope.launch {
// Initialize the Google Mobile Ads SDK on a background thread.
MobileAds.initialize(this@MyApplication) {}
}
}
}
פעולה זו מפעילה את ה-SDK ומספקת את השלד שבו יירשמו במועד מאוחר יותר לאירועים בחזית של אפליקציה.
בשלב הבא צריך להוסיף את הקוד הבא ל-AndroidManifest.xml
:
<!-- TODO: Update to reference your actual package name. -->
<application
android:name="com.google.android.gms.example.appopendemo.MyApplication" ...>
...
</application>
הטמעה של רכיב השירות שלך
המודעה אמורה להופיע במהירות, לכן כדאי לטעון אותה לפני להציג אותו. כך תהיה לכם מודעה מוכנה להצגה ברגע שהמשתמש ייכנס לאפליקציה.
מטמיעים רכיב שירות 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/9257395921";
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 later.
}
/** 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/9257395921"
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 later.
}
/** 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();
new Thread(
() -> {
// Initialize the Google Mobile Ads SDK on a background thread.
MobileAds.initialize(this, initializationStatus -> {});
})
.start();
appOpenAdManager = new AppOpenAdManager(this);
}
}
Kotlin
class MyApplication : Application() {
private lateinit var appOpenAdManager: AppOpenAdManager
override fun onCreate() {
super.onCreate()
val backgroundScope = CoroutineScope(Dispatchers.IO)
backgroundScope.launch {
// Initialize the Google Mobile Ads SDK on a background thread.
MobileAds.initialize(this@MyApplication) {}
}
appOpenAdManager = AppOpenAdManager()
}
}
טעינת מודעה
השלב הבא הוא למלא את השיטה loadAd()
ולטפל בקריאות החוזרות (callbacks) של טעינת המודעות.
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;
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;
}
});
}
// ...
}
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
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;
}
})
}
// ...
}
הצגת המודעה וטיפול באירועי קריאה חוזרת במסך מלא
השיטה הכי נפוצה להטמיע מודעות בפתיחת אפליקציה היא לנסות להציג מודעה בפתיחת אפליקציה ליד הפעלת האפליקציה, התחלת תוכן האפליקציה אם המודעה עדיין לא מוכנה וטעינה מראש של מודעה אחרת להזדמנות הבאה בפתיחת אפליקציה. צפייה הנחיות למודעות בפתיחת אפליקציה לקבלת דוגמאות להטמעה.
הקוד הבא מדגים איך להציג מודעה ולאחר מכן לטעון אותה מחדש:
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.setFullScreenContentCallback(
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
מטפל באירועים, למשל: מתי המודעה מוצגת, אם היא לא מוצגת או אם היא לא מוצגת
נסגרה.
כדאי להביא בחשבון את תפוגת התוקף של המודעות
כדי להבטיח שלא תוצג מודעה שפג תוקפה, עליך להוסיף שיטה אל 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;
// ...
/** 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;
// ...
/** Utility method to 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 {
return appOpenAd != null && wasLoadTimeLessThanNHoursAgo(4)
}
}
מעקב אחר הפעילות הנוכחית
כדי להציג את המודעה, צריך הקשר Activity
. כדי לעקוב אחרי הפעילות העדכנית ביותר שבה אתם משתמשים, כדאי להירשם ל-Application.ActivityLifecycleCallbacks
ולהטמיע אותו.
Java
public class MyApplication extends Application implements ActivityLifecycleCallbacks {
private Activity currentActivity;
@Override
public void onCreate() {
super.onCreate();
this.registerActivityLifecycleCallbacks(this);
// ...
}
/** ActivityLifecycleCallback methods. */
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivityStarted(Activity activity) {
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
override fun onCreate() {
super.onCreate()
registerActivityLifecycleCallbacks(this)
// ...
}
/** ActivityLifecycleCallback methods. */
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {
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
. מוסיפים את התלות בקובץ ה-build ברמת האפליקציה:
Kotlin
dependencies { implementation("com.google.android.gms:play-services-ads:23.3.0") implementation("androidx.lifecycle:lifecycle-process:2.8.3") }
מגניב
dependencies { implementation 'com.google.android.gms:play-services-ads:23.3.0' implementation 'androidx.lifecycle:lifecycle-process:2.8.3' }
הטמעת ממשק הצופה במחזור החיים
אפשר להאזין לאירועים שפועלים בחזית על ידי הטמעת
ממשק DefaultLifecycleObserver
.
מטמיעים את האירוע onStart
כדי להציג את המודעה בפתיחת האפליקציה.
Java
public class MyApplication extends Application
implements ActivityLifecycleCallbacks, LifecycleObserver {
// ...
@Override
public void onCreate() {
super.onCreate();
this.registerActivityLifecycleCallbacks(this);
new Thread(
() -> {
// Initialize the Google Mobile Ads SDK on a background thread.
MobileAds.initialize(this, initializationStatus -> {});
})
.start();
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)
val backgroundScope = CoroutineScope(Dispatchers.IO)
backgroundScope.launch {
// Initialize the Google Mobile Ads SDK on a background thread.
MobileAds.initialize(this@MyApplication) {}
}
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.
}
})
}
}
הפעלות במצב התחלתי (cold start) ומסכי טעינה
בינתיים, מסמכי התיעוד מניחים שאתם מציגים מודעות בפתיחת אפליקציה רק כאשר משתמשים בחזית האפליקציה כשהיא מושעה בזיכרון. 'תחילת הקפאה' יתרחשו כאשר האפליקציה שלך הופעלה אבל הזיכרון לא הושעה בעבר.
דוגמה להתחלה קרה היא כשמשתמש פותח את האפליקציה בפעם הראשונה. בהפעלה במצב התחלתי, לא תהיה מודעה שהוטענה מראש בפתיחת האפליקציה ותהיה מוכנה להצגה באופן מיידי. הזמן שחלף בין שליחת הבקשה להצגת מודעה לבין קבלת המודעה עלול ליצור מצב שבו משתמשים יוכלו להשתמש באפליקציה לזמן קצר לפני מופתעים בעקבות מודעה שמוצגת מחוץ להקשר. יש להימנע מכך, מפני חוויית משתמש גרועה.
הדרך המועדפת להשתמש במודעות בפתיחת האפליקציה בהפעלה ראשונית היא להשתמש במסך טעינה כדי לטעון את נכסי המשחק או האפליקציה, ולהציג את המודעה רק ממסך הטעינה. אם הטעינה של האפליקציה הסתיימה והיא שלחה את המשתמש תוכן של האפליקציה, לא להציג את המודעה.
שיטות מומלצות
מודעות בפתיחת אפליקציה עוזרות לך לייצר הכנסות ממסך הטעינה של האפליקציה, בפעם הראשונה שבה היא מופיעה וגם במהלך החלפת אפליקציות, אבל חשוב ליישם שיטות מומלצות כדי שהמשתמשים יהנו להשתמש באפליקציה. מומלץ:
- מציגים את המודעה הראשונה בפתיחת אפליקציה אחרי שהמשתמשים השתמשו באפליקציה כמה פעמים.
- הצגת מודעות בפתיחת האפליקציה בשעות שבהן המשתמשים היו מחכים כדי שהאפליקציה תיטען.
- אם יש מסך טעינה מתחת למודעה בפתיחת האפליקציה, ומסך הטעינה
נטענת לפני שהמודעה נסגרת, כדאי לסגור את
טוען מסך בשיטה
onAdDismissedFullScreenContent()
.
דוגמאות ב-GitHub
השלבים הבאים
לעיין בנושאים הבאים: