מודעות באנר

מודעות באנר הן מודעות מלבניות שתופסות חלק מהפריסה של האפליקציה. מודעות באנר מותאמות מסוג עוגן הן מודעות עם יחס גובה-רוחב קבוע שמוצגות במסך גם בזמן אינטראקציות של המשתמשים באפליקציה – מעוגנות בראש המסך או בתחתית המסך.

במדריך הזה מוסבר איך לטעון מודעת באנר מותאמת ומעוגנת באפליקציית Android.

דרישות מוקדמות

תמיד כדאי לבצע בדיקות באמצעות מודעות בדיקה

כשמפתחים ובודקים אפליקציות, חשוב להשתמש במודעות בדיקה ולא במודעות פעילות שמוצגות למשתמשים. אם לא תעשו את זה, אנחנו עשויים להשעות את החשבון שלכם.

הדרך הכי קלה לטעון מודעות לבדיקה היא להשתמש במזהה הייעודי של יחידת המודעות לבדיקה של מודעות באנר ל-Android:

ca-app-pub-3940256099942544/9214589741

הוא הוגדר במיוחד להחזרת מודעות בדיקה לכל בקשה, ואפשר להשתמש בו באפליקציות שלכם בזמן כתיבת קוד, בדיקה וניפוי באגים. חשוב להקפיד להחליף אותו במזהה יחידת המודעות שלכם לפני פרסום האפליקציה.

מידע נוסף על אופן הפעולה של מודעות בדיקה ב-Google Mobile Ads SDK (בטא) זמין במאמר בנושא הפעלת מודעות בדיקה.

הגדרת הצפייה במודעה

פריסת XML

מוסיפים תצוגה לקובץ הפריסה ב-XML כדי שתשמש כקונטיינר למודעת הבאנר המותאם שמוצמדת:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <FrameLayout
      android:id="@+id/banner_view_container"
      android:layout_width="0dp"
      android:layout_height="wrap_content"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintStart_toStartOf="parent">

  </FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

Jetpack פיתוח נייטיב

כוללים אלמנט AndroidView בממשק המשתמש של Compose ומגדירים משתנה mutableStateOf<BannerAd?> להצגת מודעת הבאנר:

// Initialize required variables.
val context = LocalContext.current
var bannerAdState by remember { mutableStateOf<BannerAd?>(null) }

// The AdView is placed at the bottom of the screen.
Column(modifier = modifier.fillMaxSize(), verticalArrangement = Arrangement.Bottom) {
  bannerAdState?.let { bannerAd ->
    Box(modifier = Modifier.fillMaxWidth()) {
      // Display the ad within an AndroidView.
      AndroidView(
        modifier = modifier.wrapContentSize(),
        factory = { bannerAd.getView(requireActivity()) },
      )
    }
  }
}

טעינת מודעה

  1. יוצרים אובייקט BannerAdRequest עם מזהה יחידת מודעות וגודל מודעה מותאם שמוצמד לחלק העליון או התחתון של המסך.
  2. קוראים לפונקציה BannerAd.load().
  3. מוסיפים את BannerAd.getView() להיררכיית התצוגה.

Kotlin

import com.google.android.libraries.ads.mobile.sdk.banner.AdSize
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAd
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAdEventCallback
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAdRefreshCallback
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAdRequest
import com.google.android.libraries.ads.mobile.sdk.common.AdLoadCallback
import com.google.android.libraries.ads.mobile.sdk.common.LoadAdError

class MainActivity : Activity() {

  private var bannerAd: BannerAd? = null
  private lateinit var binding: ActivityMainBinding
  private lateinit var adSize: AdSize
  private lateinit var bannerViewContainer: FrameLayout

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    // 320 is a placeholder value. Replace 320 with your banner container width.
    adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, 320)

    // Give the banner container a placeholder height to avoid a sudden layout
    // shifts when the ad loads.
    bannerViewContainer = binding.bannerViewContainer
    val bannerLayoutParams = bannerViewContainer.layoutParams
    bannerLayoutParams.height = adSize.getHeightInPixels(requireContext())
    bannerViewContainer.layoutParams = bannerLayoutParams

    // Step 1 - Create a BannerAdRequest object with ad unit ID and size.
    val adRequest = BannerAdRequest.Builder("ca-app-pub-3940256099942544/9214589741", adSize).build()

    // Step 2 - Load the ad.
    BannerAd.load(
      adRequest,
      object : AdLoadCallback<BannerAd> {
        override fun onAdLoaded(ad: BannerAd) {
          // Assign the loaded ad to the BannerAd object.
          bannerAd = ad
          // Step 3 - Call BannerAd.getView() to get the View and add it
          // to view hierarchy on the UI thread.
          activity?.runOnUiThread {
            binding.bannerViewContainer.addView(ad.getView(requireActivity()))
          }
        }

        override fun onAdFailedToLoad(loadAdError: LoadAdError) {
          bannerAd = null
        }
      },
    )
  }
}

Java

import com.google.android.libraries.ads.mobile.sdk.banner.AdSize;
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAd;
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAdEventCallback;
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAdRefreshCallback;
import com.google.android.libraries.ads.mobile.sdk.banner.BannerAdRequest;
import com.google.android.libraries.ads.mobile.sdk.common.AdLoadCallback;
import com.google.android.libraries.ads.mobile.sdk.common.LoadAdError;

public class MainActivity extends AppCompatActivity {

  private BannerAd bannerAd;
  private ActivityMainBinding binding;
  private AdSize adSize;
  private FrameLayout bannerViewContainer;

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivityMainBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

    // 320 is a placeholder value. Replace 320 with your banner container width.
    adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, 320);

    // Give the banner container a placeholder height to avoid a sudden layout
    // shifts when the ad loads.
    bannerViewContainer = binding.bannerViewContainer;
    LayoutParams bannerLayoutParams = bannerViewContainer.getLayoutParams();
    bannerLayoutParams.height = adSize.getHeightInPixels(this);
    bannerViewContainer.setLayoutParams(bannerLayoutParams);

    // Step 1 - Create a BannerAdRequest object with ad unit ID and size.
    BannerAdRequest adRequest = new BannerAdRequest.Builder("ca-app-pub-3940256099942544/9214589741",
        adSize).build();

    // Step 2 - Load the ad.
    BannerAd.load(
        adRequest,
        new AdLoadCallback<BannerAd>() {
          @Override
          public void onAdLoaded(@NonNull BannerAd ad) {
            // Assign the loaded ad to the BannerAd object.
            bannerAd = ad;
            // Step 3 - Call BannerAd.getView() to get the View and add it
            // to view hierarchy on the UI thread.
            runOnUiThread(
                () -> binding.bannerViewContainer.addView(ad.getView(MainActivity.this)));
          }

          @Override
          public void onAdFailedToLoad(@NonNull LoadAdError adError) {
            bannerAd = null;
          }
        });
  }
}

Jetpack פיתוח נייטיב

// Request an anchored adaptive banner with a width of 360.
val adSize = AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(requireContext(), 360)

// Load the ad when the screen is active.
val coroutineScope = rememberCoroutineScope()
val isPreviewMode = LocalInspectionMode.current
LaunchedEffect(context) {
  bannerAdState?.destroy()
  if (!isPreviewMode) {
    coroutineScope.launch {
      when (val result = BannerAd.load(BannerAdRequest.Builder(AD_UNIT_ID, adSize).build())) {
        is AdLoadResult.Success -> {
          bannerAdState = result.ad
        }
        is AdLoadResult.Failure -> {
          showToast("Banner failed to load.")
          Log.w(Constant.TAG, "Banner ad failed to load: $result.error")
        }
      }
    }
  }
}

רענון מודעה

אם הגדרתם את יחידת המודעות כך שתתבצע בה רענון, לא צריך לשלוח בקשה להצגת מודעה נוספת אם המודעה לא נטענת. ‫Google Mobile Ads SDK (בטא) מכבד כל קצב רענון שציינתם בממשק המשתמש של AdMob. אם לא הפעלתם את הרענון, תצטרכו לשלוח בקשה חדשה. לפרטים נוספים על רענון יחידות של מודעות, כמו הגדרת קצב רענון, אפשר לעיין במאמר בנושא שימוש ברענון אוטומטי במודעות באנר.

הפצת משאב למודעה

כשמסיימים להשתמש במודעת באנר, אפשר לשחרר את המשאבים של מודעת הבאנר.

כדי לשחרר את המשאב של המודעה, מסירים את המודעה מהיררכיית התצוגה ומבטלים את כל ההפניות אליה:

Kotlin

// Remove banner from view hierarchy.
val parentView = adView?.parent
if (parentView is ViewGroup) {
  parentView.removeView(adView)
}

// Destroy the banner ad resources.
adView?.destroy()

// Drop reference to the banner ad.
adView = null

Java

// Remove banner from view hierarchy.
if (adView.getParent() instanceof ViewGroup) {
  ((ViewGroup) adView.getParent()).removeView(adView);
}
// Destroy the banner ad resources.
adView.destroy();
// Drop reference to the banner ad.
adView = null;

Jetpack פיתוח נייטיב


// Destroy the ad when the screen is disposed.
DisposableEffect(Unit) { onDispose { bannerAdState?.destroy() } }

אירועים שקשורים למודעות

אפשר להאזין למספר אירועים במחזור החיים של המודעה, כולל חשיפה של המודעה וקליק, וגם פתיחה וסגירה של המודעה. מומלץ להגדיר את הקריאה החוזרת לפני הצגת הבאנר.

Kotlin

BannerAd.load(
  BannerAdRequest.Builder("ca-app-pub-3940256099942544/9214589741", adSize).build(),
  object : AdLoadCallback<BannerAd> {
    override fun onAdLoaded(ad: BannerAd) {
      ad.adEventCallback =
        object : BannerAdEventCallback {
          override fun onAdImpression() {
            // Banner ad recorded an impression.
          }

          override fun onAdClicked() {
            // Banner ad recorded a click.
          }

          override fun onAdShowedFullScreenContent() {
            // Banner ad showed.
          }

          override fun onAdDismissedFullScreenContent() {
            // Banner ad dismissed.
          }

          override fun onAdFailedToShowFullScreenContent(
            fullScreenContentError: FullScreenContentError
          ) {
            // Banner ad failed to show.
          }
        }
    }
    // ...
  }
)

Java

BannerAd.load(
    new BannerAdRequest.Builder("ca-app-pub-3940256099942544/9214589741", adSize).build(),
    new AdLoadCallback<BannerAd>() {
      @Override
      public void onAdLoaded(@NonNull BannerAd ad) {
        ad.setAdEventCallback(new BannerAdEventCallback() {
          @Override
          public void onAdImpression() {
            // Banner ad recorded an impression.
          }

          @Override
          public void onAdClicked() {
            // Banner ad recorded a click.
          }

          @Override
          public void onAdShowedFullScreenContent() {
            // Banner ad showed.
          }

          @Override
          public void onAdDismissedFullScreenContent() {
            // Banner ad dismissed.
          }

          @Override
          public void onAdFailedToShowFullScreenContent(
              @NonNull FullScreenContentError fullScreenContentError) {
            // Banner ad failed to show.
          }
        });

        // ...
      }
    });

התקשרות חוזרת לרענון מודעה

ה-BannerAdRefreshCallback מטפל באירועי רענון של מודעות אם משתמשים ברענון אוטומטי של מודעות באנר. חשוב להגדיר את הקריאה החוזרת לפני שמוסיפים את צפיית המודעה להיררכיית התצוגה. פרטים על רענון מודעות זמינים במאמר רענון מודעה.

Kotlin

BannerAd.load(
  BannerAdRequest.Builder("ca-app-pub-3940256099942544/9214589741", adSize).build(),
  object : AdLoadCallback<BannerAd> {
    override fun onAdLoaded(ad: BannerAd) {
      ad.bannerAdRefreshCallback =
        object : BannerAdRefreshCallback {
          // Set the ad refresh callbacks.
          override fun onAdRefreshed() {
            // Called when the ad refreshes.
          }

          override fun onAdFailedToRefresh(loadAdError: LoadAdError) {
            // Called when the ad fails to refresh.
          }
        }

      // ...
    }
  }
)

Java

BannerAd.load(
    new BannerAdRequest.Builder("ca-app-pub-3940256099942544/9214589741", adSize).build(),
    new AdLoadCallback<BannerAd>() {
      @Override
      public void onAdLoaded(@NonNull BannerAd ad) {
        ad.setBannerAdRefreshCallback(
            // Set the ad refresh callbacks.
            new BannerAdRefreshCallback() {
              @Override
              public void onAdRefreshed() {
                // Called when the ad refreshes.
              }

              @Override
              public void onAdFailedToRefresh(@NonNull LoadAdError adError) {
                // Called when the ad fails to refresh.
              }
            });
        // ...
      }
    });

שיפור המהירות באמצעות חומרה למודעות וידאו

כדי שמודעות וידאו יוצגו בהצלחה בצפיות במודעות באנר, צריך להפעיל האצת חומרה.

האצת חומרה מופעלת כברירת מחדל, אבל יכול להיות שחלק מהאפליקציות ישביתו אותה. אם זה המצב באפליקציה שלכם, מומלץ להפעיל שיפור מהירות באמצעות חומרה עבור מחלקות Activity שמשתמשות במודעות.

הפעלה של שיפור המהירות באמצעות חומרה

אם האפליקציה לא פועלת בצורה תקינה כשהאצת החומרה מופעלת באופן גלובלי, אפשר לשלוט בה גם בפעילויות ספציפיות. כדי להפעיל או להשבית את שיפור המהירות באמצעות חומרה, אפשר להשתמש במאפיין android:hardwareAccelerated של הרכיבים <application> ו-<activity> ב-AndroidManifest.xml. בדוגמה הבאה מופעלת האצת חומרה לכל האפליקציה, אבל היא מושבתת לפעילות אחת:

<application android:hardwareAccelerated="true">
    <!-- For activities that use ads, hardwareAcceleration should be true. -->
    <activity android:hardwareAccelerated="true" />
    <!-- For activities that don't use ads, hardwareAcceleration can be false. -->
    <activity android:hardwareAccelerated="false" />
</application>

מידע נוסף על אפשרויות לשליטה בשיפור המהירות באמצעות חומרה זמין במדריך בנושא שיפור המהירות באמצעות חומרה. שימו לב: אי אפשר להפעיל שיפור מהירות באמצעות חומרה לצפיות במודעות ספציפיות אם הפעילות מושבתת, ולכן צריך להפעיל שיפור מהירות באמצעות חומרה בפעילות עצמה.

מורידים ומריצים את האפליקציה לדוגמה שמדגימה את השימוש ב-Google Mobile Ads SDK (בטא).