Loading the GDPR for Google AdMob is a tricky business in Android because Google's Documentation is quite unclear, and the steps are quite messy. And something important to highlight, if you don't add the GDPR section, you might lose some revenue, or who knows what would be Google's next move (you could get banned for not complying with European laws if you distribute your apps in the EU/EEA/UK markets).
Now, the steps are the following ones:
AdMob Section
1) Go to your AdMob account.
2) Go to Privacy & Messaging and choose the phone icon.
3) Create a new message and fill in the required information.
4) Configure your message:
5) Add your privacy policy for your app:
C# Section
1) Download the Xamarin.Google.UserMessagingPlatform for Android from NuGet.
2) Double-check that your AndroidManifest.xml has these two lines:
<activity android:name="com.google.android.gms.ads.AdActivity" android:value="AD_UNIT_ID"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize
|smallestScreenSize" android:theme="@android:style/Theme.Translucent" />
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="APP_ID" />
You can get AD_UNIT_ID and APP_ID from your AdMob account:
3) Load/copy the GDPR code after this line (do not do it before!):
MobileAds.Initialize(this);
private void SetGDPR()
{
Console.WriteLine(@"DEBUG: MainActivity.OnCreate: Starting consent management flow,
via UserMessagingPlatform.");
try
{
#if DEBUG
var debugSettings = new Xamarin.Google.UserMesssagingPlatform.ConsentDebugSettings.
Builder(this)
.SetDebugGeography(Xamarin.Google.UserMesssagingPlatform.ConsentDebugSettings
.DebugGeography
.DebugGeographyEea)
.AddTestDeviceHashedId(Android.Provider.Settings.Secure.GetString(ContentResolver,
Android.Provider.Settings.Secure.AndroidId))
.Build();
#endif
var requestParameters = new Xamarin.Google.UserMesssagingPlatform.
ConsentRequestParameters
.Builder()
.SetTagForUnderAgeOfConsent(false)
#if DEBUG
.SetConsentDebugSettings(debugSettings)
#endif
.Build();
var consentInformation = Xamarin.Google.UserMesssagingPlatform.
UserMessagingPlatform.GetConsentInformation(this);
consentInformation.RequestConsentInfoUpdate(
Activity,
requestParameters,
new GoogleUMPConsentUpdateSuccessListener(
() =>
{
// The consent information state was updated.
// You are now ready to check if a form is available.
if (consentInformation.IsConsentFormAvailable)
{
Xamarin.Google.UserMesssagingPlatform.UserMessagingPlatform.
LoadConsentForm(
this,
new GoogleUMPFormLoadSuccessListener((Xamarin.Google.
UserMesssagingPlatform.IConsentForm f) => {
googleUMPConsentForm = f;
googleUMPConsentInformation = consentInformation;
Console.WriteLine(@"DEBUG: MainActivity.OnCreate:
Consent management flow: LoadConsentForm has loaded a form, which will be shown if necessary,
once the ViewModel is ready.");
DisplayAdvertisingConsentFormIfNecessary();
}),
new GoogleUMPFormLoadFailureListener((Xamarin.Google.
UserMesssagingPlatform.FormError e) => {
// Handle the error.
Console.WriteLine("ERROR: MainActivity.OnCreate: Consent
management flow: failed in LoadConsentForm with error " + e.Message);
}));
}
else
{
Console.WriteLine(@"DEBUG: MainActivity.OnCreate: Consent
management flow: RequestConsentInfoUpdate succeeded but no consent form was available.");
}
}),
new GoogleUMPConsentUpdateFailureListener(
(Xamarin.Google.UserMesssagingPlatform.FormError e) =>
{
// Handle the error.
Console.WriteLine(@"ERROR: MainActivity.OnCreate: Consent management flow:
failed in RequestConsentInfoUpdate with error " + e.Message);
})
);
}
catch (Exception ex)
{
Console.WriteLine(@"ERROR: MainActivity.OnCreate: Exception thrown during consent
management flow: ", ex);
}
}
private Xamarin.Google.UserMesssagingPlatform.IConsentForm googleUMPConsentForm = null;
private Xamarin.Google.UserMesssagingPlatform.IConsentInformation
googleUMPConsentInformation = null;
public void DisplayAdvertisingConsentFormIfNecessary()
{
try
{
if (googleUMPConsentForm != null && googleUMPConsentInformation != null)
{
/* ConsentStatus:
Unknown = 0,
NotRequired = 1,
Required = 2,
Obtained = 3
*/
if (googleUMPConsentInformation.ConsentStatus == 2)
{
Console.WriteLine(@"DEBUG: MainActivity.
DisplayAdvertisingConsentFormIfNecessary: Consent form is being displayed.");
DisplayAdvertisingConsentForm();
}
else
{
Console.WriteLine(@"DEBUG: MainActivity.
DisplayAdvertisingConsentFormIfNecessary: Consent form is not being displayed because consent
status is " + googleUMPConsentInformation.ConsentStatus.ToString());
}
}
else
{
Console.WriteLine(@"ERROR: MainActivity.DisplayAdvertisingConsentFormIfNecessary:
consent form or consent information missing.");
}
}
catch (Exception ex)
{
Console.WriteLine(@"ERROR: MainActivity.DisplayAdvertisingConsentFormIfNecessary:
Exception thrown: ", ex);
}
}
public void DisplayAdvertisingConsentForm()
{
try
{
if (googleUMPConsentForm != null && googleUMPConsentInformation != null)
{
Console.WriteLine(@"DEBUG: MainActivity.DisplayAdvertisingConsentForm:
Consent form is being displayed.");
googleUMPConsentForm.Show(Activity, new GoogleUMPConsentFormDismissedListener(
(Xamarin.Google.UserMesssagingPlatform.FormError f) =>
{
if (googleUMPConsentInformation.ConsentStatus == 2) // required
{
Console.WriteLine(@"ERROR:
MainActivity.DisplayAdvertisingConsentForm: Consent was dismissed;
showing it again because consent is still required.");
DisplayAdvertisingConsentForm();
}
}));
}
else
{
Console.WriteLine(@"ERROR: MainActivity.DisplayAdvertisingConsentForm:
consent form or consent information missing.");
}
}
catch (Exception ex)
{
Console.WriteLine(@"ERROR: MainActivity.DisplayAdvertisingConsentForm:
Exception thrown: ", ex);
}
}
public class GoogleUMPConsentFormDismissedListener : Java.Lang.Object,
Xamarin.Google.UserMesssagingPlatform.IConsentFormOnConsentFormDismissedListener
{
public GoogleUMPConsentFormDismissedListener(
Action<Xamarin.Google.UserMesssagingPlatform.FormError> failureAction)
{
a = failureAction;
}
public void OnConsentFormDismissed(Xamarin.Google.UserMesssagingPlatform.FormError f)
{
a(f);
}
private Action<Xamarin.Google.UserMesssagingPlatform.FormError> a = null;
}
public class GoogleUMPConsentUpdateFailureListener : Java.Lang.Object,
Xamarin.Google.UserMesssagingPlatform.IConsentInformationOnConsentInfoUpdateFailureListener
{
public GoogleUMPConsentUpdateFailureListener(
Action<Xamarin.Google.UserMesssagingPlatform.FormError> failureAction)
{
a = failureAction;
}
public void OnConsentInfoUpdateFailure(Xamarin.Google.UserMesssagingPlatform.FormError f)
{
a(f);
}
private Action<Xamarin.Google.UserMesssagingPlatform.FormError> a = null;
}
public class GoogleUMPConsentUpdateSuccessListener : Java.Lang.Object,
Xamarin.Google.UserMesssagingPlatform.IConsentInformationOnConsentInfoUpdateSuccessListener
{
public GoogleUMPConsentUpdateSuccessListener(Action successAction)
{
a = successAction;
}
public void OnConsentInfoUpdateSuccess()
{
a();
}
private Action a = null;
}
public class GoogleUMPFormLoadFailureListener : Java.Lang.Object,
Xamarin.Google.UserMesssagingPlatform.UserMessagingPlatform
.IOnConsentFormLoadFailureListener
{
public GoogleUMPFormLoadFailureListener(
Action<Xamarin.Google.UserMesssagingPlatform.FormError> failureAction)
{
a = failureAction;
}
public void OnConsentFormLoadFailure(Xamarin.Google.UserMesssagingPlatform.FormError e)
{
a(e);
}
private Action<Xamarin.Google.UserMesssagingPlatform.FormError> a = null;
}
public class GoogleUMPFormLoadSuccessListener : Java.Lang.Object,
Xamarin.Google.UserMesssagingPlatform.UserMessagingPlatform
.IOnConsentFormLoadSuccessListener
{
public GoogleUMPFormLoadSuccessListener(
Action<Xamarin.Google.UserMesssagingPlatform.IConsentForm> successAction)
{
a = successAction;
}
public void OnConsentFormLoadSuccess(
Xamarin.Google.UserMesssagingPlatform.IConsentForm f)
{
a(f);
}
private Action<Xamarin.Google.UserMesssagingPlatform.IConsentForm> a = null;
}
5) Load the GDPR:
MobileAds.Initialize(this);
SetGDPR();
And that's all!
Note:
If you need iOS/MAUI support, raise your concerns in GitHub and/or Tweet to David Ortinau. You can also email David at: David.Ortinau@microsoft.com. They are the only ones who can support and fix these outdated libraries. You can also try to bind and commit your changes to GitHub and support the community. If Microsoft sees there is some real interest, probably, they will do something, but you the affected one must dare to contact them via their official channels.
Anything related to Apple is outside of our scope for now. So, we cannot reply to questions about iOS/macOS coding or specific issues. This article is for Android only.
Hi, in the C# section, part to 2 it says you need to add:
ReplyDelete<activity android:name="com.google.android.gms.ads.AdActivity" android:value="AD_UNIT_ID".....
I have banner ads and interstitial ads in my app. Do i need to add an activity like this for each of them with their ad unit id's?
Hi Ben, yes, you need to add it to each of them. You might be able to "generalize" it using the translation files, but it's the only way.
DeleteHi Federico. Excellent article, thanks for sharing!
ReplyDeleteI wonder if there is some implementation like this but for iOS. I know you are not developing for iOS but maybe you are aware of some update for iOS since I saw you are making some noice on forums. Thanks in advance!
Hi Genisuf, this article is for Android and I don't own a Mac or Apple devices. I am unaware of how to help you. You can go to GitHub and try pushing your case:
Deletehttps://github.com/xamarin/GoogleApisForiOSComponents/issues/628
You can also Tweet:
https://twitter.com/davidortinau
Or email him: David.Ortinau@microsoft.com