Google ConsentSDKを使用してAndroidアプリの同意フォームに表示します。form.show()を呼び出すと、「同意フォームエラー同意フォームを表示する準備ができていません。」というエラーが表示されます。誰が私を助けられるか?
私のコード:
ConsentForm form = new ConsentForm.Builder(context, privacyUrl)
.withListener(new ConsentFormListener() {
@Override
public void onConsentFormLoaded() {
// Consent form loaded successfully.
Log.d("SplashScreen", "Consent form Loaded ");
}
@Override
public void onConsentFormOpened() {
// Consent form was displayed.
Log.d("SplashScreen", "Consent form opened ");
}
@Override
public void onConsentFormClosed(
ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed.
Log.d("SplashScreen", "Consent form Closed ");
}
@Override
public void onConsentFormError(String errorDescription) {
// Consent form error.
Log.d("SplashScreen", "Consent form error " + errorDescription);
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.build();
form.load();
form.show();
これが、アプリで使用するGoogle Consent SDKのヘルパークラスです。同意情報を初期化し、必要に応じて同意フォームを表示するには、メインアクティビティのonCreate()
メソッドに次のコードを含めます。
GdprHelper gdprHelper = new GdprHelper(this);
gdprHelper.initialise();
同様に、ユーザーが設定の[プライバシーの同意をリセット]をクリックすると、次のコードが実行されます。
GdprHelper gdprHelper = new GdprHelper(this);
gdprHelper.resetConsent();
どちらの場合も、これは現在実行中のアクティビティを参照しています。
ヘルパークラスの完全な実装:
package com.example.app;
import Android.content.Context;
import Android.content.Intent;
import Android.net.Uri;
import Android.widget.Toast;
import com.google.ads.consent.ConsentForm;
import com.google.ads.consent.ConsentFormListener;
import com.google.ads.consent.ConsentInfoUpdateListener;
import com.google.ads.consent.ConsentInformation;
import com.google.ads.consent.ConsentStatus;
import Java.net.MalformedURLException;
import Java.net.URL;
public class GdprHelper {
private static final String PUBLISHER_ID = "YOUR-PUBLISHER-ID";
private static final String PRIVACY_URL = "YOUR-PRIVACY-URL";
private static final String MARKET_URL_PAID_VERSION = "market://details?id=com.example.app.pro";
private final Context context;
private ConsentForm consentForm;
public GdprHelper(Context context) {
this.context = context;
}
// Initialises the consent information and displays consent form if needed
public void initialise() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.requestConsentInfoUpdate(new String[]{PUBLISHER_ID}, new ConsentInfoUpdateListener() {
@Override
public void onConsentInfoUpdated(ConsentStatus consentStatus) {
// User's consent status successfully updated.
if (consentStatus == ConsentStatus.UNKNOWN) {
displayConsentForm();
}
}
@Override
public void onFailedToUpdateConsentInfo(String errorDescription) {
// Consent form error. Would be Nice to have proper error logging. Happens also when user has no internet connection
if (BuildConfig.BUILD_TYPE.equals("debug")) {
Toast.makeText(context, errorDescription, Toast.LENGTH_LONG).show();
}
}
});
}
// Resets the consent. User will be again displayed the consent form on next call of initialise method
public void resetConsent() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.reset();
}
private void displayConsentForm() {
consentForm = new ConsentForm.Builder(context, getPrivacyUrl())
.withListener(new ConsentFormListener() {
@Override
public void onConsentFormLoaded() {
// Consent form has loaded successfully, now show it
consentForm.show();
}
@Override
public void onConsentFormOpened() {
// Consent form was displayed.
}
@Override
public void onConsentFormClosed(
ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed. This callback method contains all the data about user's selection, that you can use.
if (userPrefersAdFree) {
redirectToPaidVersion();
}
}
@Override
public void onConsentFormError(String errorDescription) {
// Consent form error. Would be Nice to have some proper logging
if (BuildConfig.BUILD_TYPE.equals("debug")) {
Toast.makeText(context, errorDescription, Toast.LENGTH_LONG).show();
}
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.withAdFreeOption()
.build();
consentForm.load();
}
private URL getPrivacyUrl() {
URL privacyUrl = null;
try {
privacyUrl = new URL(PRIVACY_URL);
} catch (MalformedURLException e) {
// Since this is a constant URL, the exception should never(or always) occur
e.printStackTrace();
}
return privacyUrl;
}
private void redirectToPaidVersion() {
Intent i = new Intent(
Intent.ACTION_VIEW,
Uri.parse(MARKET_URL_PAID_VERSION));
context.startActivity(i);
}
}
OK、私はこの方法で解決しました:Builderでフォームのインスタンスを作成してから、form.load()を呼び出す必要があります。
フォームが読み込まれるのを待ち、内部の.show()を呼び出します。
@Override
public void onConsentFormLoaded() {
// Consent form loaded successfully... now you can show it.
Log.d("SplashScreen", "Consent form Loaded ");
showConsentForm();
}
これを達成するためにプライベート関数を作成しました:
private showConsentForm(){ form.show(); }
フォームがどのように機能するかを確認するには、次のアプリを試してください。 https://play.google.com/store/apps/details?id=com.mapkcode.whereis
簡単な答えは、フォームの読み込みが完了するまでフォームを表示できないことです。このニュアンスの docs はかなり恐ろしいです。修正は、次のようにform.show()
内でonConsentFormLoaded()
を呼び出すことです。
public class MyGdprHelper {
private ConsentForm form;
private void getUsersConsent() {
form = new ConsentForm.Builder(context, privacyUrl)
.withListener(new ConsentFormListener() {
@Override
public void onConsentFormLoaded() {
// Consent form loaded successfully.
form.show();
}
@Override public void onConsentFormOpened() {...}
@Override public void onConsentFormClosed(ConsentStatus consentStatus, Boolean userPrefersAdFree) {...}
@Override public void onConsentFormError(String errorDescription) {...}
)
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
.withAdFreeOption()
.build();
form.load();
}
...
}
@WebMajstrの回答と@Frankのコメントに基づいて、ここに2つの追加機能がある私の独自のクラスを示します。コールバックリスナーと非EEAユーザーがチェックされます。
パッケージcom.levionsoftware.photos.utils.consensus;
import Android.content.Context;
import Android.util.Log;
import com.google.ads.consent.ConsentForm;
import com.google.ads.consent.ConsentFormListener;
import com.google.ads.consent.ConsentInfoUpdateListener;
import com.google.ads.consent.ConsentInformation;
import com.google.ads.consent.ConsentStatus;
import com.google.ads.consent.DebugGeography;
import com.levionsoftware.photos.MyApplication;
import com.levionsoftware.photos.R;
import Java.net.MalformedURLException;
import Java.net.URL;
public class GdprHelper {
private static final String PUBLISHER_ID = "pub-2308843076741286";
private final Context context;
private final ConsensusUpdatedListener consensusUpdatedListener;
private ConsentForm consentForm;
public GdprHelper(Context context, ConsensusUpdatedListener consensusUpdatedListener) {
this.context = context;
this.consensusUpdatedListener = consensusUpdatedListener;
}
// Initialises the consent information and displays consent form if needed
public void initialise() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_EEA);
consentInformation.requestConsentInfoUpdate(new String[]{PUBLISHER_ID}, new ConsentInfoUpdateListener() {
@Override
public void onConsentInfoUpdated(ConsentStatus consentStatus) {
Log.d("GdprHelper", "onConsentInfoUpdated: " + consentStatus.toString());
if(consentInformation.isRequestLocationInEeaOrUnknown()) {
Log.d("GdprHelper", "isRequestLocationInEeaOrUnknown: true");
// If the isRequestLocationInEeaOrUnknown() method returns true:
// If the returned ConsentStatus is PERSONALIZED or NON_PERSONALIZED, the user has already provided consent. You can now forward consent to the Google Mobile Ads SDK.
// If the returned ConsentStatus is UNKNOWN, see the Collect consent section below, which describes the use of utility methods to collect consent.
// User's consent status successfully updated.
if (consentStatus == ConsentStatus.UNKNOWN) {
consensusUpdatedListener.reset();
displayConsentForm();
} else {
consensusUpdatedListener.set(consentStatus == ConsentStatus.NON_PERSONALIZED, false);
}
} else {
Log.d("GdprHelper", "isRequestLocationInEeaOrUnknown: false");
// If the isRequestLocationInEeaOrUnknown() method returns false:
// the user is not located in the European Economic Area and consent is not required under the EU User Consent Policy. You can make ad requests to the Google Mobile Ads SDK.
consensusUpdatedListener.set(false, true);
}
}
@Override
public void onFailedToUpdateConsentInfo(String errorDescription) {
// Consent form error. Would be Nice to have proper error logging. Happens also when user has no internet connection
MyApplication.toastSomething(new Exception(errorDescription));
}
});
}
// Resets the consent. User will be again displayed the consent form on next call of initialise method
public void resetConsent() {
ConsentInformation consentInformation = ConsentInformation.getInstance(context);
consentInformation.reset();
}
private void displayConsentForm() {
consentForm = new ConsentForm.Builder(context, getPrivacyUrl())
.withListener(new ConsentFormListener() {
@Override
public void onConsentFormLoaded() {
// Consent form has loaded successfully, now show it
consentForm.show();
}
@Override
public void onConsentFormOpened() {
// Consent form was displayed.
}
@Override
public void onConsentFormClosed(
ConsentStatus consentStatus, Boolean userPrefersAdFree) {
// Consent form was closed. This callback method contains all the data about user's selection, that you can use.
Log.d("GdprHelper", "onConsentFormClosed: " + consentStatus.toString());
if (consentStatus == ConsentStatus.UNKNOWN) {
consensusUpdatedListener.reset();
displayConsentForm();
} else {
consensusUpdatedListener.set(consentStatus == ConsentStatus.NON_PERSONALIZED, false);
}
}
@Override
public void onConsentFormError(String errorDescription) {
// Consent form error. Would be Nice to have some proper logging
MyApplication.toastSomething(new Exception(errorDescription));
}
})
.withPersonalizedAdsOption()
.withNonPersonalizedAdsOption()
//.withAdFreeOption()
.build();
consentForm.load();
}
private URL getPrivacyUrl() {
URL privacyUrl = null;
try {
privacyUrl = new URL(MyApplication.get().getString(R.string.privacyPolicyURL));
} catch (MalformedURLException e) {
// Since this is a constant URL, the exception should never(or always) occur
e.printStackTrace();
}
return privacyUrl;
}
}
リスナー:
package com.levionsoftware.photos.utils.consensus;
public interface ConsensusUpdatedListener {
void set(Boolean npa, Boolean consensusNotNeeded);
void reset();
}
編集:参照 Android:Admobの同意SDKを使用してユーザーの位置を取得 、isRequestLocationInEeaOrUnknownはAFTER onConsentInfoUpdatedと呼ばれる必要があります。