🐱

Admob UMPを実装してみた(Android)

2023/09/29に公開

初めに

admobのホームに以下の赤い情報が出るようになったので、とりあえずUMP SDKを実装して動作を観察することとしました。

「2024年1月16日より、欧州経済領域(EEA)または英国(UK)のユーザーに広告を配信するすべてのパブリッシャー様は、Google の認定を受けた同意管理プラットフォーム(CMP)をご使用いただくことが必要となります。欧州経済領域と英国で広告を配信する際には、Google 独自の同意管理ソリューションを含む Google 認定の CMP をご利用いただけます。」

(私は現時点でEEAとUKに配信してないので直ちには関係なさそうです。
しかし、UMPがどんなものかやその影響等、どうなるのか気になるため、調べてみました。)

実装しない場合どうなるのか(わかりません)

2024年1月16日以降に実装しなかった場合、以下のいずれかでしょうか?
1.全世界に広告が出なくなる。
2.EEAとUK地域には広告が出ない。
3.EEAとUK地域には情報を取得しない設定で広告が表示される。
4.その他
上の中で1ではないと予想しています。
情報お持ちのかたがいれば教えてください。

資料

実装についての公式に資料については以下になります。
◇GDPR に関するアプリ向けメッセージを作成する
https://support.google.com/admob/answer/10113207
◇Google User Messaging Platform SDK をアプリに追加する
https://support.google.com/admob/answer/10113005

実装

この文章では上の資料のメッセージ作成には触れず、下のSDKの資料を参考に実装してみて観察したいと思います。

さて、資料を元に以下のように実装して動作を観察してみました。
言語はkotlinでuser-messaging-platform:2.1.0です。

implementation 'com.google.android.ump:user-messaging-platform:2.1.0'

テスト用に設定をできるようにしました。
テストの際にはyour_device_hashed_idを設定ください。
(ご存知と思いますがadmobを実装していれば実機のログに表示される端末ごとの値です。)

package jp.your.package

import android.app.Activity
import android.util.Log
import com.google.android.gms.ads.MobileAds
import com.google.android.ump.ConsentDebugSettings
import com.google.android.ump.ConsentForm
import com.google.android.ump.ConsentInformation
import com.google.android.ump.ConsentRequestParameters
import com.google.android.ump.UserMessagingPlatform
import java.util.concurrent.atomic.AtomicBoolean

class PrivacyConsent {
    private var TAG = "YourPrivacyConsent"
    private val ForceEEAForTesting = true
//    private val AreaForTesting =  ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_DISABLED
    private val AreaForTesting =  ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA
//  private val AreaForTesting =  ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA
    companion object {
        public lateinit var consentInformation: ConsentInformation
    }
    private var isMobileAdsInitializeCalled = AtomicBoolean(false)
    public var didInitializeAdmob: () -> Unit = {}

    fun start(activity: Activity) {
        // プライバシー同意の処理
        // Set tag for under age of consentのfalseは
	// ユーザが同意年齢以上であることを意味する。
        var params = ConsentRequestParameters
            .Builder()
            .setTagForUnderAgeOfConsent(false)
            .build()

        // EEA地域をエミュレートする場合のデバッグ
        if (ForceEEAForTesting) {
            // テストのため同意をリセットする場合
            // consentInformation.reset()

            val debugSettings = ConsentDebugSettings
		.Builder(activity.applicationContext)
                .setDebugGeography(AreaForTesting)
                .addTestDeviceHashedId("your_device_hashed_id")
                .build()
            params = ConsentRequestParameters.Builder()
                .setConsentDebugSettings(debugSettings)
                .setTagForUnderAgeOfConsent(false)
                .build()
        }

        consentInformation = UserMessagingPlatform
		.getConsentInformation(activity.applicationContext)
        // 同意するための前情報をサーバーから取得
        consentInformation.requestConsentInfoUpdate(
            activity,
            params,
            {
                // 成功。取得した情報を元に必要があれば同意ダイアログを表示
                UserMessagingPlatform.loadAndShowConsentFormIfRequired(
                    activity,
                    ConsentForm.OnConsentFormDismissedListener {
			loadAndShowError ->
                        // Consent gathering failed.
                        if (loadAndShowError != null) {
                            Log.w(TAG, String.format(
				    "loadAndShowConsent failed: %s: %s"
                                    , loadAndShowError.errorCode
                                    , loadAndShowError.message))
                        }
                        initializeMobileAdsSdk(activity)
                    }
                )
            },
            {
                // 失敗。取得できなかった
                requestConsentError ->
                Log.w(TAG, String.format(
                        "requestConsentInfoUpdate failed:%s :%s",
                        requestConsentError.errorCode,
                        requestConsentError.message))
            }
        )
        initializeMobileAdsSdk(activity)
    }

    // admob同意が取れた/取れない場合や必要ない場合にadmobを初期化して、
    // 初期処理didInitializeAdmob()を呼び出す。
    private fun initializeMobileAdsSdk(activity: Activity) {
        // 通信できなかった場合に同意関連の準備が整ってないのでreturn。
        if (!consentInformation.canRequestAds()) {
            return
        }
        // すでに初期化されていたらreturn。
        if (isMobileAdsInitializeCalled.get()) {
            return
        }
        isMobileAdsInitializeCalled.set(true)

        // admob初期化
        MobileAds.initialize(activity.applicationContext)
        didInitializeAdmob()
    }

    // 設定からボタンを押された場合などにプライバシー同意ダイアログを表示する。
    fun showPrivacyOptionForm(activity: Activity) {
        UserMessagingPlatform.showPrivacyOptionsForm(activity) { 
	    formError ->
                formError?.let {
                   // Handle the error.
                }
        }
    }
}

使い方

以下のように呼び出してます。

class MainActivity : AppCompatActivity() {
	private val consent = PrivacyConsent()
	override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityYourBinding.inflate(layoutInflater)
        setContentView(binding.root)

        consent.didInitializeAdmob = {
	    // ここにadmob初期化後の処理を書く。ここではバナーを表示している。
            val adRequest = AdRequest.Builder().build()
            val adView = findViewById<AdView>(R.id.adView)
            adView?.loadAd(adRequest)
        }

        consent.start(this)

}

注意事項

プロジェクトにadmob広告の表示がある場合に全てcanRequestAds()で表示可能かチェックする必要があるので注意が必要です。(チェックしないと同意確認前に広告リクエストをしてしまいます。)

同意変更ボタン

また、上に加えて、必要なユーザが同意を再設定できるように、ボタン(privacyButton)を設けて以下のようにしてました。

consent.didInitializeAdmob = {
            val contentStatus = PrivacyConsent.consentInformation.consentStatus
            // 同意ステータスがNOT_REQUIREDの時は、プライバシー設定ボタンは非表示。
            // OBTAINED, REQUIRED, UNKNOWNの時は表示する。
            privacyButton?.isVisible = contentStatus != ConsentInformation.ConsentStatus.NOT_REQUIRED

            // バナーの表示
            (以下略)
        }

動作を観察

上記で実行し動作を観察したところ以下のようでした。

1.通信失敗の時にリトライしてくれない

通信ができない状態でgetConsentInformationを呼出すと失敗しadmobの初期化が行われずに広告が出ません。admobは通信ができなくてもリトライしてくれますが、UMPはしてくれないのでご注意を。

2.同意ダイヤログの表示される条件

初めのgetConsentInformationで成功の場合に、同意ダイアログが出る条件は以下であると思う。
①EEA地域である。
②まだ同意も不同意も選んでいない。
③setTagForUnderAgeOfConsent(bool)がfalseか、そもそも設定してない。
(trueをセットすると同意年齢未満では同意できないのでダイアログは出ないものと思う。)

3.一度、同意処理を通ればadmobは表示される。

一度getConsentInformationで成功(必要な場合には同意不同意を選択)すると、その後の起動はgetConsentInformationをしなくてもadmobは表示された。確証はないが1度行えば端末に情報が保存されるのだと思う。

免責事項

全て自己責任にて利用ください。この文章の正確性を保証しません。

Discussion