يتم عرض الإعلانات المدمجة مع المحتوى للمستخدمين الذين يستخدمون مكونات واجهة المستخدم المدمجة مع المحتوى
منصة — على سبيل المثال،
View
على Android أو
على UIView
في
iOS.
يوضّح لك هذا الدليل كيفية تحميل الإعلانات المدمجة مع المحتوى وعرضها وتخصيصها باستخدام التعليمات البرمجية الخاصة بالنظام الأساسي.
المتطلبات الأساسية
- أكمِل دليل البدء.
- اطّلع على خيارات الإعلانات المدمجة مع المحتوى.
الاختبار دائمًا باستخدام الإعلانات الاختبارية
عند إنشاء تطبيقاتك واختبارها، احرص على استخدام إعلانات تجريبية بدلاً من إعلانات بث مباشر وتتمثل أسهل طريقة لتحميل الإعلانات الاختبارية في استخدام اختبار معرّف الوحدة الإعلانية للإعلانات المدمجة مع المحتوى:
Android
ca-app-pub-3940256099942544/2247696110
iOS
ca-app-pub-3940256099942544/3986624511
تم إعداد الوحدات الإعلانية الاختبارية لعرض إعلانات اختبارية لكل طلب، لذلك يمكنك استخدامها في تطبيقاتك أثناء الترميز والاختبار ومحاولة تصحيح الأخطاء، ما عليك سوى التأكّد من استبدالها بمعرّفات وحداتك الإعلانية قبل نشر تطبيقك.
عمليات الإعداد الخاصة بالمنصة
لإنشاء إعلاناتك المدمجة مع المحتوى، ستحتاج إلى كتابة رمز خاص بالنظام الأساسي لنظام التشغيل iOS ونظام التشغيل Android، يليه تعديل تنفيذ السهم للاستفادة من التغييرات التي أجريتها على الرموز البرمجية الأصلية
Android
استيراد المكوّن الإضافي
يتطلب تنفيذ Android للمكوّن الإضافي لإعلانات Google على الأجهزة الجوّالة فئة
تنفيذ
NativeAdFactory
واجهة برمجة التطبيقات. للإشارة إلى واجهة برمجة التطبيقات هذه من مشروع Android، أضِف السمة
الأسطر التالية إلى settings.gradle:
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
def plugins = new Properties()
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
if (pluginsFile.exists()) {
pluginsFile.withInputStream { stream -> plugins.load(stream) }
}
plugins.each { name, path ->
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
include ":$name"
project(":$name").projectDir = pluginDirectory
}
تنفيذ NativeAdFactory
بعد ذلك، أنشئ فئة تنفِّذ NativeAdFactory
وتلغي
طريقة createNativeAd()
.
package io.flutter.plugins.googlemobileadsexample;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.widget.TextView;
import com.google.android.gms.ads.nativead.NativeAd;
import com.google.android.gms.ads.nativead.NativeAdView;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin.NativeAdFactory;
import java.util.Map;
/**
* my_native_ad.xml can be found at
* github.com/googleads/googleads-mobile-flutter/blob/main/packages/google_mobile_ads/
* example/android/app/src/main/res/layout/my_native_ad.xml
*/
class NativeAdFactoryExample implements NativeAdFactory {
private final LayoutInflater layoutInflater;
NativeAdFactoryExample(LayoutInflater layoutInflater) {
this.layoutInflater = layoutInflater;
}
@Override
public NativeAdView createNativeAd(
NativeAd nativeAd, Map<String, Object> customOptions) {
final NativeAdView adView =
(NativeAdView) layoutInflater.inflate(R.layout.my_native_ad, null);
// Set the media view.
adView.setMediaView((MediaView) adView.findViewById(R.id.ad_media));
// Set other ad assets.
adView.setHeadlineView(adView.findViewById(R.id.ad_headline));
adView.setBodyView(adView.findViewById(R.id.ad_body));
adView.setCallToActionView(adView.findViewById(R.id.ad_call_to_action));
adView.setIconView(adView.findViewById(R.id.ad_app_icon));
adView.setPriceView(adView.findViewById(R.id.ad_price));
adView.setStarRatingView(adView.findViewById(R.id.ad_stars));
adView.setStoreView(adView.findViewById(R.id.ad_store));
adView.setAdvertiserView(adView.findViewById(R.id.ad_advertiser));
// The headline and mediaContent are guaranteed to be in every NativeAd.
((TextView) adView.getHeadlineView()).setText(nativeAd.getHeadline());
adView.getMediaView().setMediaContent(nativeAd.getMediaContent());
// These assets aren't guaranteed to be in every NativeAd, so it's important to
// check before trying to display them.
if (nativeAd.getBody() == null) {
adView.getBodyView().setVisibility(View.INVISIBLE);
} else {
adView.getBodyView().setVisibility(View.VISIBLE);
((TextView) adView.getBodyView()).setText(nativeAd.getBody());
}
if (nativeAd.getCallToAction() == null) {
adView.getCallToActionView().setVisibility(View.INVISIBLE);
} else {
adView.getCallToActionView().setVisibility(View.VISIBLE);
((Button) adView.getCallToActionView()).setText(nativeAd.getCallToAction());
}
if (nativeAd.getIcon() == null) {
adView.getIconView().setVisibility(View.GONE);
} else {
((ImageView) adView.getIconView()).setImageDrawable(nativeAd.getIcon().getDrawable());
adView.getIconView().setVisibility(View.VISIBLE);
}
if (nativeAd.getPrice() == null) {
adView.getPriceView().setVisibility(View.INVISIBLE);
} else {
adView.getPriceView().setVisibility(View.VISIBLE);
((TextView) adView.getPriceView()).setText(nativeAd.getPrice());
}
if (nativeAd.getStore() == null) {
adView.getStoreView().setVisibility(View.INVISIBLE);
} else {
adView.getStoreView().setVisibility(View.VISIBLE);
((TextView) adView.getStoreView()).setText(nativeAd.getStore());
}
if (nativeAd.getStarRating() == null) {
adView.getStarRatingView().setVisibility(View.INVISIBLE);
} else {
((RatingBar) adView.getStarRatingView()).setRating(nativeAd.getStarRating()
.floatValue());
adView.getStarRatingView().setVisibility(View.VISIBLE);
}
if (nativeAd.getAdvertiser() == null) {
adView.getAdvertiserView().setVisibility(View.INVISIBLE);
} else {
adView.getAdvertiserView().setVisibility(View.VISIBLE);
((TextView) adView.getAdvertiserView()).setText(nativeAd.getAdvertiser());
}
// This method tells the Google Mobile Ads SDK that you have finished populating your
// native ad view with this native ad.
adView.setNativeAd(nativeAd);
return adView;
}
}
للحصول على مثال على ضبط تنسيق NativeAdView
، يُرجى الاطّلاع على my_native_ad.xml.
تسجيل NativeAdFactory
يجب أن يتم تسجيل كل عملية تنفيذ NativeAdFactory
من خلال
factoryId
، معرّف String
فريد عند الاتصال
MainActivity.configureFlutterEngine(FlutterEngine)
سيكون factoryId
سيتم استخدامه لاحقًا عند إنشاء إعلان مدمج مع المحتوى من رمز Dart.
يمكن تنفيذ NativeAdFactory
وتسجيلها لكل نموذج محلي فريد
تنسيق الإعلان الذي يستخدمه تطبيقك أو يمكن لأحد التخطيطات أن يتعامل مع جميع التنسيقات.
لاحظ أنه عند الإنشاء باستخدام
add-to-app،
يجب أن يكون NativeAdFactory
غير مسجَّل أيضًا في
cleanUpFlutterEngine(engine)
بعد إنشاء NativeAdFactoryExample
، يمكنك إعداد MainActivity
باعتباره
التالي:
package my.app.path;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.plugins.googlemobileads.GoogleMobileAdsPlugin;
public class MainActivity extends FlutterActivity {
@Override
public void configureFlutterEngine(FlutterEngine flutterEngine) {
flutterEngine.getPlugins().add(new GoogleMobileAdsPlugin());
super.configureFlutterEngine(flutterEngine);
GoogleMobileAdsPlugin.registerNativeAdFactory(flutterEngine,
"adFactoryExample", NativeAdFactoryExample());
}
@Override
public void cleanUpFlutterEngine(FlutterEngine flutterEngine) {
GoogleMobileAdsPlugin.unregisterNativeAdFactory(flutterEngine, "adFactoryExample");
}
}
iOS
تنفيذ NativeAdFound
يتطلب تنفيذ المكون الإضافي لإعلانات Google على الأجهزة الجوّالة على نظام التشغيل iOS فئة
تنفيذ
FLTNativeAdFactory
واجهة برمجة التطبيقات. أنشئ فئة تنفِّذ NativeAdFactory
وتنفّذ السمة
طريقة createNativeAd()
.
#import "FLTGoogleMobileAdsPlugin.h"
/**
* The example NativeAdView.xib can be found at
* github.com/googleads/googleads-mobile-flutter/blob/main/packages/google_mobile_ads/
* example/ios/Runner/NativeAdView.xib
*/
@interface NativeAdFactoryExample : NSObject <FLTNativeAdFactory>
@end
@implementation NativeAdFactoryExample
- (GADNativeAdView *)createNativeAd:(GADNativeAd *)nativeAd
customOptions:(NSDictionary *)customOptions {
// Create and place the ad in the view hierarchy.
GADNativeAdView *adView =
[[NSBundle mainBundle] loadNibNamed:@"NativeAdView" owner:nil options:nil].firstObject;
// Populate the native ad view with the native ad assets.
// The headline is guaranteed to be present in every native ad.
((UILabel *)adView.headlineView).text = nativeAd.headline;
// These assets are not guaranteed to be present. Check that they are before
// showing or hiding them.
((UILabel *)adView.bodyView).text = nativeAd.body;
adView.bodyView.hidden = nativeAd.body ? NO : YES;
[((UIButton *)adView.callToActionView) setTitle:nativeAd.callToAction
forState:UIControlStateNormal];
adView.callToActionView.hidden = nativeAd.callToAction ? NO : YES;
((UIImageView *)adView.iconView).image = nativeAd.icon.image;
adView.iconView.hidden = nativeAd.icon ? NO : YES;
((UILabel *)adView.storeView).text = nativeAd.store;
adView.storeView.hidden = nativeAd.store ? NO : YES;
((UILabel *)adView.priceView).text = nativeAd.price;
adView.priceView.hidden = nativeAd.price ? NO : YES;
((UILabel *)adView.advertiserView).text = nativeAd.advertiser;
adView.advertiserView.hidden = nativeAd.advertiser ? NO : YES;
// In order for the SDK to process touch events properly, user interaction
// should be disabled.
adView.callToActionView.userInteractionEnabled = NO;
// Associate the native ad view with the native ad object. This is
// required to make the ad clickable.
// Note: this should always be done after populating the ad views.
adView.nativeAd = nativeAd;
return adView;
}
@end
للحصول على مثال على ضبط تنسيق GADNativeAdView
، اطّلِع على NativeAdView.xib.
تسجيل NativeAdFound
يجب تسجيل كل FLTNativeAdFactory
باستخدام factoryId
، وهو فريد
String
، في registerNativeAdFactory:factoryId:nativeAdFactory:
.
سيتم استخدام factoryId
لاحقًا عند إنشاء إعلان مدمج مع المحتوى
من رمز Dart.
يمكن تنفيذ FLTNativeAdFactory
وتسجيلها لكل منتج
يمكن لتخطيط الإعلان المدمج مع المحتوى الذي يستخدمه تطبيقك، أو تنسيق واحد التعامل مع جميع التنسيقات.
بعد إنشاء FLTNativeAdFactory
، يمكنك إعداد AppDelegate
باعتباره
التالي:
#import "FLTGoogleMobileAdsPlugin.h"
#import "NativeAdFactoryExample.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Must be added after GeneratedPluginRegistrant registerWithRegistry:self];
// is called.
NativeAdFactoryExample *nativeAdFactory = [[NativeAdFactoryExample alloc] init];
[FLTGoogleMobileAdsPlugin registerNativeAdFactory:self
factoryId:@"adFactoryExample"
nativeAdFactory:nativeAdFactory];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
تحميل الإعلان
بعد إضافة الرمز الخاص بالنظام الأساسي، انتقِل إلى Dart لتحميل الإعلانات. تأكَّد من أنّ factoryID
يتطابق مع رقم التعريف الذي سجّلته سابقًا.
class NativeExampleState extends State<NativeExample> {
NativeAd? _nativeAd;
bool _nativeAdIsLoaded = false;
// TODO: replace this test ad unit with your own ad unit.
final String _adUnitId = Platform.isAndroid
? 'ca-app-pub-3940256099942544/2247696110'
: 'ca-app-pub-3940256099942544/3986624511';
/// Loads a native ad.
void loadAd() {
_nativeAd = NativeAd(
adUnitId: _adUnitId,
// Factory ID registered by your native ad factory implementation.
factoryId: 'adFactoryExample',
listener: NativeAdListener(
onAdLoaded: (ad) {
print('$NativeAd loaded.');
setState(() {
_nativeAdIsLoaded = true;
});
},
onAdFailedToLoad: (ad, error) {
// Dispose the ad here to free resources.
print('$NativeAd failedToLoad: $error');
ad.dispose();
},
),
request: const AdRequest(),
// Optional: Pass custom options to your native ad factory implementation.
customOptions: {'custom-option-1', 'custom-value-1'}
);
_nativeAd.load();
}
}
أحداث الإعلانات المدمجة مع المحتوى
لتلقّي إشعارات بالأحداث ذات الصلة بالتفاعلات مع الإعلانات المدمجة مع المحتوى، استخدِم
listener
الخاصة بالإعلان. بعد ذلك، نفِّذ
NativeAdListener
لتلقّي استدعاءات حدث الإعلان.
class NativeExampleState extends State<NativeExample> {
NativeAd? _nativeAd;
bool _nativeAdIsLoaded = false;
// TODO: replace this test ad unit with your own ad unit.
final String _adUnitId = Platform.isAndroid
? 'ca-app-pub-3940256099942544/2247696110'
: 'ca-app-pub-3940256099942544/3986624511';
/// Loads a native ad.
void loadAd() {
_nativeAd = NativeAd(
adUnitId: _adUnitId,
// Factory ID registered by your native ad factory implementation.
factoryId: 'adFactoryExample',
listener: NativeAdListener(
onAdLoaded: (ad) {
print('$NativeAd loaded.');
setState(() {
_nativeAdIsLoaded = true;
});
},
onAdFailedToLoad: (ad, error) {
// Dispose the ad here to free resources.
print('$NativeAd failedToLoad: $error');
ad.dispose();
},
// Called when a click is recorded for a NativeAd.
onAdClicked: (ad) {},
// Called when an impression occurs on the ad.
onAdImpression: (ad) {},
// Called when an ad removes an overlay that covers the screen.
onAdClosed: (ad) {},
// Called when an ad opens an overlay that covers the screen.
onAdOpened: (ad) {},
// For iOS only. Called before dismissing a full screen view
onAdWillDismissScreen: (ad) {},
// Called when an ad receives revenue value.
onPaidEvent: (ad, valueMicros, precision, currencyCode) {},
),
request: const AdRequest(),
// Optional: Pass custom options to your native ad factory implementation.
customOptions: {'custom-option-1', 'custom-value-1'}
);
_nativeAd.load();
}
}
إعلان صوري
لعرض NativeAd
كأداة، يجب إنشاء مثيل
AdWidget
بإعلان متوافق بعد الاتصال بـ load()
. يمكنك إنشاء الأداة قبل
جارٍ استدعاء load()
، ولكن يجب طلب load()
قبل إضافته إلى التطبيق المصغَّر
شَجَرَة
تكتسب AdWidget
من فئة Widget
في Flutter ويمكن استخدامها مثل أي فئة أخرى.
التطبيق المصغّر. على أجهزة iOS، احرص على وضع التطبيق المصغّر في حاوية ذات عرض وارتفاع محدّدَين. وإلا فقد لا يتم عرض إعلانك.
final Container adContainer = Container(
alignment: Alignment.center,
child: AdWidget adWidget = AdWidget(ad: _nativeAd!),
width: WIDTH,
height: HEIGHT,
);
التخلص من الإعلان
حاسمة
NativeAd
يجب التخلص منها عند عدم الحاجة إلى الوصول إليها. إن أفضل ممارسة
وقت الاتصال بـ dispose()
بعد AdWidget
المرتبط بالإعلان المدمج مع المحتوى
تتم إزالتها من شجرة التطبيقات المصغّرة وفي AdListener.onAdFailedToLoad()
معاودة الاتصال.
الخطوات التالية
- مزيد من المعلومات عن "الإعلانات المدمجة مع المحتوى" في الإعلان المدمج مع المحتوى الدليل الإرشادي.
- اطّلِع على سياسات الإعلانات المدمجة مع المحتوى وإرشاداتها.
- الاطلاع على بعض قصص نجاح العملاء: دراسة حالة 1، دراسة حالة 2.