Androidアプリ開発

AdMobを使用しているアプリのGDPR対応

この記事は約20分で読めます。
記事内に広告が含まれています。
スポンサーリンク

この記事は Android スマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Java での開発経験、XML 構文規則、Android のアプリ開発経験がある方を対象としています。
Android のアプリ開発でお役にたててれば、嬉しいです。
(これから Android のアプリ開発や Java での開発を始めたい方への案内は、
記事の最後で紹介します)

この記事のテーマ


 AdMobやFirebaseを使用しているアプリをGDPRに対応する

GDPR とは、EU一般データ保護規則の略称で、個人データの保護やその取り扱いについて定められた欧州経済領域と英国に適用される法令です。
つまり、個人データを扱うアプリを欧州経済領域と英国に配信する場合は、
GDPR に対応する必要があります。

注意すべき点として、個人データを扱っていないアプリでも、AdMob Firebase を使用している場合、GDPR に対応する必要があります。

デバイスの言語に応じて、メッセージの言語を変更することが可能です

バックアップに最適♪1GBのファイルも十数秒でバックアップできます💛

GDPR対応が必要なアプリ

個人データを扱うアプリを欧州経済領域と英国に配信する場合は、GDPR 対応は必須です。
GooglePlay でアプリを公開する際、配信先に欧州経済領域と英国が含まれている場合に、アプリのマニフェストファイルの内容とデータセフティで申告している内容でチェックされています。
なお、
AdMob Firebase を使用する場合、データセフティで個人データを扱う申告が必要です。
GooglePlay でアプリの配信先に欧州経済領域と英国を含めない場合、GDPR の対応は不要という解釈になります。

23年9月、AdMob の管理コンソールに下記の通知がありました。

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

この通知から、これまでの GooglePlay でのチェックに加え、広告配信時にも AdMob でチェックすることが予想できます。
AdMob のチェックで NG となった場合の措置として、広告配信が制限されることが容易に想像できます。
アプリの配信が欧州経済領域と英国が含まれていない場合でも、アプリの使用自体は制限できないので、可能性のひとつとして
GDPR に対応しておく方が安全と判断します。

GDPRメッセージの作成

欧州経済領域と英国のユーザに個人データの取り扱いについての同意確認のメッセージを作成します。
AdMob では、Google 独自の同意管理ソリューションを含む Google 認定の CMP を利用することができ、簡単な設定だけで GDPR に関するメッセージを作成することができます。
ただし、
GDPR に関するメッセージを作成するだけでは、ユーザに同意を求めるダイアログは表示されませんので、後述の UMP SDK の実装が必要です。

Google AdMob

GDPR メッセージの作成は、Google AdMob の管理コンソールから行います。
AdMob にログインして、メニューの「プライバシーとメッセージ」をクリックします。

GDPR」 → 「メッセージの作成」をクリックします。

GDPR のメッセージを識別するメッセージ名(サンプルではGDPR)、GDPR のメッセージを表示するアプリ、デフォルト言語、別の言語、ユーザの選択を設定します。

デバイスの言語が別の言語で追加した言語にあれば使用され、ない場合は言語(デフォルト)が使用されます。
AdMob に登録しているアプリから、アプリを選択します。
また、アプリの選択とあわせて、プライバシーポリシーの URL を入力します。
ユーザの選択では、同意しないボタン、閉じるボタンを表示する・しないが選択できます。

スタイルでは、ヘッダーや本文、ボタンのフォントや色を変更します。

ターゲッティングでは、メッセージを表示する地域を、欧州経済領域と英国だけか、すべての国かを選択します。

下書きに保存」をクリックして、作成した GDPR メッセージ を保存します。
公開」をクリックして、GDPR メッセージ を公開します。

UMP SDKの実装

UMP SDK(Google User Messaging Platform SDK)は、GDPR の同意確認を取得するためのライブラリです。
Consent SDK は非推奨となり、UMP SDK に置き換える必要があります。

※2023年10月現在、クイックスタートのページが参照できなくなっているようです。

UMP SDKを使用するための準備

UMP SDK を使用するには、モジュールのbuild.gradle ファイルに定義の追加が必要です。

◎build.gradle(モジュール)
2023年10月現在の最新バージョンは 2.1.0です。

…
dependencies {
    …
    implementation 'com.google.android.ump:user-messaging-platform:2.1.0'
}

同意確認フォーム表示

AdMob に限らず、外部サービスをアプリからハンドリングする場合、設定や制御と合わせてクラスとして実装する方法が一般的です。
クラスとして実装することで、再利用が容易になります。
サンプルでは、
広告の設定や制御を AdMob クラスとして実装しています。
同意確認フォームの表示は、
AdMob クラスのコンストラクタで実装します。
インスタンス化した時点で、同意確認前の場合に同意確認フォームを表示します。
メソッドとして、
広告のロード、広告ロード時のエラーコード取得、同意ステータス確認を用意しています。

public class AdMob {
    private static final boolean    DEBUG = false;
    private static final String     TAG = AdMob.class.getSimpleName();
    public ConsentInformation       consentInformation;
    private int                     errorCode;
    …

    //コンストラクタ
    public AdMob(Activity activity) {
        ConsentRequestParameters params;
        if (DEBUG) {
            //デバッグ用
            ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(activity)
                    .setDebugGeography(ConsentDebugSettings.DebugGeography.DEBUG_GEOGRAPHY_EEA)
                    .addTestDeviceHashedId( //デバイスID )
                    .build();
            params = new ConsentRequestParameters.Builder()
                    .setConsentDebugSettings(debugSettings)
                    .setTagForUnderAgeOfConsent(false)
                    .build();
        } else {
            params = new ConsentRequestParameters.Builder()
                    .setTagForUnderAgeOfConsent(false)
                    .build();
        }
        consentInformation = UserMessagingPlatform.getConsentInformation(activity.getApplicationContext());
        consentInformation.requestConsentInfoUpdate(activity, params, () -> {
            if (consentInformation.isConsentFormAvailable()) {
                loadForm(activity.getApplicationContext(), activity);
            }
        }, formError -> { //フォーム表示エラー時の処理 });
    }

    // 同意ステータス確認 //
    public int getConsentStatus() {
        return consentInformation.getConsentStatus();
    }

    // エラーコード取得 //
    public int getErrorCode() {
        return errorCode;
    }

    // AdMobロード //
    public void loadAdMob(Context context ,AdView adView) {
        MobileAds.initialize(context, initializationStatus -> { // MobileAds初期化エラー時の処理 });
        AdRequest adRequest = new AdRequest.Builder().build();
        adView.loadAd(adRequest);
        adView.setAdListener(new AdListener() {
            @Override
            public void onAdImpression() {
                super.onAdImpression();
            }
            @Override
            public void onAdClicked() {
                //広告クリック時の処理
                super.onAdClicked();
            }
            @Override
            public void onAdLoaded() {
                //広告ロード完了時の処理
            }
            @Override
            public void onAdOpened() {
                //広告開始の処理
            }
            @Override
            public void onAdClosed() {
                //広告終了の処理
            }
            @Override
            public void onAdFailedToLoad(@NonNull LoadAdError error) {
                errorCode = error.getCode();
                //広告ロードエラー時の処理
            }
        });
    }

    // 同意確認フォーム表示 //
    private void loadForm(Context context, Activity activity) {
        UserMessagingPlatform.loadConsentForm(context, consentForm -> {
            if (getConsentStatus() == ConsentInformation.ConsentStatus.REQUIRED) {
                consentForm.show(activity, formError -> {
                    //同意確認フォーム表示エラー時の処理
                });
            } else {
                //同意が必要以外の処理 
            }
        }, formError -> { //同意確認フォームロードエラー時の処理 });
    }
}

同意確認フォームは欧州経済領域と英国のユーザでしか表示できないため、テストができません。
強制的に同意確認フォームを表示するために
ConsentDebugSettings を使用します。
ConsentDebugSettings の生成には、テストで使用するデバイスのデバイスIDが必要です。
デバイスIDを知る方法として、
addTestDeviceHashedId を指定せず(コメントアウト)に実行、Logcat に出力されたデバイスIDを使用します。

アプリからAdMobをハンドリングする

サンプルでは、AdMob のバナー広告を使用しています。
バナー広告は、画面(Activity)のレイアウトXML に
AdView を配置します。
AdMob クラスのインスタンス化、広告表示を関数としています。

    public Handler   adHandler;
    public Runnable  adRunnable;
    public AdMob     adMob;
    public AdView    adView;
    private int      consentStatus = 0;
    … 
    // AdMob初期化 //
    public void initializeAdMob(Activity activity) {
        // AdMob広告
        if (adView != null) {
            adView.resume();
        } else {
            adView = findViewById(R.id.adView);
        }
        adMob = adMob == null ? new AdMob(activity) : adMob;
    }

    // 広告表示 //
    public void adShow(Activity activity) {
        adHandler = new Handler(Looper.getMainLooper());
        adRunnable = new Runnable() {
            @Override
            public void run() {
                int status = adMob.getConsentStatus();
                if (consentStatus == 0 && (status == ConsentInformation.ConsentStatus.OBTAINED || status == ConsentInformation.ConsentStatus.NOT_REQUIRED)) {
                    consentStatus = status;
                    if (adView != null) {
                        adMob.loadAdMob(context, adView);
                    }
                    //同意済み、同意不要の場合は広告表示
                    if (consentStatus == ConsentInformation.ConsentStatus.OBTAINED || consentStatus == ConsentInformation.ConsentStatus.NOT_REQUIRED) {
                        if (adView != null) adView.setVisibility(View.VISIBLE);
                    }
                }
                if (adMob.getErrorCode() == 0) {
                    //AdMob広告
                    if (adView != null) adView.setVisibility(View.VISIBLE);
                } else {
                    if (adView != null) {
                        adView.setVisibility(View.INVISIBLE);
                        adView.destroy();
                    }
                }
                adHandler.postDelayed(this, 1000);
            }
        };
        adHandler.post(adRunnable);
    }

同意ステータスとして、UNKNOWN(0:不明)、NOT_REQUIRED(1:同意不要)、REQUIRED(2:同意必要)、OBTAINED(3:確認済み)があります。
REQUIRED は同意確認フォームを表示して確認、NOT_REQUIRED は確認不要、 OBTAINED は確認済みです。
注意点としては、確認済みということはわかるが、同意確認フォームの回答内容までわからないということです。
同意確認フォームの回答で承認しないを選択した場合、広告ロードエラーが発生する仕組みとなっているようです。

Activity onResume で AdMob初期化、広告表示を実行します。
広告表示では AdMob初期化で同意確認フォームの回答を待ち合わせる場合があるので、
Handlerを使用して、広告の表示を待ち合わせています。
on