입찰 어댑터 개발

이 가이드는 입찰 어댑터를 만들려는 광고 네트워크를 대상으로 합니다. 해야 Google 미디에이션에서 실시간 입찰 (RTB)에 참여할 수 있습니다. 만약 게시자인 경우 게시자 미디에이션 참조하세요.

입찰 어댑터는 통합의 클라이언트 측 부분입니다. 어댑터 를 사용하면 광고 네트워크 SDK가 Google 모바일 광고 SDK와 통신하여 광고를 로드할 수 있습니다.

입찰이 올바르게 작동하려면 어댑터에서 초기화, 신호 수집, 광고 로드, 광고 수명 주기 릴레이 이벤트를 수신합니다. 이 가이드에서는 어댑터를 연결하는 방법에 대해 설명합니다. 구현됩니다.

입찰 어댑터의 워크플로

초기화

요청, 응답, 렌더링 전체 수명 주기의 상세한 흐름 어댑터의 정의는 아래와 같습니다.

어댑터는 워크플로의 다음 부분을 담당합니다.

  • 4~7단계: 어댑터 초기화 및 Google 모바일 광고 SDK 콜백 초기화가 완료된 후

  • 10~13단계: 광고 네트워크 SDK에서 신호를 수집하여 Google 모바일 애플리케이션에 선택합니다.

  • 18~21단계: 입찰자가 낙찰가를 반환하면 어떻게 해야 할까요? 로드가 완료되면 Google 모바일 광고 SDK에 알림 확인할 수 있습니다.

  • 23단계 이후: 광고가 표시되는 동안 Google 모바일 광고에 알림 노출 및 클릭 이벤트뿐만 아니라 발생하는 기타 광고 이벤트의 SDK 사용할 수 있습니다.

를 통해 개인정보처리방침을 정의할 수 있습니다.

입찰 어댑터 구현

Google 모바일 광고 SDK용 입찰 어댑터를 만들려면 RtbAdapter 추상 클래스를 확장합니다. 다음 섹션 RtbAdapter의 각 추상 메서드를 설명합니다.

getSDKVersionInfo()

여기에서 SDK 버전을 반환해야 합니다. 이 버전은 입찰자에게 전달됩니다.

이 메서드를 사용하려면 VersionInfo를 반환해야 합니다. 아래 예는 SDK의 문자열 버전을 VersionInfo.으로 변환할 수 있습니다.

@Override
public VersionInfo getSDKVersionInfo() {
  // Get your SDK's version as a string. E.g. "1.2.3"
  // String versionString = YourSdk.getVersion();
  String splits[] = versionString.split("\\.");
  if (splits.length >= 3) {
      int major = Integer.parseInt(splits[0]);
      int minor = Integer.parseInt(splits[1]);
      int micro = Integer.parseInt(splits[2]);
      return new VersionInfo(major, minor, micro);
   }

   String logMessage = String.format("Unexpected SDK version format: %s." +
           "Returning 0.0.0 for SDK version.", sdkVersion);
   Log.w(TAG, logMessage);
   return new VersionInfo(0, 0, 0);
}

getVersionInfo()

여기에서 어댑터 버전을 반환해야 합니다. 이 버전은 입찰자에게 전달됩니다.

Google의 오픈소스로 제공되며 어댑터 4자리 어댑터 버전 체계를 사용하지만 VersionInfo는 숫자입니다. 이 문제를 해결하려면 마지막 두 자리 숫자를 조합하는 것이 좋습니다. 패치 버전으로 업데이트합니다

@Override
public VersionInfo getVersionInfo() {
  // Get your adapters's version as a string. E.g. "1.2.3.0"
  String versionString = BuildConfig.VERSION_NAME;
  String splits[] = versionString.split("\\.");
  if (splits.length >= 4) {
      int major = Integer.parseInt(splits[0]);
      int minor = Integer.parseInt(splits[1]);
      int micro = Integer.parseInt(splits[2]) * 100 + Integer.parseInt(splits[3]);
      return new VersionInfo(major, minor, micro);
    }

    String logMessage = String.format("Unexpected adapter version format: %s." +
                "Returning 0.0.0 for adapter version.", versionString);
    Log.w(TAG, logMessage);
    return new VersionInfo(0, 0, 0);
}

initialize()

제한 시간: 30초

initialize() 메서드는 어댑터에서 호출되는 첫 번째 메서드입니다. 그것은 세션당 한 번만 호출됩니다. 이 방법을 사용하면 MediationConfiguration 객체는 이 앱에서 광고 네트워크에 구성된 게재위치 연속 재생 가능 각 게재위치에 대한 사용자 인증 정보를 파싱하고, 초기화를 위해 관련 데이터를 SDK에 전달합니다.

SDK가 초기화되고 광고 요청을 받을 준비가 되면 InitializationCompleteCallbackonInitializationSucceeded() 메서드 이 콜백은 앱 게시자에게 전달되어 광고 로드를 시작할 수 있습니다

@Override
public void initialize(Context context,
    InitializationCompleteCallback initializationCompleteCallback,
    List<MediationConfiguration> mediationConfigurations) {
  // Initialize your ad network's SDK.
  ...

  // Invoke the InitializationCompleteCallback once initialization completes.
  initializationCompleteCallback.onInitializationSucceeded();
}

collectSignals()

제한 시간: 1초

게시자가 광고를 요청할 때마다 RtbAdapter의 새 인스턴스는 다음과 같이 계산됩니다. 생성되고 collectSignals() 메서드가 호출됩니다. 이 인스턴스는 RtbAdapter는 광고 요청, 응답의 지속 시간과 합니다. collectSignals() 메서드를 사용하면 사용할 신호를 제공하는데, 이 어댑터는 OpenRTB 요청

collectSignals()는 백그라운드 스레드에서 호출됩니다. Google 모바일 광고 SDK가 동시에 모든 어댑터의 신호를 요청함 참여할 수 있습니다. 이 점을 고려하여 UI 스레드에 대한 호출을 제한하세요. 확인할 수 있습니다. 데이터를 수집하기 위해 어댑터 또는 SDK가 수행해야 하는 고부하 작업 신호는 initialize() 메서드에서 실행되고 캐시되어야 합니다.

신호가 준비되면 onSuccess() 콜백을 인코딩합니다.

다음은 구현의 예입니다.

@Override
public void collectSignals(RtbSignalData rtbSignalData,
                           SignalCallbacks signalCallbacks) {
  String signals = YourSdk.getSignals();
  signalCallbacks.onSuccess(signals);
}

어댑터가 신호를 수집하지 못하면 signalCallbacks.onFailure()를 호출합니다. 발생한 오류를 설명하는 문자열로 바꿉니다.

광고 로드 메서드 구현

제한 시간: 10초

입찰자가 낙찰가를 반환하면 Google 모바일 광고 SDK가 어댑터를 호출하여 낙찰된 광고를 로드하고, SDK가 해당 광고를 로드해야 한다는 것을 반환했습니다.

호출되는 정확한 로드 메서드는 광고의 이 요청의 형식:

광고 형식 로드 방법
배너 loadBannerAd()
전면 광고 loadInterstitialAd()
리워드 제공됨 loadRewardedAd()

어댑터가 지원하는 광고 형식에 대해 이러한 메서드를 구현합니다.

로드 메서드는 신호를 제공한 어댑터입니다. 이 방법을 사용하면 매개변수:

  • MediationAdConfiguration: SDK에서 실행해야 하는 매개변수가 포함되어 있습니다. 입찰 응답 및 사용자 인증 정보 등 낙찰가에 대한 광고를 로드합니다. AdMob UI에서 구성한 게시자입니다.

  • Google 모바일 광고 SDK에 알리는 데 사용되는 MediationAdLoadCallback 객체 로드가 성공하거나 실패할 때

SDK에서 광고를 로드하면 mediationAdLoadCallback.onSuccess()를 호출합니다. 이벤트 광고가 로드되지 않으면 mediationAdLoadCallback.onFailure() 발생한 오류를 설명하는 문자열입니다.

mediationAdLoadCallback.onSuccess() 메서드를 사용하려면 'Ad' 중 하나를 확인하는 객체입니다. Google 모바일에서 정의한 인터페이스 선택합니다. 이러한 광고 인터페이스에서는 광고에 대한 몇 가지 정보를 제공하도록 요청합니다.

MediationAdConfiguration에도 getWatermark()이(가) 있습니다. 메서드를 사용하여 PNG 이미지를 나타내는 base64 인코딩 문자열을 반환합니다. 이 이미지 광고의 투명한 오버레이에 타일로 표시됩니다. 워터마크를 렌더링하는 방법에 관한 추가 안내는 Google에 문의하세요. 게시 중인 광고에 대한 메타데이터가 포함되어 있으며, 게시자가 이 메타데이터를 사용하여 게재되는 광고의 소스입니다.

배너의 경우 배너 보기를 제공하라는 메시지가 표시됩니다. 전면 광고 및 show() 메서드를 구현하여 더 나중으로 만들 수 있습니다. 가장 좋은 방법은 광고 로드가 이러한 광고 메서드 구현도 담당하나요?

다음은 loadBannerAd()의 샘플 구현입니다. 유의사항 어댑터가 구현되는 방식이 달라진다는 사실을 다른 SDK에 통합됩니다

public final class SampleRtbAdapter extends RtbAdapter {
  ...

  @Override
  public void loadBannerAd(
      MediationBannerAdConfiguration adConfiguration,
      MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> callback) {

      SampleBannerRenderer bannerRenderer =
          new SampleBannerRenderer(adConfiguration, callback);
      bannerRenderer.render();
    }
}

// Renders a banner ad, and forwards callbacks to the Google Mobile Ads SDK.
public class SampleBannerRenderer implements MediationBannerAd {
  private MediationBannerAdConfiguration adConfiguration;
  private final MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> adLoadCallback;
  private AdView adView;
  private MediationBannerAdCallback callback;

  public SampleRtbBannerRenderer(
      MediationBannerAdConfiguration adConfiguration,
      MediationAdLoadCallback<MediationBannerAd, MediationBannerAdCallback> adLoadCallback) {
    this.adConfiguration = adConfiguration;
    this.adLoadCallback = adLoadCallback;
  }

  public void render() {
    adView = new AdView(adConfiguration.getContext());
    adView.setAdSize(adConfiguration.getAdSize());
    // serverParameters are the parameters entered in the AdMob UI for your network.
    adView.setAdUnitId(adConfiguration.getServerParameters().getString("adUnitId"));

    // Map the callbacks from your SDK to Google's SDK.
    adView.setAdListener(new AdListener() {
      // See the next step for more information on callback mapping.
      // ...
    });

    // Get the bid response and watermark from the ad configuration and
    // pass the relevant information to your SDK.
    String ad = adConfiguration.getBidResponse();
    String watermark = adConfiguration.getWatermark();
    Bundle extras = new Bundle();
    extras.putString("bid", ad);
    extras.putString("watermark", watermark);
    AdRequest request = new AdRequest.Builder()
        .addNetworkExtrasBundle(AdMobAdapter.class, extras)
        .build();
    adView.loadAd(request);
  }

  // MediationBannerAd implementation

  @NonNull
  @Override
  public View getView() {
    return adView;
  }
}

광고 프레젠테이션 수명 주기 이벤트 릴레이

어댑터의 마지막 역할은 Google 모바일 광고 SDK에 이를 알리는 것입니다. 전달될 수 있도록 모든 프레젠테이션 수명 주기 이벤트에서 있습니다. 게시자는 어떤 광고 네트워크에서 광고를 게재하는지 알 수 있기 때문에 이 중 대부분이 가능한 한 적절한 시점에 콜백이 호출되므로 모바일 광고 SDK가 이를 게시자에게 전달할 수 있습니다.

어댑터는 해당하는 경우 다음 이벤트를 호출해야 합니다.

모든 형식에 공통
메서드 호출 시점
reportAdClicked() 광고를 클릭한 경우
reportAdImpression() 광고에서 노출을 렌더링한 경우
onAdOpened() 광고가 전체 화면으로 표시된 경우
onAdClosed() 광고의 전체 화면 보기가 닫힌 경우
onAdLeftApplication() 광고로 인해 사용자가 앱에서 나간 경우
보상형 광고
onRewarded() 사용자에게 보상이 제공된 경우
동영상 콜백 (보상형 및 네이티브 광고)
onVideoStarted() 광고 동영상이 시작된 경우
onVideoCompleted() 광고 동영상이 완료된 경우

어댑터는 MediationAdLoadCallback<MediationAdT, MediationAdCallbackT>를 가져옵니다. mediationAdLoadCallback.onSuccess() 호출 시 해당 객체를 다시 반환합니다. 어댑터는 이 객체를 보유하여 프레젠테이션 이벤트를 호출하는 데 사용할 것으로 예상됩니다. 확인할 수 있습니다.

일반적으로 이러한 이벤트의 대부분은 광고 네트워크의 SDK에 의해 발생합니다. 이 어댑터의 역할은 광고 네트워크 SDK의 콜백을 Google 모바일 광고 SDK에 오신 것을 환영합니다.

다음 예는 Google 모바일 광고 SDK에 대한 SDK의 광고 리스너:

adView.setAdListener(new AdListener() {
    public void onAdLoaded() {
        callback = adLoadCallback.onSuccess(SampleBannerRenderer.this);
    }

    public void onAdImpression() {
        if (callback != null) {
            callback.reportAdImpression();
        }
    }

    public void onAdFailedToLoad(LoadAdError adError) {
        adLoadCallback.onFailure("Error: " + adError.toString());
    }

    public void onAdClosed() {
        if (callback != null) {
            callback.onAdClosed();
        }
    }

    public void onAdOpened() {
        if (callback != null) {
            callback.onAdOpened();
            callback.reportAdClicked();
        }
    }

    public void onAdLeftApplication() {
        if (callback != null) {
            callback.onAdLeftApplication();
        }
    }
});

네이티브 광고 노출 추적을 위한 필수 애셋

Google 모바일 광고 SDK는 광고가 표시되는지 확인합니다. 광고 네트워크 SDK에서 특정 확장 소재를 표시해야 하는 경우 유효한 노출을 렌더링하기 위해 입찰자는 네이티브 애셋을 표시합니다. 그러면 Google 모바일 광고 SDK가 필수 네이티브 애셋이 표시되어야 합니다.

자세한 내용은 네이티브 필수 애셋 문서에서 입찰에서 추가 필수 애셋을 지정하는 방법에 대한 자세한 정보 있습니다.

광고 오류 표시

전면 광고 및 보상형 광고와 같은 전체 화면 형식의 경우 로드 콜백을 호출하여 MediationInterstitialAd 또는 MediationRewardedAd 그래야 Google 모바일 광고 SDK가 어댑터에 광고 표시를 요청할 수 있습니다.

Google 모바일 광고 SDK는 어댑터가 광고를 정상적으로 로드한 경우 게시자가 광고를 표시하도록 요청할 때 광고를 게재할 준비가 된 것입니다. 즉, 노출로 이어져야 합니다

그러나 경우에 따라 광고를 게재할 수 없는 경우도 있습니다. 만약 광고를 게재할 수 없는 경우 onAdFailedToShow() 콜백을 호출하여 노출을 취소합니다.

아래 표에는 프레젠테이션 콜백이 전체 화면 광고 형식의 노출 기록에 미치는 영향이 나와 있습니다.

콜백 결과
onAdOpened() Impression recorded
onAdFailedToShow() Impression failure1
몇 초 동안 해당 사항 없음 Impression recorded

1 실패한 경우 광고 네트워크에 노출에 대해 비용이 청구되지 않지만 청구 가능한 이벤트 요율 조정에 영향을 미칩니다. 입찰 요청 보기 신호를 사용하여 확인할 수 있습니다

다음 모의 예시는 광고가 한 번에 표시되는 로드/표시 수명 주기를 오류가 발생할 수 있습니다.

final class SampleRtbAdapter extends RtbAdapter implements MediationRewardedAd {

 private MediationRewardedAdCallback callback;
 private RewardedAd rewardedAd;

 ...

  @Override
  public void loadRewardedAd(
      MediationRewardedAdConfiguration adConfiguration,
      final MediationAdLoadCallback<MediationRewardedAd, MediationRewardedAdCallback> loadCallback) {

    // Load an ad. This mock example uses Google's SDK, but in practice
    // your adapter will load the ad using your ad network's SDK.
    RewardedAd.load(adConfiguration.getContext(),
        "ca-app-pub-3940256099942544/5224354917",
        new AdRequest.Builder().build(),
        new RewardedAdLoadCallback() {
          @Override
          public void onAdLoaded(@NonNull RewardedAd rewardedAd) {
            // When the ad loads, invoke the load success callback.
            callback = loadCallback.onSuccess(SampleRtbAdapter.this);
          }
        });
  }

  @Override
  public void showAd(Context context) {
    // In this mock example, your ad network requires an activity context, but
    // didn't receive one, making you unable to show the ad.
    if (!(context instanceof Activity)) {
      AdError error = new AdError(1, "Context must be an activity",
          "com.google.ads.mediation.sample");
      callback.onAdFailedToShow(error);
    }

    // This example shows Google SDK's callbacks, but it's likely your SDK
    // has similar presentation callbacks.
    rewardedAd.setFullScreenContentCallback(new FullScreenContentCallback() {
      @Override
      public void onAdShowedFullScreenContent() {
        // Your ad network SDK successfully showed the ad. Call onAdOpened().
        callback.onAdOpened();
      }

      @Override
      public void onAdFailedToShowFullScreenContent(AdError adError) {
        // Your ad network SDK failed to show the ad, invoke onAdFailedToShow.
        // In practice, you will map your SDK's error to an AdError.
        AdError error = new AdError(adError.getCode(), adError.getMessage(),
            adError.getDomain());
        callback.onAdFailedToShow(adError);
      }
    });


    rewardedAd.show((Activity) context, ...);
  }
}