Android 및 iOS의 기본 설정

네이티브 광고는 플랫폼 고유의 UI 구성요소(예: Android의 View 또는 iOS의 UIView)를 사용하여 사용자에게 표시됩니다.

이 가이드에서는 SDK를 사용하여 네이티브 광고를 로드하고, 표시하고, 맞춤설정하는 방법을 코드를 작성할 수 있습니다.

기본 요건

항상 테스트 광고로 테스트

앱을 빌드하고 테스트할 때는 만들 수 있습니다. 테스트 광고를 로드하는 가장 쉬운 방법은 네이티브 광고의 테스트 광고 단위 ID:

Android

ca-app-pub-3940256099942544/2247696110

iOS

ca-app-pub-3940256099942544/3986624511

테스트 광고 단위는 모든 요청에 대해 테스트 광고를 반환하도록 구성되어 있으므로 코딩, 테스트, 개발 중에 자체 앱에서 이를 사용할 수 있으며 자체 광고 단위 ID로 바꿔야 합니다. 매우 중요합니다

플랫폼별 설정

네이티브 광고를 만들려면 iOS용 플랫폼별 코드를 작성해야 합니다. Android, 그리고 Dart 구현을 수정하여 네이티브 코드 변경사항을 활용할 수 있습니다.

Android

플러그인 가져오기

Android에서 Google 모바일 광고 플러그인을 구현하려면 클래스가 필요합니다. 이를 구현하고 NativeAdFactory 드림 API에 액세스할 수 있습니다. Android 프로젝트에서 이 API를 참조하려면 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을 사용하여 빌드할 때는 cleanUpFlutterEngine(engine)에서 NativeAdFactory의 등록도 취소해야 합니다.

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

NativeAdFactory 구현

Google 모바일 광고 플러그인의 iOS 구현에는 클래스가 필요합니다. 이를 구현하고 FLTNativeAdFactory 드림 API에 액세스할 수 있습니다. 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를 참조하세요.

NativeAdFactory 등록

FLTNativeAdFactory는 고유한 factoryId String 식별자(registerNativeAdFactory:factoryId:nativeAdFactory:) factoryId는 나중에 네이티브 광고를 인스턴스화할 때 사용됩니다. 얻습니다.

FLTNativeAdFactory는 고유한 각 UI에 대해 구현 및 등록될 수 있습니다. 네이티브 광고 레이아웃을 사용해야 하며, 단일 광고 레이아웃으로 모든 레이아웃을 처리할 수 있습니다.

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이 이전에 등록한 ID와 일치하는지 확인합니다.

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를 위젯으로 표시하려면 load()를 호출한 후 지원되는 광고를 사용하여 AdWidget를 인스턴스화해야 합니다. 다음 날짜 이전에 위젯을 만들 수 있습니다. load()를 호출하지만 위젯에 추가하기 전에 load()를 호출해야 합니다. 있습니다.

AdWidget는 Flutter의 Widget 클래스에서 상속되며 다른 클래스처럼 사용할 수 있습니다. 위젯에 추가합니다. iOS에서는 지정된 너비와 높이를 바탕으로 컨테이너에 위젯을 배치해야 합니다. 그렇지 않으면 광고가 게재되지 않을 수 있습니다.

final Container adContainer = Container(
  alignment: Alignment.center,
  child: AdWidget adWidget = AdWidget(ad: _nativeAd!),
  width: WIDTH,
  height: HEIGHT,
);

광고 폐기

NativeAd 드림 는 액세스 권한이 더 이상 필요하지 않은 경우 폐기해야 합니다. GCP의 dispose()를 호출해야 하는 시점이 네이티브 광고와 연결된 AdWidget 이후 위젯 트리와 AdListener.onAdFailedToLoad()에서 삭제됩니다. 있습니다.

다음 단계

GitHub의 전체 예

네이티브 플랫폼