구현 예시

Ad Placement API는 웹 또는 앱의 HTML5 게임에 전면 광고와 보상형 광고를 게재하는 애드센스 및 AdMob 개발자를 지원하도록 설계되었습니다. 이 예에서는 Ad Placement API를 게임에 통합하고 이를 사용하여 전면 광고를 게재하는 방법을 알아봅니다.

기본 요건

시작하기 전에 다음 사항이 필요합니다.

  • 같은 디렉터리에 빈 파일 두 개를 만듭니다.
    • index.html
    • game.js
  • Python을 로컬 환경에 설치하거나 웹 서버를 사용하여 구현을 테스트합니다.

앱 샘플 코드

AdMob 게시자의 경우 샘플 앱 코드를 다운로드하면 API를 앱 게임에 통합하는 방법을 더 잘 이해할 수 있습니다.

앱 샘플 코드 다운로드

1. 개발 서버 시작하기

Ad Placement API는 로드되는 페이지와 동일한 프로토콜을 통해 종속 항목을 로드하므로 웹 서버를 사용하여 앱을 테스트해야 합니다. Python의 기본 제공 서버를 사용하여 로컬 개발 환경을 만들 수 있습니다.

  1. 터미널을 엽니다.

  2. index.html 파일이 있는 디렉터리로 이동한 후 다음을 실행합니다.

    python -m http.server 8000
    
  3. 웹브라우저에서 localhost:8000으로 이동합니다.

Apache HTTP 서버와 같은 기타 웹 서버도 사용할 수 있습니다.

2. HTML5 게임 만들기

index.html을 수정하여 HTML5 캔버스 요소 및 게임플레이를 트리거하는 버튼을 만듭니다. 그런 다음 필요한 스크립트 태그를 추가하여 game.js 파일을 로드합니다.

index.html

<!doctype html>
<html lang="en">
  <head>
    <title>Ad Placement API HTML5 demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>

    <script src="game.js"></script>
  </body>
</html>

'재생' 버튼을 클릭하여 동전 던지기 게임을 즐길 수 있도록 game.js를 수정합니다.

game.js

// Create a coin flip game
class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';

    this.canvas = document.getElementById('gameContainer').getContext('2d');
    this.canvas.font = '24px Arial';

    this.playButton = document.getElementById('playButton');
    this.headsButton = document.getElementById('headsButton');
    this.tailsButton = document.getElementById('tailsButton');

    // On click listeners for the game's buttons.
    this.playButton.addEventListener('click', () => {
      this.erase();
      this.play();
    });

    this.headsButton.addEventListener('click', () => {
      this.choice = 'Heads';
      this.flipCoin();
    });

    this.tailsButton.addEventListener('click', () => {
      this.choice = 'Tails';
      this.flipCoin();
    });

    this.erase();
  }

  // Start the game
  play() {
    this.score = 0;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none';
    this.headsButton.style.display = 'inline-block';
    this.tailsButton.style.display = 'inline-block';
  }

  // Flip the coin
  flipCoin() {
    this.headsButton.disabled = true;
    this.tailsButton.disabled = true;
    this.erase();
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Flipping coin . . .', 60, 150);

    setTimeout(() => { this.coinLanded() }, 2000);
  }

  // Logic for when the coin lands
  coinLanded() {
    this.headsButton.disabled = false;
    this.tailsButton.disabled = false;
    let sideUp;
    if(Math.random() < 0.5) {
      sideUp = 'Heads';
    } else {
      sideUp = 'Tails';
    }

    if (sideUp === this.choice ) {
      this.win(sideUp);
    } else {
      this.lose(sideUp);
    }
  }

  // Guess the flip correctly
  win(sideUp) {
    this.erase();
    this.score += 1;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('It was ' + sideUp + '!', 66, 150);
    this.canvas.fillText('Guess again', 70, 200);
  }

  // Guess the flip incorrectly
  lose(sideUp) {
    this.erase();
    this.canvas.fillText('Sorry, it was ' + sideUp, 50, 100);
    this.canvas.fillText('Your score was ' + this.score, 50, 150);
    this.canvas.fillText('Want to play again?', 45, 200);

    this.playButton.style.display = 'inline-block';
    this.headsButton.style.display = 'none';
    this.tailsButton.style.display = 'none';
  }

  // Erase the canvas
  erase() {
    this.canvas.fillStyle = '#ADD8E6';
    this.canvas.fillRect(0, 0, 300, 300);
    this.canvas.fillStyle = '#000000';
  }
}

const game = new Game();

이 단계를 완료하면 브라우저에서 index.html을 열 때(개발 서버를 통해) 게임 캔버스와 '재생' 버튼이 표시됩니다. 재생을 클릭하면 동전 던지기 게임이 시작됩니다.

3. Ad Placement API 가져오기

다음으로 game.js의 태그 앞 index.html에 스크립트 태그를 삽입해 게임에 Ad Placement API를 추가합니다.

스크립트 태그는 여러 매개변수를 사용할 수 있습니다. 다음 매개변수를 사용하여 애드센스 속성 코드를 지정하고 테스트 모드를 사용 설정합니다.

  • data-ad-client=<AdSense property code> 애드센스 속성 코드입니다. 이는 앱 내에서 실행되는 게임에서도 항상 필요합니다.
  • data-adbreak-test="on" 테스트 모드를 사용 설정합니다. 플레이어에게 제시된 후에는 게임에서 이 속성을 삭제하세요.

애드센스 코드 설정 및 테스트 모드 사용 설정하기

Ad Placement API 기능은 애드센스 코드에 포함되어 있습니다. 이 기능을 사용하려면 먼저 애드센스 코드를 추가하고 두 가지 주요 함수, 즉 adBreak()adConfig()를 초기화하는 작은 스크립트 스니펫을 포함해야 합니다.

index.html(웹)

 [...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>

    <script async
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-123456789"
      crossorigin="anonymous">
    </script>
    <script>
      window.adsbygoogle = window.adsbygoogle || [];
      const adBreak = adConfig = function(o) {adsbygoogle.push(o);}
    </script>
    <script src="game.js"></script>
  </body>
</html>

게임 삽입(선택사항)

iframe 내부의 다른 페이지에 게임을 삽입하려 하고 adsbygoogle 태그가 게임의 HTML 페이지에 있는 경우 iframe 요소에 allow='autoplay'를 추가해야 합니다. 이는 특정 광고를 게임에 게재하는 데 필요한 권장사항입니다.

<head>
  <!-- The adsbygoogle tag is not here -->
</head>
<body>
  <iframe src="https://www.my-game.com" title="My game" allow="autoplay">
    <!-- The game is loaded here and contains the adsbygoogle tag -->
  </iframe>
</body>

모바일 앱 지원

H5 게임은 일반 웹브라우저, WebView, 또는 앱 내의 Chrome 맞춤 탭에서 실행할 수 있습니다. Ad Placement API는 게임이 실행 중인 환경을 감지하고 광고 요청을 적절하게 전달할 수 있습니다. 게임이 일반 웹브라우저에서 실행되는 경우 광고 요청은 일반적인 애드센스 요청으로 간주됩니다. Ad Placement API는 인앱 환경을 감지하면 Google 모바일 광고 SDK(있는 경우)와 통신하여 AdMob 광고를 요청하고 표시합니다.

이 기능은 Google 모바일 광고 SDK에 연결된 Android 앱에서 지원됩니다. 이 기능을 사용 설정하려면 Google 모바일 광고 SDK로 게임을 표시할 WebView를 등록한 다음 AdMob 광고 단위를 구성하고 이를 애드센스 태그에 추가 매개변수로 전달해야 합니다. 게임이 적절한 앱 내에서 실행되면 Ad Placement API가 이러한 광고 단위를 사용하여 광고를 표시합니다.

모바일 지원을 사용 설정하려면 다음과 같은 추가 태그 매개변수를 지정해야 합니다.

  • data-admob-interstitial-slot=<AdMob slot ID> 이전에 구성한 AdMob 전면 광고 단위 ID입니다.
  • data-admob-rewarded-slot=<AdMob slot ID> AdMob 보상형 광고 단위 ID입니다.

애드센스 속성 코드는 항상 data-ad-client 매개변수를 통해 전달되어야 하며, data-admob-interstitial-slot 또는 data-admob-rewarded-slot 중 하나 이상을 지정해야 합니다. 게임에서 두 형식을 모두 사용하는 경우 두 매개변수를 모두 지정해야 합니다.

선택적으로 data-admob-ads-only=on 태그 매개변수를 지정하여 게임에서 AdMob의 광고만 표시하고 AdMob 요청을 지원하지 않는 환경(예: 앱 이외의 환경 또는 Google 모바일 광고 SDK가 구성되지 않은 앱)에서 게임이 플레이되는 경우 애드센스로 대체하지 않아야 함을 나타낼 수도 있습니다.

중요: 게임이 앱 내에 삽입되도록 설계하고자 할 때 앱을 소유하고 있거나 앱 소유자와 수익 배분 계약을 체결할 때 정책을 준수하면서 실적을 높일 수 있는 유일한 방법은 이 AdMob 지원을 사용하는 것입니다.

먼저 Google 모바일 광고 SDK로 게임을 보여 주는 WebView를 등록합니다.

MainActivity.java(앱)

Default WebView settings are not optimized for ads. Use the WebSettings APIs to configure your WebView for:

  • JavaScript
  • Access to local storage
  • Automatic video play

Java

import android.webkit.CookieManager;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {
  private WebView webView;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    webView = findViewById(R.id.webview);

    // Let the web view accept third-party cookies.
    CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true);
    // Let the web view use JavaScript.
    webView.getSettings().setJavaScriptEnabled(true);
    // Let the web view access local storage.
    webView.getSettings().setDomStorageEnabled(true);
    // Let HTML videos play automatically.
    webView.getSettings().setMediaPlaybackRequiresUserGesture(false);

    // Set the H5AdsWebViewClient.
    h5AdsWebViewClient = new H5AdsWebViewClient(this, webView);
    webView.setWebViewClient(h5AdsWebViewClient);
    h5AdsWebViewClient.setDelegateWebViewClient(pubWebViewClient);

    // Register the web view.
    MobileAds.registerWebView(webView);
  }
}

Kotlin

import android.webkit.CookieManager
import android.webkit.WebView

class MainActivity : AppCompatActivity() {
  lateinit var webView: WebView

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    webView = findViewById(R.id.webview)

    // Let the web view accept third-party cookies.
    CookieManager.getInstance().setAcceptThirdPartyCookies(webView, true)
    // Let the web view use JavaScript.
    webView.settings.javaScriptEnabled = true
    // Let the web view access local storage.
    webView.settings.domStorageEnabled = true
    // Let HTML videos play automatically.
    webView.settings.mediaPlaybackRequiresUserGesture = false

    // Set the H5AdsWebViewClient.
    val h5AdsWebViewClient = H5AdsWebViewClient(this, webView)
    webView.webViewClient = h5AdsWebViewClient
    h5AdsWebViewClient.delegateWebViewClient = pubWebViewClient

    // Register the web view.
    MobileAds.registerWebView(webView)
  }
}

그런 다음 아래와 같이 AdMob 광고 단위(전면 광고용 1개와 보상형 광고용 1개)를 전달합니다.

index.html(앱)

 [...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>
    <script async
      data-admob-interstitial-slot="ca-app-pub-0987654321/1234567890"
      data-admob-rewarded-slot="ca-app-pub-0987654321/0987654321"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-123456789"
      crossorigin="anonymous">
    </script>
    <script>
      window.adsbygoogle = window.adsbygoogle || [];
      const adBreak = adConfig = function(o) {adsbygoogle.push(o);}
    </script>
    <script src="game.js"></script>
  </body>
</html>

4. adConfig() 호출하기

adConfig() 호출은 게임의 현재 구성을 Ad Placement API에 전달합니다. 이후 API는 이러한 정보를 사용하여 요청하는 광고 유형을 게임에 적합하도록 필터링합니다(예: 사운드가 사용 설정된 경우 사운드가 필요한 동영상 광고로 필터링).

언제든지 구성이 변경되면 (예: 사용자가 게임을 음소거하거나 음소거를 해제하는 경우) adConfig()가 호출됩니다. 게임의 생성자에서 adConfig()를 호출한 다음, 게임에 음소거 및 음소거 해제 버튼을 추가하여 추가적으로 adConfig()를 호출하도록 합니다.

game.js

class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';
    this.muted = false;

    this.canvas = document.getElementById('gameContainer').getContext('2d');
    this.canvas.font = '24px Arial';

    this.playButton = document.getElementById('playButton');
    this.headsButton = document.getElementById('headsButton');
    this.tailsButton = document.getElementById('tailsButton');
    this.muteButton = document.getElementById('muteButton');

    adConfig({
      sound: 'on',
    });

    // On click listeners for the game's buttons.
    this.playButton.addEventListener('click', () => {
      this.erase();
      this.play();
    });

    this.headsButton.addEventListener('click', () => {
      this.choice = 'Heads';
      this.flipCoin();
    });

    this.tailsButton.addEventListener('click', () => {
      this.choice = 'Tails';
      this.flipCoin();
    });

    this.muteButton.addEventListener('click', () => {
      var soundString = this.muted ? 'on' : 'off';
      this.muteButton.innerHTML = this.muted ? 'Mute sound' : 'Un-mute sound';
      this.muted = !this.muted;
      adConfig({
        sound: soundString,
      });
    });

    this.erase();
  [...]

이제 HTML 파일에 음소거 버튼을 추가합니다.

index.html

[...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>
    <button id="muteButton">Mute sound</button>

    <script async
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-123456789"
      crossorigin="anonymous">
    </script>
[...]

5. 게임 종료 시 adBreak() 호출하기

adBreak() 호출은 광고 게재위치를 정의하며, 게임의 해당 지점에서 광고를 게재하는 데 필요한 모든 것을 지정하는 게재위치 구성이라는 객체를 취합니다. 다양한 유형의 광고를 지원하려면 게재위치 구성의 여러 하위 집합을 초기화해야 합니다.

adBreak() 호출은 광고를 게재할 수 있는 위치인 게재위치, 즉 광고를 게재할 수 있는 기회를 정의합니다. 광고가 실제로 표시되는지 여부는 다음과 같은 여러 요인에 따라 결정됩니다.

  • 선언한 광고 게재위치의 유형
  • 광고 게재위치 이전에 적절한 사용자 상호작용이 발생했는지 여부
  • 현재 플레이어에게 적합한 광고가 있는지 여부. 예를 들어
    • 플레이어에게 관련성이 있는 광고
    • 플레이어의 데이터 개인 정보 보호 및 동의 설정과 일치하는 광고
  • 사용자가 최근에 본 광고의 개수
  • 다음 형태 중 하나로 게임에 대해 구성한 컨트롤 설정
    • 태그 내 힌트
    • 애드센스 내(참고: 애드센스에서 사용할 수 있는 컨트롤은 시간이 지남에 따라 변경됨)

게임을 다시 시작할 때 표시할 전면 광고에 대한 코드를 추가합니다. 게임이 한 번 실행된 후에만 play() 함수 내에서 adBreak()를 호출합니다.

adBreak()는 사용자 작업(예: '재생' 버튼 클릭) 중 일부로 호출되어야 합니다. 그렇지 않으면 API에서 광고를 요청하고 표시할 수 없습니다.

광고 시점 전후에 호출할 함수를 만들어 adBreak() 게재위치 구성에서 사용합니다. beforeAdafterAd 함수는 적합한 광고가 있는 경우에만 호출된다는 점을 잊지 마세요.

game.js

class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';
    this.muted = false;
    this.shouldShowAdOnPlay = false;

  [...]

  // Start the game
  play() {
    if (this.shouldShowAdOnPlay) {
      this.shouldShowAdOnPlay = false;

      adBreak({
        type: 'next',  // ad shows at start of next level
        name: 'restart-game',
        beforeAd: () => { this.disableButtons(); },  // You may also want to mute the game's sound.
        afterAd: () => { this.enableButtons(); },    // resume the game flow.
      });
    }

    this.score = 0;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none'
    this.headsButton.style.display = 'inline-block'
    this.tailsButton.style.display = 'inline-block'
  }

  [...]

  // Guess the flip incorrectly
  lose(sideUp) {
    this.erase()
    this.canvas.fillText('Sorry, it was ' + sideUp, 50, 100);
    this.canvas.fillText('Your score was ' + this.score, 50, 150);
    this.canvas.fillText('Want to play again?', 45, 200);

    this.playButton.style.display = 'inline-block'
    this.headsButton.style.display = 'none'
    this.tailsButton.style.display = 'none'
    this.shouldShowAdOnPlay = true;
  }

  [...]

  // Erase the canvas
  erase() {
    this.canvas.fillStyle = '#ADD8E6';
    this.canvas.fillRect(0, 0, 300, 300);
    this.canvas.fillStyle = '#000000';
  }

  enableButtons() {
    this.playButton.disabled = false;
    this.headsButton.disabled = false;
    this.tailsButton.disabled = false;
  }

  disableButtons() {
    this.playButton.disabled = true;
    this.headsButton.disabled = true;
    this.tailsButton.disabled = true;
  }
}

const game = new Game();

6. 보상형 광고의 adBreak() 호출하기

게임이 종료되지만 사용자가 새로 시작하는 대신 기존 점수를 다시 살리고자 할 때 표시될 보상형 광고의 코드를 추가합니다. lose() 함수 내에서 adBreak()를 호출하여 보상형 광고를 사용할 수 있는지 확인합니다. 사용할 수 있으면 사용자에게 리워드(이 경우 부활)를 원하는지 묻는 프롬프트를 표시하고, 사용자가 광고를 보는 데 동의할 경우 해당하는 showAdFn()을 호출합니다. adViewedadDismissed 콜백을 사용하여 사용자가 보상형 광고를 보거나 건너뛰는 경우 필요한 조치를 구성할 수 있습니다.

보상형 광고를 표시할 때마다 adBreak()를 새로 호출해야 합니다. 이렇게 하면 이전 광고가 만료되거나 이전 광고를 사용할 수 없는 경우 광고가 새로고침됩니다.

광고를 보려면 showAdFn()을 직접 사용자 작업의 일부로 호출해야 하며 그렇지 않으면 광고가 표시되지 않을 수도 있습니다.

광고 시점 전후에 호출할 함수를 만들어 adBreak() 게재위치 구성에서 사용합니다. beforeReward, adViewed, adDismissed, beforeAdafterAd 함수는 적합한 광고가 있는 경우에만 호출된다는 점을 잊지 마세요.

game.js

class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';
    this.muted = false;
    this.shouldShowAdOnPlay = false;
    this.showRewardedAdFn = null;

    this.canvas = document.getElementById('gameContainer').getContext('2d');
    this.canvas.font = '24px Arial';

    this.playButton = document.getElementById('playButton');
    this.headsButton = document.getElementById('headsButton');
    this.tailsButton = document.getElementById('tailsButton');
    this.muteButton = document.getElementById('muteButton');
    this.continueButton = document.getElementById('continueButton');

    adConfig({
      sound: 'on',
    });

    // On click listeners for the game's buttons.
    this.playButton.addEventListener('click', () => {
      this.erase();
      this.play();
    });

    this.headsButton.addEventListener('click', () => {
      this.choice = 'Heads';
      this.flipCoin();
    });

    this.tailsButton.addEventListener('click', () => {
      this.choice = 'Tails';
      this.flipCoin();
    });

    this.muteButton.addEventListener('click', () => {
      var soundString = this.muted ? 'on' : 'off';
      this.muteButton.innerHTML = this.muted ? 'Mute sound' : 'Un-mute sound';
      this.muted = !this.muted;
      adConfig({
        sound: soundString,
      });
    });

    this.continueButton.addEventListener('click', () => {
      if (this.showRewardedAdFn) {
        this.showRewardedAdFn();
      }
    });

    this.erase();
  }

  // Start the game
  play() {
    if (this.shouldShowAdOnPlay) {
      this.shouldShowAdOnPlay = false;

      adBreak({
        type: 'next',  // ad shows at start of next level
        name: 'restart-game',
        beforeAd: () => { this.disableButtons(); },  // You may also want to mute the game's sound.
        afterAd: () => { this.enableButtons(); },    // resume the game flow.
      });
    }

    this.score = 0;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none';
    this.continueButton.style.display = 'none';
    this.headsButton.style.display = 'inline-block';
    this.tailsButton.style.display = 'inline-block';
  }

  [...]

  // Guess the flip incorrectly
  lose(sideUp) {
    this.erase()
    this.canvas.fillText('Sorry, it was ' + sideUp, 50, 100);
    this.canvas.fillText('Your score was ' + this.score, 50, 150);
    this.canvas.fillText('Want to play again?', 45, 200);

    this.playButton.style.display = 'inline-block'
    this.headsButton.style.display = 'none'
    this.tailsButton.style.display = 'none'
    this.shouldShowAdOnPlay = true;

    adBreak({
      type: 'reward',  // rewarded ad
      name: 'reward-continue',
      beforeReward: (showAdFn) => {
        this.showRewardedAdFn = () => { showAdFn(); };
        // Rewarded ad available - prompt user for a rewarded ad
        this.continueButton.style.display = 'inline-block';
      },
      beforeAd: () => { this.disableButtons(); },     // You may also want to mute the game's sound.
      adDismissed: () => {
        this.continueButton.style.display = 'none';   // Hide the reward button and continue lose flow.
      },
      adViewed: () => { this.continueGame(); },       // Reward granted - continue game at current score.
      afterAd: () => { this.enableButtons(); },       // Resume the game flow.
    });
  }

  // Continue gameplay at current score
  continueGame() {
    this.erase();
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none';
    this.continueButton.style.display = 'none';
    this.headsButton.style.display = 'inline-block';
    this.tailsButton.style.display = 'inline-block';
  }
  [...]
}

const game = new Game();

이제 HTML 파일에 계속 버튼을 추가합니다.

index.html

[...]
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <br>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>
    <button style="display:none" id="continueButton">Watch Ad to continue?</button>
    <button id="muteButton">Mute sound</button>

    <script async
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-123456789"
      crossorigin="anonymous">
    </script>
[...]

이제 동전 던지기 앱은 광고 게재를 위한 광고 게재위치를 만듭니다.

앱에는 게임이 종료될 때 이외에도 광고를 표시할 적절한 추가 위치가 있을 수 있습니다. 이러한 위치에서 adBreak()를 호출하는 방식도 이 예에 나온 내용과 비슷합니다.

프로덕션 앱 테스트 사용 중지

index.htmldata-adbreak-test="on" 라인은 해당 코드가 프로덕션에서 테스트 설정을 활성화하므로 앱 출시 전에 삭제하거나 주석 처리해야 합니다.