始める

Google の EU ユーザーの同意ポリシーに基づき、欧州経済領域(EEA)および英国のユーザーに対して特定の開示を行い、法的に義務付けられている場合に Cookie などのローカル ストレージを使用すること、および広告配信に個人データ(AdID など)を使用することについて同意を得る必要があります。このポリシーには、EU の e プライバシー指令と一般データ保護規則(GDPR)の要件が反映されています。

パブリッシャー様がこのポリシーで定められた義務を遂行できるよう、Google は User Messaging Platform(UMP)SDK を提供しています。UMP SDK は、最新の IAB 標準をサポートするように更新されました。これらの構成はすべて、[プライバシーとメッセージ] で Ad Manager 簡単に処理できます。

前提条件

  • Android API レベル 21 以上

メッセージ タイプを作成する

アド マネージャーアカウントの [プライバシーとメッセージ] タブで、 利用可能なユーザー メッセージ のいずれかでユーザー メッセージを作成します。UMP SDK は、プロジェクトで設定された Ad Manager アプリケーション ID から作成されたユーザー メッセージを表示しようとします。アプリケーションにメッセージが構成されていない場合、SDK はエラーを返します。

詳しくは、 プライバシーとメッセージについて

Gradle を使用してインストールする

Google User Messaging Platform SDK の依存関係をモジュールのアプリレベルの Gradle ファイル(通常は app/build.gradle)に追加します。

dependencies {
  implementation("com.google.android.ump:user-messaging-platform:2.2.0")
}

アプリの build.gradle に変更を加えたら、必ずプロジェクトを Gradle ファイルと同期してください。

requestConsentInfoUpdate()を使用して、アプリが起動されるたびにユーザーの同意情報の更新をリクエストする必要があります。これにより、ユーザーがまだ同意していない場合や、同意の有効期限が切れている場合に、ユーザーが同意する必要があるかどうかが決まります。

onCreate() メソッドの MainActivity からステータスを確認する例を次に示します。

Java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import com.google.android.ump.ConsentInformation;
import com.google.android.ump.ConsentRequestParameters;
import com.google.android.ump.FormError;
import com.google.android.ump.UserMessagingPlatform;

public class MainActivity extends AppCompatActivity {
  private ConsentInformation consentInformation;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Create a ConsentRequestParameters object.
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .build();

    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        (OnConsentInfoUpdateSuccessListener) () -> {
          // TODO: Load and show the consent form.
        },
        (OnConsentInfoUpdateFailureListener) requestConsentError -> {
          // Consent gathering failed.
          Log.w(TAG, String.format("%s: %s",
              requestConsentError.getErrorCode(),
              requestConsentError.getMessage()));
        });
  }
}

Kotlin

package com.example.myapplication

import com.google.android.ump.ConsentInformation
import com.google.android.ump.ConsentInformation.OnConsentInfoUpdateFailureListener
import com.google.android.ump.ConsentInformation.OnConsentInfoUpdateSuccessListener
import com.google.android.ump.ConsentRequestParameters
import com.google.android.ump.UserMessagingPlatform

class MainActivity : AppCompatActivity() {
  private lateinit var consentInformation: ConsentInformation

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Create a ConsentRequestParameters object.
    val params = ConsentRequestParameters
        .Builder()
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ConsentInformation.OnConsentInfoUpdateSuccessListener {
          // TODO: Load and show the consent form.
        },
        ConsentInformation.OnConsentInfoUpdateFailureListener {
          requestConsentError ->
          // Consent gathering failed.
          Log.w(TAG, "${requestConsentError.errorCode}: ${requestConsentError.message}")
        })
  }
}

必要に応じて同意フォームを読み込んで表示する

最新の同意ステータスを取得したら、ConsentForm クラスのloadAndShowConsentFormIfRequired() を呼び出して同意フォームを読み込みます。同意ステータスが必要な場合は、SDK によってフォームが読み込まれ、 指定された activityからすぐに表示されます。 callback は、 フォームが閉じられると呼び出されます。同意が必要ない場合は、直ちに callback が 呼び出されます。

Java

public class MainActivity extends AppCompatActivity {
  private ConsentInformation consentInformation;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Create a ConsentRequestParameters object.
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .build();

    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        (OnConsentInfoUpdateSuccessListener) () -> {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this,
            (OnConsentFormDismissedListener) loadAndShowError -> {
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, String.format("%s: %s",
                    loadAndShowError.getErrorCode(),
                    loadAndShowError.getMessage()));
              }

              // Consent has been gathered.
            }
          );
        },
        (OnConsentInfoUpdateFailureListener) requestConsentError -> {
          // Consent gathering failed.
          Log.w(TAG, String.format("%s: %s",
              requestConsentError.getErrorCode(),
              requestConsentError.getMessage()));
        });
  }
}

Kotlin

class MainActivity : AppCompatActivity() {
  private lateinit var consentInformation: ConsentInformation

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Create a ConsentRequestParameters object.
    val params = ConsentRequestParameters
        .Builder()
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ConsentInformation.OnConsentInfoUpdateSuccessListener {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this@MainActivity,
            ConsentForm.OnConsentFormDismissedListener {
              loadAndShowError ->
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, "${loadAndShowError.errorCode}: ${loadAndShowError.message}")
              }

              // Consent has been gathered.
            }
          )
        },
        ConsentInformation.OnConsentInfoUpdateFailureListener {
          requestConsentError ->
          // Consent gathering failed.
          Log.w(TAG, "${requestConsentError.errorCode}: ${requestConsentError.message}")
        })
  }
}

ユーザーが選択またはフォームを閉じた後でアクションを実行する必要がある場合は、そのロジックをフォームの callbackに配置します。

広告をリクエスト

アプリで広告をリクエストする前に、 canRequestAds()を使用してユーザーから同意を得ているかどうかを確認してください。同意を取得する際には、次の 2 つの場所を確認します。

  1. 現在のセッションで同意が得られたら、
  2. requestConsentInfoUpdate()を呼び出した直後。前回のセッションで同意を取得した可能性があります。レイテンシに関するベスト プラクティスとして、コールバックの完了を待たずに、アプリの起動後できるだけ早く広告の読み込みを開始できるようにすることをおすすめします。

同意取得プロセス中にエラーが発生した場合でも、広告のリクエストを試みる必要があります。UMP SDK は前回のセッションの同意ステータスを使用します。

Java

public class MainActivity extends AppCompatActivity {
  private ConsentInformation consentInformation;
  // Use an atomic boolean to initialize the Google Mobile Ads SDK and load ads once.
  private final AtomicBoolean isMobileAdsInitializeCalled = new AtomicBoolean(false);
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Create a ConsentRequestParameters object.
    ConsentRequestParameters params = new ConsentRequestParameters
        .Builder()
        .build();

    consentInformation = UserMessagingPlatform.getConsentInformation(this);
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        (OnConsentInfoUpdateSuccessListener) () -> {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this,
            (OnConsentFormDismissedListener) loadAndShowError -> {
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, String.format("%s: %s",
                    loadAndShowError.getErrorCode(),
                    loadAndShowError.getMessage()));
              }

              // Consent has been gathered.
              if (consentInformation.canRequestAds()) {
                initializeMobileAdsSdk();
              }
            }
          );
        },
        (OnConsentInfoUpdateFailureListener) requestConsentError -> {
          // Consent gathering failed.
          Log.w(TAG, String.format("%s: %s",
              requestConsentError.getErrorCode(),
              requestConsentError.getMessage()));
        });
    
    // Check if you can initialize the Google Mobile Ads SDK in parallel
    // while checking for new consent information. Consent obtained in
    // the previous session can be used to request ads.
    if (consentInformation.canRequestAds()) {
      initializeMobileAdsSdk();
    }
  }
  
  private void initializeMobileAdsSdk() {
    if (isMobileAdsInitializeCalled.getAndSet(true)) {
      return;
    }

    new Thread(
            () -> {
              // Initialize the Google Mobile Ads SDK on a background thread.
              MobileAds.initialize(this, initializationStatus -> {});
              runOnUiThread(
                  () -> {
                    // TODO: Request an ad.
                    // InterstitialAd.load(...);
                  });
            })
        .start();
  }
}

Kotlin

class MainActivity : AppCompatActivity() {
  private lateinit var consentInformation: ConsentInformation
  // Use an atomic boolean to initialize the Google Mobile Ads SDK and load ads once.
  private var isMobileAdsInitializeCalled = AtomicBoolean(false)
  
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Create a ConsentRequestParameters object.
    val params = ConsentRequestParameters
        .Builder()
        .build()

    consentInformation = UserMessagingPlatform.getConsentInformation(this)
    consentInformation.requestConsentInfoUpdate(
        this,
        params,
        ConsentInformation.OnConsentInfoUpdateSuccessListener {
          UserMessagingPlatform.loadAndShowConsentFormIfRequired(
            this@MainActivity,
            ConsentForm.OnConsentFormDismissedListener {
              loadAndShowError ->
              if (loadAndShowError != null) {
                // Consent gathering failed.
                Log.w(TAG, "${loadAndShowError.errorCode}: ${loadAndShowError.message}")
              }

              // Consent has been gathered.
              if (consentInformation.canRequestAds()) {
                initializeMobileAdsSdk()
              }
            }
          )
        },
        ConsentInformation.OnConsentInfoUpdateFailureListener {
          requestConsentError ->
          // Consent gathering failed.
          Log.w(TAG, "${requestConsentError.errorCode}: ${requestConsentError.message}")
        })
    
    // Check if you can initialize the Google Mobile Ads SDK in parallel
    // while checking for new consent information. Consent obtained in
    // the previous session can be used to request ads.
    if (consentInformation.canRequestAds()) {
      initializeMobileAdsSdk()
    }
  }
  
  private fun initializeMobileAdsSdk() {
    if (isMobileAdsInitializeCalled.getAndSet(true)) {
      return
    }

    val backgroundScope = CoroutineScope(Dispatchers.IO)
    backgroundScope.launch {
      // Initialize the Google Mobile Ads SDK on a background thread.
      MobileAds.initialize(this@MainActivity) {}
      // TODO: Request an ad.
      // InterstitialAd.load(...)
    }
  }
}

プライバシー設定

一部の同意フォームでは、ユーザーがいつでも同意を変更する必要があります。必要に応じて、次の手順に沿ってプライバシー オプション ボタンを実装してください。

手順は次のとおりです。

  1. アプリの設定ページのボタンなど、プライバシー オプション フォームをトリガーする UI 要素を実装します。
  2. loadAndShowConsentFormIfRequired() が完了したら、privacyOptionsRequirementStatus() を確認して、プライバシー オプション フォームを表示できる UI 要素を表示するかどうかを決定します。
  3. ユーザーが UI 要素を操作したら、showPrivacyOptionsForm() を呼び出してフォームを表示し、ユーザーがいつでもプライバシー オプションを更新できるようにします。

次の例は、MenuItem からのプライバシー オプション フォームを提示する方法を示しています。

Java

private final ConsentInformation consentInformation;

// Show a privacy options button if required.
public boolean isPrivacyOptionsRequired() {
  return consentInformation.getPrivacyOptionsRequirementStatus()
      == PrivacyOptionsRequirementStatus.REQUIRED;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
  // ...

  consentInformation = UserMessagingPlatform.getConsentInformation(this);
  consentInformation.requestConsentInfoUpdate(
      this,
      params,
      (OnConsentInfoUpdateSuccessListener) () -> {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(
          this,
          (OnConsentFormDismissedListener) loadAndShowError -> {
            // ...

            // Consent has been gathered.

            if (isPrivacyOptionsRequired()) {
              // Regenerate the options menu to include a privacy setting.
              invalidateOptionsMenu();
            }
          }
        )
      }
      // ...
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
  getMenuInflater().inflate(R.menu.action_menu, menu);
  MenuItem moreMenu = menu.findItem(R.id.action_more);
  moreMenu.setVisible(isPrivacyOptionsRequired());
  return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
  // ...

  popup.setOnMenuItemClickListener(
      popupMenuItem -> {
        if (popupMenuItem.getItemId() == R.id.privacy_settings) {
          // Present the privacy options form when a user interacts with
          // the privacy settings button.
          UserMessagingPlatform.showPrivacyOptionsForm(
              this,
              formError -> {
                if (formError != null) {
                  // Handle the error.
                }
              }
          );
          return true;
        }
        return false;
      });
  return super.onOptionsItemSelected(item);
}

Kotlin

private val consentInformation: ConsentInformation =
  UserMessagingPlatform.getConsentInformation(context)

// Show a privacy options button if required.
val isPrivacyOptionsRequired: Boolean
  get() =
    consentInformation.privacyOptionsRequirementStatus ==
      ConsentInformation.PrivacyOptionsRequirementStatus.REQUIRED

override fun onCreate(savedInstanceState: Bundle?) {
  ...
  consentInformation = UserMessagingPlatform.getConsentInformation(this)
  consentInformation.requestConsentInfoUpdate(
      this,
      params,
      ConsentInformation.OnConsentInfoUpdateSuccessListener {
        UserMessagingPlatform.loadAndShowConsentFormIfRequired(
          this@MainActivity,
          ConsentForm.OnConsentFormDismissedListener {
            // ...

            // Consent has been gathered.

            if (isPrivacyOptionsRequired) {
              // Regenerate the options menu to include a privacy setting.
              invalidateOptionsMenu();
            }
          }
        )
      }
      // ...
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
  menuInflater.inflate(R.menu.action_menu, menu)
  menu?.findItem(R.id.action_more)?.apply {
    isVisible = isPrivacyOptionsRequired
  }
  return super.onCreateOptionsMenu(menu)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
  // ...

  popup.setOnMenuItemClickListener { popupMenuItem ->
    when (popupMenuItem.itemId) {
      R.id.privacy_settings -> {
        // Present the privacy options form when a user interacts with
        // the privacy settings button.
        UserMessagingPlatform.showPrivacyOptionsForm(this) { formError ->
          formError?.let {
            // Handle the error.
          }
        }
        true
      }
      else -> false
    }
  }
  return super.onOptionsItemSelected(item)
}

テスト

開発中にアプリで統合をテストする場合は、次の手順に沿ってテストデバイスをプログラムに登録します。アプリをリリースする前に、これらのテストデバイス ID を設定するコードを必ず削除してください。

  1. requestConsentInfoUpdate()を呼び出します。
  2. ログ出力で、次の例のようなメッセージを確認します。このメッセージには、デバイス ID と、テストデバイスとして追加する方法が示されています。

    Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231") to set this as a debug device.
    
  3. テストデバイス ID をクリップボードにコピーします。

  4. コードを変更して、 呼び出しDebugGeography.TestDeviceHashedIds を設定し、 テストデバイス ID のリストを渡します。

地域を強制的に適用する

UMP SDK では、 the setDebugGeography method which takes a DebugGeography on ConsentDebugSettings.Builderを使用して、デバイスが EEA または英国にあるかのようにアプリの動作をテストできます。デバッグ設定はテストデバイスでのみ機能します。

Java

ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
    .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
    .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
    .build();

ConsentRequestParameters params = new ConsentRequestParameters
    .Builder()
    .setConsentDebugSettings(debugSettings)
    .build();

consentInformation = UserMessagingPlatform.getConsentInformation(this);
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
    this,
    params,
    ...
);

Kotlin

val debugSettings = ConsentDebugSettings.Builder(this)
    .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
    .addTestDeviceHashedId("TEST-DEVICE-HASHED-ID")
    .build()

val params = ConsentRequestParameters
    .Builder()
    .setConsentDebugSettings(debugSettings)
    .build()

consentInformation = UserMessagingPlatform.getConsentInformation(this)
// Include the ConsentRequestParameters in your consent request.
consentInformation.requestConsentInfoUpdate(
    this,
    params,
    ...
)

UMP SDK でアプリをテストする場合は、SDK の状態をリセットして、ユーザーの最初のインストール エクスペリエンスをシミュレートすると便利です。SDK には、これを行うための reset() メソッドが用意されています。

Java

consentInformation.reset();

Kotlin

consentInformation.reset()

GitHub の例

UMP SDK の統合例: Java | Kotlin