2022年9月11日日曜日

Android アプリ AdMob GDPR 同意メッセージ

やりたいこと
GDPRに対応したメッセージをアプリの起動時に表示させることができたので、
その方法をメモしておきます。



背景
ここはよみとばして大丈夫です。

詳しいことは忘れてしまったのですが、admobかgoogleからGDPRに対応してねというメールかなにか来たか、
PlayConsoleかAdmobの管理画面でそういう通知がきてたかだったと思います。

過去の通知とかを漁ったのですがどれがそれなのかよくわかりませんでした。

ざっくり言うと、Admobを使っていて、EUを販売対象としている場合は、メッセージをだして同意を求める必要があるというものになります。

Admob > プライバシーとメッセージ > GDPR > 設定ボタン を押すと表示される画面にそういう内容が書いてあります。


(引用元 : Google Admobの管理画面)
ということで、やっとそのメッセージが表示できるようになったので、
やりかたをメモしておきます。

環境
Win11 21h2
Android Studio 2021.2.1 Patch 2
admobの広告は設定済み
参考にしたサイト
Admobのサイト
https://developers.google.com/admob/ump/android/quick-start

こちらを主に参考にしました。

デバイスIDの調べ方
https://www.howtodroid.com/how-to-find-hashed-device-id-for-admob.html
 
ざっくりいうと
ざっくりいうと、Admobのページでメッセージを出す設定に変更して、
その後にプログラムを修正する。という流れになります。

Step.1
最初にAdmobのサイトで設定をしておきます。
Admobのページにログインし、プライバシーメッセージに遷移します。
GDPRをクリック(たしか設定ボタンだったかも。)


GDPRを使ってみるの画面に遷移するので、続行をクリックする。

3ステップでGDPRメッセージを作成の画面に遷移するので、
GCPRメッセージを作成ボタンをクリックする。


次の画面でプライバシーポリシーのURLを設定する必要があります。
プライバシーポリシーは前回つくったので、そちらをURLをいれました。
(まったく自身がないプライバシーポリシーですが。)

次に言語と、表示するメッセージを選択する画面に遷移するので、
設定します。

確定するとメッセージのプレビュー画面に遷移するので、公開ボタンをクリックしてStep1は完了です。







Step.2
ここからはコードの方の話になります。
参考サイトのWebページに従って実装していきます。

まずは、*.appの方のBuild Gradleに以下の最終行を追加します。

dependencies {

    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
    implementation 'androidx.navigation:navigation-fragment:2.4.1'
    implementation 'androidx.navigation:navigation-ui:2.4.1'
    implementation 'androidx.preference:preference:1.1.1'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    // for admob
    implementation 'com.google.android.gms:play-services-ads:21.0.0'

    // for EU
    implementation 'com.google.android.ump:user-messaging-platform:2.0.0'
}
Step.3
AndroidManifest.xmlに広告IDを記載します。
 (テスト用でなくて本物の方じゃないとだめか?)



Step.4
MainActivityにメンバ変数を二つ追加。下の2行です。
public class MainActivity extends AppCompatActivity {

    private AppBarConfiguration appBarConfiguration;
    private ActivityMainBinding binding;

    // for EU ①
    private ConsentInformation consentInformation;
    private ConsentForm consentForm;

Step.5
MainActivityのonCreate()メソッドに、14行目以降を追加します。
for EU for DEBUG 以下を全部追加します。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        setSupportActionBar(Objects.requireNonNull(binding.toolbar));

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);

        // for EU for DEBUG
//        ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
//                .setDebugGeography(ConsentDebugSettings
//                        .DebugGeography
//                        .DEBUG_GEOGRAPHY_EEA)
//                .addTestDeviceHashedId("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
//                .build();


        // for EU ②
        // Set tag for underage of consent. Here false means users are not underage.
        ConsentRequestParameters params = new ConsentRequestParameters
                .Builder()
        		// for EU for DEBUG
                //.setConsentDebugSettings(debugSettings)   // for DEBUG
                .setTagForUnderAgeOfConsent(false)
                .build();

        consentInformation = UserMessagingPlatform.getConsentInformation(this);

        // for EU for DEBUG
        //consentInformation.reset();

        consentInformation.requestConsentInfoUpdate(
                this,
                params,
                new ConsentInformation.OnConsentInfoUpdateSuccessListener() {
                    @Override
                    public void onConsentInfoUpdateSuccess() {
                        // The consent information state was updated.
                        // You are now ready to check if a form is available.
                        if (consentInformation.isConsentFormAvailable()) {
                            loadForm();
                        }
                    }
                },
                new ConsentInformation.OnConsentInfoUpdateFailureListener() {
                    @Override
                    public void onConsentInfoUpdateFailure(FormError formError) {
                        // Handle the error.
                        Log.d("error", "error_ConsentInfoUpdateFailure");
                    }
                });

    }

Step.6
MainActivity に loadForm()を追加する。
    public void loadForm() {
        UserMessagingPlatform.loadConsentForm(
                this, new UserMessagingPlatform.OnConsentFormLoadSuccessListener() {
                    @Override
                    public void onConsentFormLoadSuccess(ConsentForm consentForm) {
                        MainActivity.this.consentForm = consentForm;
                        if (consentInformation.getConsentStatus() == ConsentInformation.ConsentStatus.REQUIRED) {
                            consentForm.show(
                                    MainActivity.this,
                                    new ConsentForm.OnConsentFormDismissedListener() {
                                        @Override
                                        public void onConsentFormDismissed(@Nullable FormError formError) {
                                            // Handle dismissal by reloading form.
                                            loadForm();
                                        }
                                    });
                        }
                    }
                },
                new UserMessagingPlatform.OnConsentFormLoadFailureListener() {
                    @Override
                    public void onConsentFormLoadFailure(FormError formError) {
                        // Handle the error.
                        Log.d("error", "error_ConsentFormLoadFailure");
                    }
                });
    }
Step.7 テストの準備
これだと、日本では、メッセージが表示されないので、強制的に地域をEUに変更するテストコードを追加します。

テストコードを追加するまえに、テストするデバイスのデバイスハッシュIDというのが必要になるので、まずはそれを調べます。

デバッグ対象のデバイス( emulatorとか )でアプリを実行します。

Logcat Windowで、「addtestdevice」で検索すると、ハッシュIDが表示されるので、どこかにメモっておきます。




Step.8 テスト
それでは、先ほどの強制的に地域をEUに変更するコードを追加するのですが、
実はStep5ですでに追加はしてあって、コメントアウトしているので、それを生かします。

3か所あります。

1個目が、Step5のコードの14行目の「for EU for DEBUG」とコメントがあるこの部分です。
    
        // for EU for DEBUG
        ConsentDebugSettings debugSettings = new ConsentDebugSettings.Builder(this)
                .setDebugGeography(ConsentDebugSettings
                        .DebugGeography
                        .DEBUG_GEOGRAPHY_EEA)
                .addTestDeviceHashedId("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
                .build();
    
XXXにはStep7で調べたハッシュIDを入れます。

2個目がStep5のコードの27行目のコメント部分を生かします。
    
        		// for EU for DEBUG
                //.setConsentDebugSettings(debugSettings)   // for DEBUG
    
3個目がStep5のコードの34行目のコメント部分を生かします。
これはユーザーが同意のメッセージを選択したことをリセットする処理になります。
// for EU for DEBUG
とコメントがあるこちらです。
    
        // for EU for DEBUG
        //consentInformation.reset();
おわり
これで実行すると、同意のメッセージが表示されます。
たぶんされるはず。

まとめ
Andorid アプリで GDPRの同意メッセージを表示する方法について記載いたしました。
最初にAdmobの設定で同意メッセージを表示するという設定を行い、
次に、コードを変更して同意メッセージを表示するコードを記載しました。

また、テストのために地域を変更する方法と、同意した内容をリセットする方法を記載しました。

これで一応メッセージが表示できるようになったのですが、これが正解なのかどうかがいまいち自身はないです。

苦労した点
①Step1をするということがわからず、コードだけ直して、いくらやってもメッセージがでてこないので、
そこに気づくのにとても時間をかけてしまいました。
<