המדריך הזה מיועד לבעלי תוכן דיגיטלי שמשלבים מודעות לפתיחת אפליקציה באמצעות Google Mobile Ads SDK .
מודעות בפתיחת אפליקציה הן פורמט מודעה מיוחד שמיועד לבעלי אפליקציות שרוצים לייצר הכנסות ממסכי הטעינה של האפליקציה שלהם. אפשר לסגור מודעות בפתיחת האפליקציה בכל שלב, והן מיועדות להצגה כשהמשתמשים מעבירים את האפליקציה לחזית.
מודעות בפתיחת האפליקציה מציגות באופן אוטומטי אזור מיתוג קטן כדי שהמשתמשים ידעו שהם באפליקציה שלכם. הנה דוגמה למודעה בפתיחת האפליקציה:
דרישות מוקדמות
- כדאי לעיין במדריך לתחילת העבודה.
תמיד כדאי לבצע בדיקות באמצעות מודעות בדיקה
כשמפתחים ובודקים אפליקציות, חשוב להשתמש במודעות בדיקה ולא במודעות פעילות שמוצגות למשתמשים. אם לא תעשו את זה, אנחנו עשויים להשעות את החשבון שלכם.
הדרך הכי קלה לטעון מודעות בדיקה היא להשתמש במזהה יחידת המודעות הייעודי לבדיקה של מודעות לפתיחת אפליקציה:
ca-app-pub-3940256099942544/9257395921
הוא הוגדר במיוחד להחזרת מודעות בדיקה לכל בקשה, ואתם יכולים להשתמש בו באפליקציות שלכם בזמן כתיבת קוד, בדיקה וניפוי באגים. חשוב להקפיד להחליף אותו במזהה יחידת המודעות שלכם לפני פרסום האפליקציה.
מידע נוסף על אופן הפעולה של מודעות בדיקה ב-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
, קוראים לשיטות של עטיפת ה-API הציבורי במופע של singleton MyApplication
. הממשקים של המחלקה Application
פועלים עם שאר הקוד, ומעבירים את העבודה של טעינת המודעה והצגתה למנהל.
טעינת מודעה
השלב הבא הוא למלא את השיטה loadAd()
ולטפל בקריאות החוזרות (callback) של טעינת המודעה.
Java
Kotlin
מחליפים את AD_UNIT_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
. מוסיפים את יחסי התלות שלו לקובץ ה-build ברמת האפליקציה:
Kotlin
dependencies { implementation("com.google.android.gms:play-services-ads:24.5.0") implementation("androidx.lifecycle:lifecycle-process:2.8.3") }
גרוב
dependencies { implementation 'com.google.android.gms:play-services-ads:24.5.0' implementation 'androidx.lifecycle:lifecycle-process:2.8.3' }
הטמעה של ממשק lifecycle observer
כדי להאזין לאירועים של העברת האפליקציה לחזית, צריך להטמיע את הממשק 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)
}
}
הפעלות במצב התחלתי (cold start) ומסכי טעינה
עד עכשיו, ההנחה במסמכים הייתה שאתם מציגים מודעות בפתיחת האפליקציה רק כשהמשתמשים מעבירים את האפליקציה לחזית כשהיא מושהית בזיכרון. 'הפעלות קרות' מתרחשות כשהאפליקציה מופעלת אבל לא הושעתה קודם בזיכרון.
דוגמה להפעלה קרה היא כשמשתמש פותח את האפליקציה בפעם הראשונה. בהפעלה במצב התחלתי, לא תהיה לכם מודעה בפתיחת האפליקציה שכבר נטענה ומוכנה להצגה מיידית. העיכוב בין הרגע שבו מבקשים להציג מודעה לבין הרגע שבו מקבלים את המודעה יכול ליצור מצב שבו המשתמשים יכולים להשתמש באפליקציה לזמן קצר לפני שהם מופתעים ממודעה שלא קשורה להקשר. מומלץ להימנע מכך כי זה פוגע בחוויית המשתמש.
הדרך המומלצת להשתמש במודעות בפתיחת אפליקציה בהפעלות קרות היא להשתמש במסך טעינה כדי לטעון את הנכסים של המשחק או האפליקציה, ולהציג את המודעה רק ממסך הטעינה. אם האפליקציה סיימה להיטען והמשתמש הועבר לתוכן הראשי של האפליקציה, אל תציגו את המודעה.
שיטות מומלצות
מודעות בפתיחת אפליקציה עוזרות לכם לייצר הכנסות ממסך הטעינה של האפליקציה, כשהאפליקציה מופעלת לראשונה ובמהלך מעבר בין אפליקציות. עם זאת, חשוב להקפיד על השיטות המומלצות כדי שהמשתמשים ייהנו מהשימוש באפליקציה. מומלץ:
- כדאי להציג את המודעה הראשונה בפתיחת האפליקציה אחרי שהמשתמשים השתמשו באפליקציה כמה פעמים.
- הצגת מודעות בפתיחת האפליקציה בזמנים שבהם המשתמשים ממתינים שהאפליקציה תיטען.
- אם יש לכם מסך טעינה מתחת למודעה בפתיחת האפליקציה, והטעינה של מסך הטעינה מסתיימת לפני שהמודעה נסגרת, כדאי לסגור את מסך הטעינה בשיטה
onAdDismissedFullScreenContent()
.
דוגמאות ב-GitHub
השלבים הבאים
כדאי לעיין בנושאים הבאים: