Closed Luklek closed 6 years ago
ad 1) I don't want to add a close button, there is no need for this I think ad 3) I prefer the soft opt in and there is defenitely no need to explicitly ask again for consent for non personalised ads ad 5) That's a good idea as well...
The problem is, AdMob dialog targets ads only, I try to keep the dialog generic though, so it's not that easy to have the same workflow... I will try to make some changes in this direction as I like the appearance of AdMob's dialog.
After seeing this dialog, I could think about following change though:
1) Change main text to something like following "We care about your privacy and keep this app cheap/free by using third party services. We use ads/cloud storage in this app. Those services may collect unique identifiers and collect personal data to provide a proper and personalised service. (<a href="...">Lern more about our partners</a>
). By agreeing, you are confirming that you would like this personalised experience."
2) Optionally I will add the link to the app's own privacy policy
Check out the new code and demo, I've adjusted the flow to be even simplier and a little more like AdMob's... Or try the v0.5.0
release to try it out
I just tested v0.5 Some more ideas/comments (sorry if I write too much^^):
I would like (the option) to not allow the user to dismiss the Dialog or click Back to close the App. Google consent SDK doesn't allow to click Back and the dialog can't be dismissed by clicking outside. So the user has to make a choice at this point. I think in general I like this behavior a little bit more, because it's the approach used by Google. (so mostly I think/hope it shouldn't cause problems with Google Play policy)
in case of Negative Consent, I would like (the option) to have an extra dialog/screen with further text and Agree button. Again, this is mostly because it's the way Google decided to handle it and it seems on line with their policy at last paragraph: https://support.google.com/admob/answer/7676680 In this case a simple Agree button with no other choice is fine (as per ePrivacy Directive and not GDPR). I understand that actually in the previous dialog it already states that user will see less relevan Ads... but to be on the safe side the extra dialog could be nice (again... as it's the way Google implemented it). In case you decide to have this option, this is the text I would use: "We won't collect your data for personalized advertising. Although non-personalized ads don’t use mobile ad identifiers for ad targeting, they do still use mobile ad identifiers for frequency capping, aggregated ad reporting, and to combat fraud and abuse." "Agree" button
I would modify the consent dialog a bit as below (changes in bold): We care about your privacy and data security. We keep this app %1$s by showing ads and using third party services. We use %1$s in this app. %2$s %3$s (including %6$s partners) %4$s unique identifiers and other personal data. <a href=\"\">Learn more about %5$s %3$s and how it/they collect/collects your personal data. [Bold biggest font]Can we continue to use your data to tailor ads for you and as needed by the other services used in this App? You can change your choice at anytime in the app settings. By agreeing, you are confirming that you are over the age of 16.
I would add/change:
<string name="gdpr_type_crash">crash reporting</string>
<string name="gdpr_type_analytics">analytics reporting</string>
on my Samsung S9 the dialog looks quite thin (anyway I prefer using Activity)
1) I can make the close part optional, but imho, this is not fully GDPR conform... It does put pressure on the user to select something, there is no easy way out in this case... I can add the option, but I would not suggest to use it.
2) can be done, but is no must. I talked about the general workflow with a GDPR expert (her friend even was one of the guys responsible for GDPR) and I got her ok for the soft opt in here. Feel free to ad this as optional flag though
3) the library is general, someone may use it without ads. In the definitions of services I already have a flag that indicates if a service is an ad service. If you try the newest version, you will already see the information about what the services used do (ads, cloud database, crash reporting)
4) check out the newest layout (screenshot you posted is old). I already added the services function to the main dialog e.g. (like ads) => this also effects the point about "I would add/change: crash reporting, analytics reporting"
5) The sentence "Can we continue to use your data to tailor ads for you and as needed by the other services used in this App?" I'll add a question like this, but a shorter one probably. You can anyway override resources yourself at anytime...
6) Layout - you can also try the bottom sheet style now if you want to...
Info
Only because google is doing something, it does not mean it's correct/perfect. They may make changes to the sdk in the near future, rleasing the sdk so late is an indicator for this imho. The problem with laws like this is, that nobody really knows what is 100% save until the first courtyard has made a judgement. From then on you are a lot safer as you can always use the case as reference to back up your behaviour...
Try out version 0.5.2... Some points are implemented and some other changes may be solved now as well...
I understand that of course Google may be wrong about their own implementation and may change behavior in the future. To be honest I am not even worried about GDPR itself as much as Google own policies (AdMob, Google Play). About 2. (as the https://support.google.com/admob/answer/7676680 specify it's about the ePrivacy Directive) my main concern is that AdMob policy itself now maybe requires that extra step to agree to non-personalized Ads.
About 1. it just makes me feel that if the user misclick outside of the dialogue he will think the App crashed for example. Or even pressing Back when facing a Dialog, the user doesn't expect an App to close (but to dismiss the Dialog only). Anyway it's just an idea that may be worth to have an option for.
About 3-5) are just mostly ideas to try to make the library more general as possible and then have the strings translated in many languages (I can provide Italian). Other than that of course each one can adjust as they prefer.
v0.5.2
I think the "Can we continue to use your data..." question should include a reference to personalized/tailored ads (at least in the case that an Ad Network is setup too)
The "Force user to make a choice" doesn't work in Activity mode.
with the new layout, I would move "Learn more about %5$s %3$s and your personal data" after the "You can change your choice at anytime in the app settings" (just for the looks)
I would modify (to add separate Analytics and Crash reporting services):
<string name="gdpr_type_crash">crash analytics</string>
to:
<string name="gdpr_type_crash">crash reporting</string>
<string name="gdpr_type_analytics">analytics reporting</string>
the Dialog still have a lot of empty spaces on the sides in my S9
Everything should be adjusted now but following:
1) "Can we continue to use your data..." question Adding redundant information (all the info is written above already) again here makes the dialog even bigger imho... It would make it even scrollable in portrait mode on my S6 already...
2) dialog size
I added a method withCustomDialogTheme
. You can add a custom dialog theme there... Other than this, the dialog size should be androids default size, there is nothing in the app that changes the size or style... The app's theme is simply Theme.AppCompat.Light.DarkActionBar
Tested latest version:
withForceSelection: In the Info Page (Activity style), the back button doesn't work. (while it can be used to navigate Back in the Dialog styles)
"Can we continue to use your data..." question I think adding "personalized/tailored ads" info isn't redundant here (if an Ad Network is added to library setup at least). In the current Dialog text, it's not specified why Ads need to use Identifiers and personal data (with the reason being to show personal and more relevant Ads) I understand the library have a more general usage but still the main point of the GDPR are personalized Ads. Also from what I understand, the GDRP requires we explain to the user the reason why you request their data. So I think personally I will use "Can we continue to use your data for these purposes and to show personalized ads?"
Some other ideas from MoPub and Google SDKs:
add something like this to check if we can collect user data (it may also check about the phone settings about Limit Ad Tracking Preference). This would be useful to check if we can pass consent to other Networks mediation adapters or services etc
public boolean canCollectPersonalInformation() {
final Boolean gdprApplies = gdprApplies(); // If we don't know whether or not GDPR applies, then we haven't synced, so we cannot // collect personal information. if (gdprApplies == null) { return false; }
// If we are not in a GDPR region, we can freely collect user data.
if (!gdprApplies) {
return true;
}
// Return whether or not we have consent and that Do Not Track is disabled.
return getPersonalInfoConsentStatus().equals(ConsentStatus.EXPLICIT_YES) &&
!ClientMetadata.getInstance(mAppContext).getMoPubIdentifier().getAdvertisingInfo()
.isDoNotTrack();
}
add isRequestLocationInEeaOrUnknown (same reasons as above)
1) fixed
2) added this short text "and to show personalised ads" if an ad service is used
3) I don't understand what this should do; looks like checking if the user is within EAA or not, so the same as 4?
4) checkout GDPRSetup::withCheckRequestLocation
=> this will check following url (the one from googles sdk). Btw, I would not use this though... as written in my readme about GDPR...
to see if we are allowed to collect user data.
It first check if the EEA applies (by the user location)
Then it checks the consent status (and if the user didn't turn on Limited Ad Tracking on the phone settings... but maybe this doesn't really make sense)
It may be useful when passing consent to other Ad Networks not integrated directly (for example with MoPub mediation, in each Netowrk Adapter file):
// Pass the user consent from the MoPub SDK to AppLovin as per GDPR boolean canCollectPersonalInfo = MoPub.canCollectPersonalInformation(); AppLovinPrivacySettings.setHasUserConsent(canCollectPersonalInfo, context);
is mostly used within 3. to check location and see if GDPR apply to user.
so you want to use other sdks functions? Then simply do this before asking for consent with this library, not sure if I understand you here (I've never used MoPub). E.g.:
@Override
public void onConsentNeedsToBeRequested() {
// my library says you should ask the user for consent
// if you use withCheckRequestLocation(true), googles url did report that you are in the EAA
// otherwise the location check was not done yet, but the user did not give his consent yet
// make additional checks here via other API calls, e.g.
if (!MoPub.shouldGetConsent()) {
// oh, MoPub says we do not need to get consent here
return;
}
// show dialog
GDPR.getInstance().showDialog(this, mSetup);
}
as the comments above show, use it via the builder. The call is done asynchronously and the library is talking care for this. You can use the CheckLocationAsyncTask
yourself. I can make the inner function public as well, than you can use it in a Rx
chain or elsewehere manually as well if you want to...
No sorry. I meant to have a similar
public boolean canCollectPersonalInformation()
in your Library too.
So when I need to pass consent to other Netowks I can use it easily in something like
canCollectPersonalInfo = GDPR.canCollectPersonalInformation(); AppLovinPrivacySettings.setHasUserConsent(canCollectPersonalInfo, context);
Also for AdMob itself without any mediation, having maybe multiple Banner/Interstial/Native Ads to load in multiple activities etc:
If !canCollectPersonalInfo will create AdRequest with extras (to pass non personalized ads)
Bundle extras = new Bundle();
extras.putString("npa", "1");
AdRequest request = new AdRequest.Builder()
.addNetworkExtrasBundle(AdMobAdapter.class, extras)
.build();
If canCollectPersonalInfo will create AdRequest without extras
so your canCollectPersonalInformation()
should return if the user have given consent for personal data usage with my library?
This can be done like this:
GDPRConsent consent = GDPR.getInstance().getConsent();
boolean canCollectPersonalInformation = consent != null && consent == GDPRConsent.PERSONAL_CONSENT;
It should also check if it's an EEA location or not.
canCollectPersonalInformation should be true if consent == GDPRConsent.PERSONAL_CONSENT
but also if isRequestLocationInEeaOrUnknown
is false (and so consent == GDPRConsent.UNKNOWN
in the case that we show consent dialog only in EEA location)
Ok, the library will now save the location of the last request as well. Checkout GDPR.getInstance().getRequestLocation()
. You will get GDPRLocation.UNKNOWN
if the request times out or if you do not enable the location check via GDPR.withCheckRequestLocation(true)
.
Hope this helps...
EDIT
I replaced GDPRConsent
with GDPRConsentState
which is a class holding the GDPRConsent
now (and additionally it holds the date, app version and request location)
I was trying the version before your EDIT (1h ago) and I was getting GDPRLocation.UNKNOWN
even with GDPR.withCheckRequestLocation(true)
and my IP outisde of EEA.
When I was using IP inside EEA, I was instead getting GDPRLocation.EAA
Maybe I was doing something wrong, I will test again the new version. Thanks!
Checkout what you get from this url: http://adservice.google.com/getconfig/pubvendors This is what I use in this library, no fallback method though...
I get following answer from within the EAA (but have not tried it anywhere else):
{"is_request_in_eea_or_unknown":true}
At my real IP (out of Europe), I get {"is_request_in_eea_or_unknown":false}
you're right, there was a bug... fixed it now, it should work now
Thanks, seem to be working fine now.
So can maybe also add something like this now? to get consent + location anywhere in the app
boolean canCollectPersonalInformation() { GDPRConsentState consentState = GDPR.getInstance().getConsent(); GDPRConsent consent = consentState.getConsent(); // the given constent GDPRLocation location = consentState.getLocation(); // where has the given consent been given // If we don't know whether or not GDPR applies, then we haven't synced, so we cannot // collect personal information. if (location.equals(GDPRLocation.EAA) || location.equals(GDPRLocation.UNKNOWN)) { return false; } // If we are not in a GDPR region, we can freely collect user data. if (location.equals(GDPRLocation.NOT_IN_EAA)) { return true; } // Return whether or not we have consent. return consent.equals(GDPRConsent.PERSONAL_CONSENT); }
check out this function I've just added:
I think the method fulfills your requirements as well, so I'll close this.
I tried implementing the Consent SDK and I noticed some small differences compared to the MoPub solution in the consent flow/content. Below some screenshots and video too.
In the Consent SDK: 1) Back button does not close Dialogue nor Navigate Back (have own Back button in the dialogue layout) 2) CONSENT YES: just close the dialogue without any more confirmation messages 3) CONSENT NO (non personalized ads): next dialogue asks to actually Agree to non personalized or Back (not a simple Close as MoPub) 4) link to new dialogue to show all the Links of Networks, Services and Partners. (with the main/first dialogue not referencing directly any names of Networks or Partners or Services) 5) link to the App own Privacy Policy (in the other 2 dialogues other than the main one)
Personally I think the first 3 points are good and the 4-5 are worth considering.