Zarządzanie reklamami na Androidzie i iOS

Reklamy natywne są wyświetlane użytkownikom za pomocą komponentów UI natywnych dla danej platformy, np. ViewView na Androidzie lub UIViewUIView na iOS.

Z tego przewodnika dowiesz się, jak wczytywać, wyświetlać i dostosowywać reklamy natywne za pomocą kodu specyficznego dla platformy.

Wymagania wstępne

Zanim przejdziesz dalej, wykonaj te czynności:

Zawsze testuj za pomocą reklam testowych

Podczas tworzenia i testowania aplikacji używaj reklam testowych, a nie reklam produkcyjnych. Najłatwiejszym sposobem na wczytanie reklam testowych jest użycie naszego specjalnego identyfikatora jednostki reklamowej do testowania reklam natywnych:

  • /21775744923/example/native

Jednostki reklamowe do testowania są skonfigurowane tak, aby zwracać reklamy testowe w odpowiedzi na każde żądanie. Możesz ich używać w swoich aplikacjach podczas kodowania, testowania i debugowania. Pamiętaj tylko, aby przed opublikowaniem aplikacji zastąpić je własnymi identyfikatorami jednostek reklamowych.

Konfiguracja specyficzna dla platformy

Aby utworzyć reklamy natywne, musisz napisać kod specyficzny dla platformy iOS i Android, a następnie zmodyfikować implementację w języku Dart, aby wykorzystać wprowadzone zmiany w kodzie natywnym.

Android

Importowanie wtyczki

Implementacja wtyczki Google Mobile Ads na Androida wymaga klasy implementującej NativeAdFactory interfejs API. Aby odwołać się do tego interfejsu API w projekcie aplikacji na Androida, dodaj te wiersze do pliku 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
}

Implementowanie NativeAdFactory

Następnie utwórz klasę, która implementuje NativeAdFactory i zastępuje metodę 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 Google Mobile Ads Flutter Plugin that you have finished populating your
    // native ad view with this native ad.
    adView.setNativeAd(nativeAd);

    return adView;
  }
}

Przykład konfiguracji układu NativeAdView znajdziesz w pliku my_native_ad.xml.

Rejestrowanie NativeAdFactory

Każda implementacja NativeAdFactory musi zostać zarejestrowana za pomocą factoryId, unikalnego identyfikatora String, podczas wywoływania MainActivity.configureFlutterEngine(FlutterEngine). factoryId będzie używany później podczas tworzenia instancji reklamy natywnej z kodu w języku Dart.

NativeAdFactory można zaimplementować i zarejestrować dla każdego unikalnego układu reklamy natywnej używanego przez aplikację lub można użyć jednej implementacji do obsługi wszystkich układów.

Pamiętaj, że podczas tworzenia aplikacji za pomocą funkcji dodawania do aplikacji należy też wyrejestrować NativeAdFactory w cleanUpFlutterEngine(engine).

Po utworzeniu NativeAdFactoryExample skonfiguruj MainActivity w ten sposób:

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

Implementowanie NativeAdFactory

Implementacja wtyczki Google Mobile Ads na iOS wymaga klasy implementującej FLTNativeAdFactory interfejs API. Utwórz klasę, która implementuje NativeAdFactory, i zaimplementuj metodę 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

Przykład konfiguracji układu GADNativeAdView znajdziesz w pliku NativeAdView.xib.

Rejestrowanie NativeAdFactory

Każda implementacja FLTNativeAdFactory musi zostać zarejestrowana za pomocą factoryId, unikalnego String identyfikatora, w registerNativeAdFactory:factoryId:nativeAdFactory:. factoryId będzie używany później podczas tworzenia instancji reklamy natywnej z kodu w języku Dart.

FLTNativeAdFactory można zaimplementować i zarejestrować dla każdego unikalnego układu reklamy natywnej używanego przez aplikację lub można użyć jednej implementacji do obsługi wszystkich układów.

Po utworzeniu FLTNativeAdFactory skonfiguruj AppDelegate w ten sposób:

#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

Wczytywanie reklamy

Po dodaniu kodu specyficznego dla platformy przejdź do języka Dart, aby wczytać reklamy. Upewnij się, że factoryID pasuje do zarejestrowanego wcześniej identyfikatora.

class NativeExampleState extends State<NativeExample> {
  NativeAd? _nativeAd;
  bool _nativeAdIsLoaded = false;

 // TODO: replace this test ad unit with your own ad unit.
 final _adUnitId = '/21775744923/example/native';

  /// 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 AdManagerAdRequest(),
        // Optional: Pass custom options to your native ad factory implementation.
        customOptions: {'custom-option-1', 'custom-value-1'}
    );
    _nativeAd.load();
  }
}

Zdarzenia związane z reklamami natywnymi

Aby otrzymywać powiadomienia o zdarzeniach związanych z interakcjami z reklamą natywną, użyj listener właściwości reklamy. Następnie zaimplementuj NativeAdListener aby otrzymywać wywołania zwrotne zdarzeń reklamowych.

class NativeExampleState extends State<NativeExample> {
  NativeAd? _nativeAd;
  bool _nativeAdIsLoaded = false;

 // TODO: replace this test ad unit with your own ad unit.
 final _adUnitId = '/21775744923/example/native';

  /// 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 AdManagerAdRequest(),
        // Optional: Pass custom options to your native ad factory implementation.
        customOptions: {'custom-option-1', 'custom-value-1'}
    );
    _nativeAd.load();
        
  }
}

Wyświetlanie reklamy

Aby wyświetlić NativeAd jako widżet, musisz utworzyć instancję AdWidget z obsługiwaną reklamą po wywołaniu load(). Możesz utworzyć widżet przed wywołaniem load(), ale load() musi zostać wywołane przed dodaniem go do drzewa widżetów.

AdWidget dziedziczy po klasie Widget Fluttera i może być używany jak każdy inny widżet. Na iOS umieść widżet w kontenerze o określonej szerokości i wysokości. W przeciwnym razie reklama może się nie wyświetlić.

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

Zamykanie reklamy

Gdy dostęp do NativeAd nie jest już potrzebny, należy go zamknąć. Najlepszym rozwiązaniem jest wywołanie dispose() po usunięciu z drzewa widżetów AdWidget powiązanego z reklamą natywną oraz w wywołaniu zwrotnym AdListener.onAdFailedToLoad().