إعلان مدمج مع المحتوى (متقدم)

اختيار النظام الأساسي: Android iOS

عرض NativeAd

عند تحميل إعلان مُدمَج مع المحتوى، تستدعي حزمة "SDK لإعلانات Google على الأجهزة الجوّالة" أداة معالجة الأحداث الخاصة بشكل الإعلان ذي الصلة. ويكون تطبيقك مسؤولاً بعد ذلك عن عرض الإعلان، مع أنّه ليس بالضرورة أن يتم ذلك على الفور. لتسهيل عرض أشكال الإعلانات المحدّدة من النظام، توفّر حزمة SDK بعض المراجع المفيدة، كما هو موضّح أدناه.

تحديد فئة NativeAdView

حدِّد فئة NativeAdView. هذا الصف هو صف ViewGroup وهو الحاوية ذات المستوى الأعلى لصف NativeAdView. يحتوي كل عرض لإعلان مدمج مع المحتوى على مواد عرض خاصة بهذا النوع من الإعلانات، مثل عنصر العرض MediaView أو عنصر العرض Title، ويجب أن يكونا عنصرَين ثانويَين للكائن NativeAdView.

تنسيق XML

أضِف ملف XML NativeAdView إلى مشروعك:

<com.google.android.gms.ads.nativead.NativeAdView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <LinearLayout
    android:orientation="vertical">
        <LinearLayout
        android:orientation="horizontal">
          <ImageView
          android:id="@+id/ad_app_icon" />
          <TextView
            android:id="@+id/ad_headline" />
        </LinearLayout>
        <!--Add remaining assets such as the image and media view.-->
    </LinearLayout>
</com.google.android.gms.ads.nativead.NativeAdView>

Jetpack Compose

أدرِج وحدة JetpackComposeDemo/compose-util التي تتضمّن أدوات مساعدة لإنشاء NativeAdView ومواد العرض الخاصة به.

باستخدام الوحدة compose-util، أنشئ NativeAdView:

  import com.google.android.gms.compose_util.NativeAdAttribution
  import com.google.android.gms.compose_util.NativeAdView

  @Composable
  /** Display a native ad with a user defined template. */
  fun DisplayNativeAdView(nativeAd: NativeAd) {
      NativeAdView {
          // Display the ad attribution.
          NativeAdAttribution(text = context.getString("Ad"))
          // Add remaining assets such as the image and media view.
        }
    }

التعامل مع الإعلان المدمج مع المحتوى الذي تم تحميله

عند تحميل إعلان مدمج مع المحتوى، تعامَل مع حدث رد الاتصال، ووسِّع عرض الإعلان المدمج مع المحتوى، وأضِفه إلى بنية العرض:

Java

AdLoader.Builder builder = new AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
    .forNativeAd(new NativeAd.OnNativeAdLoadedListener() {
        @Override
        public void onNativeAdLoaded(NativeAd nativeAd) {
            // Assumes you have a placeholder FrameLayout in your View layout
            // (with ID fl_adplaceholder) where the ad is to be placed.
            FrameLayout frameLayout =
                findViewById(R.id.fl_adplaceholder);
            // Assumes that your ad layout is in a file call native_ad_layout.xml
            // in the res/layout folder
            NativeAdView adView = (NativeAdView) getLayoutInflater()
                .inflate(R.layout.native_ad_layout, null);
            // This method sets the assets into the ad view.
            populateNativeAdView(nativeAd, adView);
            frameLayout.removeAllViews();
            frameLayout.addView(adView);
        }
});

Kotlin

val builder = AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
    .forNativeAd { nativeAd ->
        // Assumes you have a placeholder FrameLayout in your View layout
        // (with ID fl_adplaceholder) where the ad is to be placed.
        val frameLayout: FrameLayout = findViewById(R.id.fl_adplaceholder)
        // Assumes that your ad layout is in a file call native_ad_layout.xml
        // in the res/layout folder
        val adView = layoutInflater
                .inflate(R.layout.native_ad_layout, null) as NativeAdView
        // This method sets the assets into the ad view.
        populateNativeAdView(nativeAd, adView)
        frameLayout.removeAllViews()
        frameLayout.addView(adView)
    }

Jetpack Compose

@Composable
/** Load and display a native ad. */
fun NativeScreen() {
  var nativeAd by remember { mutableStateOf<NativeAd?>(null) }
  val context = LocalContext.current
  var isDisposed by remember { mutableStateOf(false) }

  DisposableEffect(Unit) {
    // Load the native ad when we launch this screen
    loadNativeAd(
      context = context,
      onAdLoaded = { ad ->
        // Handle the native ad being loaded.
        if (!isDisposed) {
          nativeAd = ad
        } else {
          // Destroy the native ad if loaded after the screen is disposed.
          ad.destroy()
        }
      },
    )
    // Destroy the native ad to prevent memory leaks when we dispose of this screen.
    onDispose {
      isDisposed = true
      nativeAd?.destroy()
      nativeAd = null
    }
  }

  // Display the native ad view with a user defined template.
  nativeAd?.let { adValue -> DisplayNativeAdView(adValue) }
}

fun loadNativeAd(context: Context, onAdLoaded: (NativeAd) -> Unit) {
  val adLoader =
    AdLoader.Builder(context, NATIVE_AD_UNIT_ID)
      .forNativeAd { nativeAd -> onAdLoaded(nativeAd) }
      .withAdListener(
        object : AdListener() {
          override fun onAdFailedToLoad(error: LoadAdError) {
            Log.e(TAG, "Native ad failed to load: ${error.message}")
          }

          override fun onAdLoaded() {
            Log.d(TAG, "Native ad was loaded.")
          }

          override fun onAdImpression() {
            Log.d(TAG, "Native ad recorded an impression.")
          }

          override fun onAdClicked() {
            Log.d(TAG, "Native ad was clicked.")
          }
        }
      )
      .build()
  adLoader.loadAd(AdRequest.Builder().build())
}

يُرجى العِلم أنّه يجب عرض جميع مواد العرض لإعلان مدمج مع المحتوى معيّن داخل التنسيق NativeAdView. تحاول حزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة تسجيل تحذير عند عرض مواد عرض الإعلانات المدمجة مع المحتوى خارج تنسيق عرض الإعلان المدمج مع المحتوى.

توفّر فئات عرض الإعلانات أيضًا طرقًا تُستخدَم لتسجيل طريقة العرض المستخدَمة لكل مادة عرض فردية، وطريقة لتسجيل العنصر NativeAd نفسه. يتيح تسجيل طرق العرض بهذه الطريقة لحزمة تطوير البرامج (SDK) معالجة مهام تلقائيًا، مثل:

  • تسجيل النقرات
  • تسجيل مرّات الظهور عندما تكون وحدة البكسل الأولى مرئية على الشاشة
  • عرض تراكب AdChoices

تراكب "خيارات الإعلان"

تضيف حزمة تطوير البرامج (SDK) شارة "خيارات الإعلان" إلى كلّ مشاهدة للإعلان. اترك مساحة في الزاوية المفضّلة من طريقة عرض الإعلان الأصلي لشعار "خيارات الإعلان" الذي يتم إدراجه تلقائيًا. ومن الضروري أيضًا أن يتمكّن المستخدم من رؤية هذه الشارة بسهولة، لذا يجب اختيار ألوان الخلفية والصور بشكل مناسب. لمزيد من المعلومات عن مظهر التراكب ووظيفته، اطّلِع على أوصاف حقول الإعلانات المدمجة مع المحتوى.

التصنيف كإعلان

يجب عرض تصنيف الإعلان للإشارة إلى أنّ المشاهدة هي إعلان. مزيد من المعلومات في إرشادات السياسة

مثال على الرمز

في ما يلي خطوات عرض إعلان مدمج مع المحتوى:

  1. أنشئ مثيلاً لفئة NativeAdView.
  2. لكل مادة عرض إعلان سيتم عرضها:

    1. املأ طريقة عرض مواد العرض بمادة العرض في عنصر الإعلان.
    2. سجِّل طريقة عرض مادة العرض باستخدام الفئة NativeAdView.
  3. سجِّل MediaView إذا كان تصميم الإعلان المُدمج مع المحتوى يتضمّن مادة عرض كبيرة الحجم.

  4. تسجيل عنصر الإعلان باستخدام الفئة NativeAdView

في ما يلي مثال على دالة تعرض NativeAd:

Java

private void displayNativeAd(ViewGroup parent, NativeAd ad) {

  // Inflate a layout and add it to the parent ViewGroup.
  LayoutInflater inflater = (LayoutInflater) parent.getContext()
          .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  NativeAdView adView = (NativeAdView) inflater
          .inflate(R.layout.ad_layout_file, parent);

  // Locate the view that will hold the headline, set its text, and call the
  // NativeAdView's setHeadlineView method to register it.
  TextView headlineView = adView.findViewById<TextView>(R.id.ad_headline);
  headlineView.setText(ad.getHeadline());
  adView.setHeadlineView(headlineView);

  // Repeat the process for the other assets in the NativeAd
  // using additional view objects (Buttons, ImageViews, etc).

  // If the app is using a MediaView, it should be
  // instantiated and passed to setMediaView. This view is a little different
  // in that the asset is populated automatically, so there's one less step.
  MediaView mediaView = (MediaView) adView.findViewById(R.id.ad_media);
  adView.setMediaView(mediaView);

  // Call the NativeAdView's setNativeAd method to register the
  // NativeAdObject.
  adView.setNativeAd(ad);

  // Ensure that the parent view doesn't already contain an ad view.
  parent.removeAllViews();

  // Place the AdView into the parent.
  parent.addView(adView);
}

Kotlin

fun displayNativeAd(parent: ViewGroup, ad: NativeAd) {

  // Inflate a layout and add it to the parent ViewGroup.
  val inflater = parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)
          as LayoutInflater
  val adView = inflater.inflate(R.layout.ad_layout_file, parent) as NativeAdView

  // Locate the view that will hold the headline, set its text, and use the
  // NativeAdView's headlineView property to register it.
  val headlineView = adView.findViewById<TextView>(R.id.ad_headline)
  headlineView.text = ad.headline
  adView.headlineView = headlineView

  // Repeat the process for the other assets in the NativeAd using
  // additional view objects (Buttons, ImageViews, etc).

  val mediaView = adView.findViewById<MediaView>(R.id.ad_media)
  adView.mediaView = mediaView

  // Call the NativeAdView's setNativeAd method to register the
  // NativeAdObject.
  adView.setNativeAd(ad)

  // Ensure that the parent view doesn't already contain an ad view.
  parent.removeAllViews()

  // Place the AdView into the parent.
  parent.addView(adView)
}

Jetpack Compose

@Composable
/** Display a native ad with a user defined template. */
fun DisplayNativeAdView(nativeAd: NativeAd) {
  val context = LocalContext.current
  Box(modifier = Modifier.padding(8.dp).wrapContentHeight(Alignment.Top)) {
    // Call the NativeAdView composable to display the native ad.
    NativeAdView {
      // Inside the NativeAdView composable, display the native ad assets.
      Column(Modifier.align(Alignment.TopStart).wrapContentHeight(Alignment.Top)) {
        // Display the ad attribution.
        NativeAdAttribution(text = context.getString(R.string.attribution))
        Row {
          // If available, display the icon asset.
          nativeAd.icon?.let { icon ->
            NativeAdIconView(Modifier.padding(5.dp)) {
              icon.drawable?.toBitmap()?.let { bitmap ->
                Image(bitmap = bitmap.asImageBitmap(), "Icon")
              }
            }
          }
          Column {
            // If available, display the headline asset.
            nativeAd.headline?.let {
              NativeAdHeadlineView {
                Text(text = it, style = MaterialTheme.typography.headlineLarge)
              }
            }
            // If available, display the star rating asset.
            nativeAd.starRating?.let {
              NativeAdStarRatingView {
                Text(text = "Rated $it", style = MaterialTheme.typography.labelMedium)
              }
            }
          }
        }

        // If available, display the body asset.
        nativeAd.body?.let { NativeAdBodyView { Text(text = it) } }
        // Display the media asset.
        NativeAdMediaView(Modifier.fillMaxWidth().height(500.dp).fillMaxHeight())

        Row(Modifier.align(Alignment.End).padding(5.dp)) {
          // If available, display the price asset.
          nativeAd.price?.let {
            NativeAdPriceView(Modifier.padding(5.dp).align(Alignment.CenterVertically)) {
              Text(text = it)
            }
          }
          // If available, display the store asset.
          nativeAd.store?.let {
            NativeAdStoreView(Modifier.padding(5.dp).align(Alignment.CenterVertically)) {
              Text(text = it)
            }
          }
          // If available, display the call to action asset.
          // Note: The Jetpack Compose button implements a click handler which overrides the native
          // ad click handler, causing issues. Use the NativeAdButton which does not implement a
          // click handler. To handle native ad clicks, use the NativeAd AdListener onAdClicked
          // callback.
          nativeAd.callToAction?.let { callToAction ->
            NativeAdCallToActionView(Modifier.padding(5.dp)) { NativeAdButton(text = callToAction) }
          }
        }
      }
    }
  }
}

في ما يلي المهام الفردية:

  1. تضخيم التنسيق

    Java

    LayoutInflater inflater = (LayoutInflater) parent.getContext()
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    NativeAdView adView = (NativeAdView) inflater
            .inflate(R.layout.ad_layout_file, parent);
    

    Kotlin

    val inflater = parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)
            as LayoutInflater
    val adView = inflater.inflate(R.layout.ad_layout_file, parent) as NativeAdView
    

    يعمل هذا الرمز على تضخيم تنسيق XML يحتوي على طرق عرض لعرض إعلان أصلي، ثم تحديد مرجع إلى NativeAdView. يُرجى العِلم أنّه يمكنك أيضًا إعادة استخدام NativeAdView حالي إذا كان هناك واحد في الجزء أو النشاط، أو حتى إنشاء مثيل ديناميكيًا بدون استخدام ملف تنسيق.

  2. تعبئة طرق عرض مواد العرض وتسجيلها

    يحدّد نموذج الرمز هذا طريقة العرض المستخدَمة لعرض العنوان، ويضبط النص باستخدام مادة عرض السلسلة التي يوفّرها عنصر الإعلان، ويسجّله باستخدام العنصر NativeAdView:

    Java

    TextView headlineView = adView.findViewById<TextView>(R.id.ad_headline);
    headlineView.setText(ad.getHeadline());
    adView.setHeadlineView(headlineView);
    

    Kotlin

    val headlineView = adView.findViewById<TextView>(R.id.ad_headline)
    headlineView.text = ad.headline
    adView.headlineView = headlineView
    

    يجب تكرار عملية تحديد موقع العرض وتعيين قيمته وتسجيله باستخدام فئة عرض الإعلان لكل مواد العرض التي يوفّرها عنصر الإعلان الأصلي الذي سيعرضه التطبيق.

  3. التعامل مع النقرات

    لا تنفِّذ أي معالجات نقرات مخصّصة على أي طرق عرض فوق طريقة عرض الإعلان الأصلي أو بداخلها. تتعامل حزمة SDK مع النقرات على مواد عرض الإعلان طالما أنّك تملأ طرق عرض مواد العرض وتسجّلها بشكل صحيح، كما هو موضّح في القسم السابق.

    للاستماع إلى النقرات، عليك تنفيذ وظيفة معاودة الاتصال الخاصة بالنقرات في "حزمة تطوير البرامج (SDK) لإعلانات Google على الأجهزة الجوّالة":

    Java

    AdLoader adLoader = new AdLoader.Builder(context, "ca-app-pub-3940256099942544/2247696110")
        // ...
        .withAdListener(new AdListener() {
            @Override
            public void onAdFailedToLoad(LoadAdError adError) {
                // Handle the failure by logging.
            }
            @Override
            public void onAdClicked() {
                // Log the click event or other custom behavior.
            }
        })
        .build();
    

    Kotlin

    val adLoader = AdLoader.Builder(this, "ca-app-pub-3940256099942544/2247696110")
        // ...
        .withAdListener(object : AdListener() {
            override fun onAdFailedToLoad(adError: LoadAdError) {
                // Handle the failure.
            }
            override fun onAdClicked() {
                // Log the click event or other custom behavior.
            }
        })
        .build()
    
  4. تسجيل MediaView

    عليك استخدام مادة العرض MediaView بدلاً من مادة العرض ImageView إذا أردت تضمين مادة عرض صورة رئيسية في تصميم إعلانك المدمج مع المحتوى.

    MediaView هو View خاص مصمّم لعرض مادة عرض الوسائط الرئيسية، سواء كانت فيديو أو صورة.

    يمكن تحديد MediaView في تصميم XML أو إنشاؤه ديناميكيًا. يجب وضعها ضمن التسلسل الهرمي للعرض الخاص بـ NativeAdView، تمامًا مثل أي عرض آخر لمادة عرض. على التطبيقات التي تستخدم MediaView تسجيلها لدى NativeAdView:

    Java

     // Populate and register the media asset view.
     nativeAdView.setMediaView(nativeAdBinding.adMedia);
    

    Kotlin

     // Populate and register the media asset view.
     nativeAdView.mediaView = nativeAdBinding.adMedia
    

    ImageScaleType

    تحتوي الفئة MediaView على السمة ImageScaleType عند عرض الصور. إذا أردت تغيير طريقة تغيير حجم الصورة في MediaView، اضبط ImageView.ScaleType المقابل باستخدام طريقة setImageScaleType() في MediaView:

    Java

    mediaView.setImageScaleType(ImageView.ScaleType.CENTER_CROP);
    

    Kotlin

    mediaView.imageScaleType = ImageView.ScaleType.CENTER_CROP
    

    MediaContent

    تحتوي الفئة MediaContent على البيانات المرتبطة بمحتوى الوسائط الخاص بالإعلان الأصلي، والذي يتم عرضه باستخدام الفئة MediaView. عند ضبط السمة MediaView mediaContent باستخدام مثيل MediaContent:

    • إذا كانت مادة عرض الفيديو متاحة، يتم تخزينها مؤقتًا ويبدأ تشغيلها داخل MediaView. يمكنك معرفة ما إذا كانت مادة عرض الفيديو متاحة من خلال التحقّق من hasVideoContent().

    • إذا لم يكن الإعلان يتضمّن مادة عرض فيديو، يتم تنزيل مادة العرض mainImage ووضعها داخل MediaView بدلاً من ذلك.

    تلقائيًا، تكون mainImage هي أول مادة عرض صورة يتم تنزيلها. في حال استخدام setReturnUrlsForImageAssets(true)، تكون قيمة mainImage هي null، ويجب ضبط السمة mainImage على الصورة التي تم تنزيلها يدويًا. يُرجى العِلم أنّه سيتم استخدام هذه الصورة فقط عندما لا تتوفّر مادة عرض فيديو.

  5. تسجيل عنصر الإعلان المدمج مع المحتوى

    تؤدي هذه الخطوة الأخيرة إلى تسجيل عنصر "الإعلان المدمج مع المحتوى" مع طريقة العرض المسؤولة عن عرضه.

    Java

    adView.setNativeAd(ad);
    

    Kotlin

    adView.setNativeAd(ad)
    

تدمير الإعلان

بعد الانتهاء من عرض الإعلان المدمج مع المحتوى، عليك إتلافه لكي يتم جمع البيانات غير الضرورية بشكل سليم.

Java

nativeAd.destroy();

Kotlin

nativeAd.destroy()

أمثلة على GitHub

مثال على عملية إعداد "الإعلانات المدمجة مع المحتوى" بالكامل:

Java Kotlin JetpackCompose

الخطوات التالية

يمكنك الاطّلاع على المواضيع التالية: