localization - GDPR - 同意 SDK - 同意书翻译

标签 localization admob

Consent SDK允许显示同意书,但目前只有英文版本(SDK 版本 1.0.3)。 SDK页面说:

To update consent text of the Google-rendered consent form, modify the consentform.html file included in the Consent SDK as required.

但是,consentform.html 作为 Assets 提供,我没有找到对其进行本地化的方法,尤其是使用 gradle。在这种情况下处理本地化的最佳方法是什么?为什么一开始没有这样做?欧洲不仅仅是英语。

最佳答案

由于 Google 的欧盟同意对话框不可本地化,因此我创建了自己的同意对话框,您可以像往常一样使用 strings.xml 进行翻译。它大致基于谷歌所做的事情。这将在没有中介的情况下使用:

Custom EU consent dialog

您可以自由使用我的代码,但如果文本适合您,请咨询您的法律顾问。我无法就适合您的同意文本提供法律建议。

添加到您的 gradle 文件:

implementation 'com.google.android.ads.consent:consent-library:1.0.3'

添加成员变量:

public boolean mShowNonPersonalizedAdRequests = false;
private AlertDialog mEuDialog;

onCreate()中调用checkConsentStatus():

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

添加使用 Google Consent SDK 的 checkConsentStatus() 方法:

// https://developers.google.com/admob/android/eu-consent
private void checkConsentStatus(){
    ConsentInformation consentInformation = ConsentInformation.getInstance(this);
    ConsentInformation.getInstance(this).addTestDevice("YOUR-DEVICE-ID"); // enter your device id, if you need it for testing

    String[] publisherIds = {"pub-YOUR-ADMOB-PUB-ID"}; // enter your admob pub-id
    consentInformation.requestConsentInfoUpdate(publisherIds, new ConsentInfoUpdateListener() {
        @Override
        public void onConsentInfoUpdated(ConsentStatus consentStatus) {
            log("User's consent status successfully updated: " +consentStatus);

            if (ConsentInformation.getInstance(MainActivity.this).isRequestLocationInEeaOrUnknown()){
                log("User is from EU");

                /////////////////////////////
                // TESTING - reset the choice
                //ConsentInformation.getInstance(MainActivity.this).setConsentStatus(ConsentStatus.UNKNOWN);
                /////////////////////////////

                // If the returned ConsentStatus is UNKNOWN, collect user's consent.
                if (consentStatus == ConsentStatus.UNKNOWN) {
                    showMyConsentDialog(false);
                }

                // If the returned ConsentStatus is PERSONALIZED or NON_PERSONALIZED
                // the user has already provided consent. Forward consent to the Google Mobile Ads SDK.
                else if (consentStatus == ConsentStatus.NON_PERSONALIZED) {

                    mShowNonPersonalizedAdRequests = true;

                    // The default behavior of the Google Mobile Ads SDK is to serve personalized ads.
                    // If a user has consented to receive only non-personalized ads, you can configure
                    // an AdRequest object with the following code to specify that only non-personalized
                    // ads should be returned.

                }


            } else {
                log("User is NOT from EU");
                // we don't have to do anything
            }

        }

        @Override
        public void onFailedToUpdateConsentInfo(String errorDescription) {
            log("User's consent status failed to update: " +errorDescription);
        }
    });
}

添加showMyConsentDialog()方法:

public void showMyConsentDialog(boolean showCancel) {

    AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this, R.style.MyAlertDialogStyle);
    LayoutInflater inflater = getLayoutInflater();
    View eu_consent_dialog = inflater.inflate(R.layout.eu_consent, null);

    alertDialog.setView(eu_consent_dialog)
               .setCancelable(false);

    if (showCancel) alertDialog.setPositiveButton(R.string.dialog_close, null);

    mEuDialog = alertDialog.create();
    mEuDialog.show();

    Button btn_eu_consent_yes = eu_consent_dialog.findViewById(R.id.btn_eu_consent_yes);
    Button btn_eu_consent_no = eu_consent_dialog.findViewById(R.id.btn_eu_consent_no);
    Button btn_eu_consent_remove_ads = eu_consent_dialog.findViewById(R.id.btn_eu_consent_remove_ads);
    btn_eu_consent_yes.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mEuDialog.cancel();
            toast(getString(R.string.thank_you), MainActivity.this);
            ConsentInformation.getInstance(MainActivity.this).setConsentStatus(ConsentStatus.PERSONALIZED);
            mShowNonPersonalizedAdRequests = false;
        }
    });
    btn_eu_consent_no.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mEuDialog.cancel();
            toast(getString(R.string.thank_you), MainActivity.this);
            ConsentInformation.getInstance(MainActivity.this).setConsentStatus(ConsentStatus.NON_PERSONALIZED);
            mShowNonPersonalizedAdRequests = true;
        }
    });
    btn_eu_consent_remove_ads.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mEuDialog.cancel();
            IAP_buyAdsFree(); // YOUR REMOVE ADS METHOD
            }
        });

    TextView tv_eu_learn_more = eu_consent_dialog.findViewById(R.id.tv_eu_learn_more);
    tv_eu_learn_more.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            euMoreInfoDialog();
        }
    });  
}

这是同意布局,保存到eu_consent.xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <LinearLayout
        android:id="@+id/ll_eu_consent"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/activity_horizontal_margin"
        >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/eu_consent_text"
            android:textSize="14sp"
            android:paddingBottom="6dp"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/eu_consent_question"
            android:textSize="14sp"
            android:paddingBottom="6dp"
            android:textStyle="bold"
        />

        <Button
            android:id="@+id/btn_eu_consent_yes"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/eu_consent_yes"
            android:textSize="13sp"
            />

        <Button
            android:id="@+id/btn_eu_consent_no"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/eu_consent_no"
            android:textSize="13sp"
            android:layout_marginTop="6dp"
            android:layout_marginBottom="6dp"
            />

        <Button
            android:id="@+id/btn_eu_consent_remove_ads"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/action_remove_ads"
            android:textSize="13sp"
            />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/eu_consent_change_setting"
            android:textSize="14sp"
            android:paddingTop="6dp"
            android:paddingBottom="6dp"
            />

        <TextView
            android:id="@+id/tv_eu_learn_more"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/learn_more"
            android:textSize="14sp"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:paddingTop="6dp"
            android:paddingBottom="6dp"
            android:textColor="@color/blue"
            style="@style/SelectableItem"
            />

    </LinearLayout>

</ScrollView>

添加euMoreInfoDialog():

private void euMoreInfoDialog(){

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, R.style.MyAlertDialogStyle);

    ScrollView sv = new ScrollView(this);
    LinearLayout ll = new LinearLayout(this);
    ll.setOrientation(LinearLayout.VERTICAL);

    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.MATCH_PARENT,
            LinearLayout.LayoutParams.WRAP_CONTENT);
    params.setMargins(40, 20, 40, 20);

    TextView tv_my_privacy_policy = new TextView(this);
    String link = "<a href="+PRIVACY_URL+">"+getResources().getString(R.string.app_name)+"</a>";
    tv_my_privacy_policy.setText(Html.fromHtml(link));
    tv_my_privacy_policy.setMovementMethod(LinkMovementMethod.getInstance());
    ll.addView(tv_my_privacy_policy, params);

    TextView tv_google_partners = new TextView(this);
    tv_google_partners.setText(R.string.google_partners);
    tv_google_partners.setPadding(40,40,40,20);
    ll.addView(tv_google_partners);

    List<AdProvider> adProviders = ConsentInformation.getInstance(this).getAdProviders();
    for (AdProvider adProvider : adProviders) {
        //log("adProvider: " +adProvider.getName()+ " " +adProvider.getPrivacyPolicyUrlString());
        link = "<a href="+adProvider.getPrivacyPolicyUrlString()+">"+adProvider.getName()+"</a>";
        TextView tv_adprovider = new TextView(this);
        tv_adprovider.setText(Html.fromHtml(link));
        tv_adprovider.setMovementMethod(LinkMovementMethod.getInstance());
        ll.addView(tv_adprovider, params);
    }
    sv.addView(ll);

    builder.setTitle(R.string.privacy_policy)
           .setView(sv)
           .setPositiveButton(R.string.dialog_close, null);

    final AlertDialog createDialog = builder.create();
    createDialog.show();

}

在您的 AdMob 网络界面中选择您想要使用的广告技术提供商。我建议您不要选择超过 20 个(左右),因为我认为如果您选择太多提供程序,euMoreInfoDialog() 会变得非常慢。

添加到onDestroy()以防止屏幕旋转时出现错误:

@Override
public void onDestroy(){
    // ...
    if (mEuDialog != null && mEuDialog.isShowing()) mEuDialog.cancel();
    // ...
    super.onDestroy();
}

当您发出广告请求时,请检查 mShowNonPersonalizedAdRequests 的值,并在必要时将 “npa” 添加到请求中:

Bundle extras = new Bundle();
if (mShowNonPersonalizedAdRequests)
    extras.putString("npa", "1");

AdRequest adRequest = new AdRequest.Builder()
    .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
    .addTestDevice("YOUR-DEVICE-ID-GOES-HERE") // insert your device id
    .addNetworkExtrasBundle(AdMobAdapter.class, extras)
    .build();

最后,将所有语言的字符串添加到 strings.xml 中:

<!-- EU GDPR Consent texts -->
<string name="eu_consent_text">Dear user!\n\nWe use Google Admob to show ads. Ads support our work, and enable further development of this app. In line with the new European Data Protection Regulation (GDPR), we need your consent to serve ads tailored for you.</string>
<string name="eu_consent_question">Can your data be used to show ads tailored for you?</string>
<string name="learn_more">Learn how your data is used</string>
<string name="google_partners">Google and its partners:</string>
<string name="eu_consent_yes">Yes, continue to show relevant ads</string>
<string name="eu_consent_no">No, show ads that are irrelevant</string>
<string name="eu_consent_change_setting">You can change this setting anytime in the \"About\" window.</string>
<string name="thank_you">Thank you!</string>

就是这样!

(注意:log()toast() 是我的方法,请将它们替换为您自己的方法。PRIVACY_URL 是您的 您的隐私政策的字符串 url。)

关于localization - GDPR - 同意 SDK - 同意书翻译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50540538/

相关文章:

c++ - Borland C++ 本地化

iphone - 如何在 iPhone 上将中文文本音译为拼音?

android - 缺少 NativeExpressAdView XML 属性 adSize

android - 在 Unity 移动应用程序中获取加载的 AdMob 广告目标 URL

android - Google admob “Problem linking app. Please try again later.”

安卓崩溃 :/data/user/0/[my app]/cache/WebView is not a directory

qt - 在纯 QT4 应用程序中使用 KDE4 本地化机制

asp.net - 要全局化 asp.net 应用程序,我需要了解什么?

Java 挪威语小数分隔符在 Java 6 和 7 中有所不同

android - 如何从应用程序 config.xml 中删除 `key` 和 `string` 以停止显示 AdMob?