Developed by Konrad Kollnig, Department of Computer Science, University of Oxford
This repository shall help app developers implement consent in apps more easily. This helps compliance with the GDPR, CCPA and other legal regimes. The motivation for this project that our research at Oxford found that less than 4% of Android apps implement any form of consent. It puts our previous compliance guide from the website https://gdpr4devs.com into code. Unfortunately, most existing mobile consent solutions are limited in their functionality, costly, and may not actually help with GDPR compliance.
Specifically, this tool targets the following common compliance problems:
Common Problem 1: Failure to to implement any consent flows. This can both involve 1) the sharing of data with third-party companies without consent (violating Articles 7 and (35)1 GDPR) and 2) non technically-necessary accessing or storing of data on smartphone (violating Article 5(3) ePrivacy Directive)
Solution: Automatic implementation of consent flows with this library.
Common Problem 2: Sharing more data than necessary (violating Article 4(1) GDPR).
Solution: Many third-party libraries come with configuration options to reduce data collection. This library automatically chooses some of the most common settings.
At the moment, this project automatically implements a consent flow if your app uses one of the following SDKs:
- Google Firebase Analytics
- Google Crashlytics
- Google Ads
- Facebook SDK
- AppLovin
- Flurry (disabled SDK if lack of consent altogether)
- InMobi
- AppsFlyer
- ironSource
- AdColony
- Vungle (untested)
- Google Play Services Advertising Identifier Library
Note that the use of Google and Facebook services in the EU is likely illegal even with user consent, because data is sent to the US and can be used for unlawful surveillance of EU citizens. The same applies to other US-based services.
NOTE THAT THE USE OF THIS TOOL COMES AT YOUR OWN RISK. THIS TOOL CANNOT REPLACE AND DOES NOT PROVIDE EXPERT LEGAL ADVICE. IT IS CURRENTLY NOT MEANT FOR PRODUCTION USE, BEING AN ALPHA RELEASE.
- Add the JitPack repo:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
- Add the library:
dependencies {
implementation 'com.github.kasnder:app-consent-android:0.8'
}
- Initialise the library by calling
ConsentManager consentManager =
new ConsentManager.Builder(this)
.setPrivacyPolicy(Uri.parse("http://www.example.org/privacy"))
.build();
- If you want to, you can change the title (or message) in the consent flow by changing
the
consent_title
(orconsent_msg
) string. - If you want to exclude certain libraries from the consent flow (e.g. the opt-in to the use of the
Advertising ID), then use the
setExcludedLibraries()
method of theConsentManager.Builder
. For example, for Firebase Analytics:.setExcludedLibraries(new String[]{"firebase_analytics"})
. You can see the identifiers of all currently managed libraries throughconsentManager.getManagedLibraries()
. - By extending the class
net.kollnig.consent.library.Library
, you can connect further libraries. Use thesetCustomLibraries()
method of theConsentManager.Builder
to include them, e.g..setCustomLibraries(new Library[]{new CustomLibrary()})
. See the directorylibrary/src/main/java/net/kollnig/consent/library/
for example implementations.
You can check the example project in app/
to see how the library is used.
This tool interacts with third-party libraries in three ways: 1) by setting options in
the AndroidManifest.xml
file, 2) by calling functions of the third-party library directly (through
Reflection), and 3) by intercepting method calls to the third-party library and either adding more
privacy-preserving options or preventing the call to that function altogether.
The third method is the most invasive and only taken when no alternatives are available. It relies on YAHFA (Yet Another Hook Framework for ART) to hook functions of third-party libraries. Since YAHFA is only compatible with Android 7–12, lower Android versions are not supported by the library. This might be addressed in future versions of this library.
The following gives more details on how this tool interacts with third-party libraries.
Note that the use of Google and Facebook services in the EU is likely illegal even with user consent, because data is sent to the US and can be used for unlawful surveillance of EU citizens. The same applies to other US-based services.
Purpose: Analytics
How consent is implemented: Automatic data collection upon the first app start is managed through the setAnalyticsCollectionEnabled
setting. This prevents the collection of analytics without user consent.
Further reduced data collection: The tool disables the settings google_analytics_ssaid_collection_enabled
(to prevent the collection of the ANDROID_ID) and google_analytics_default_allow_ad_personalization_signals
(to prevent the use of data for ads). If you need the sharing of analytics data for ads, you can add the following to your <application>
tag in your AndroidManifest.xml
file:
<meta-data android:name="google_analytics_default_allow_ad_personalization_signals" tools:node="remove"/>
Uses hooks: No
Further details: https://firebase.google.com/docs/analytics/configure-data-collection?platform=android
Purpose: Crash reporting
How consent is implemented: Automatic data collection upon the first app start is prevented through the setCrashlyticsCollectionEnabled
setting. This prevents the collection of crash reports without user consent.
Further reduced data collection: None, except that the firebase_crashlytics_collection_enabled
flag is set to false
in the AndroidManifest.xml
file to implement consent.
Uses hooks: No
Further details: https://firebase.google.com/docs/crashlytics/customize-crash-reports?platform=android
Purpose: Ads
How consent is implemented: If no consent is given, calls to the init
and loadAd
methods are blocked. This prevents communication with the Google Ads servers without user consent. As per Google’s consent policies, the use of Google Ads is only permitted with user consent (even of non-personalised ads).
Further reduced data collection: None, except that the com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT
flag is set to false
in the AndroidManifest.xml
file to implement consent.
Uses hooks: Yes
Further details: https://developers.google.com/admob/ump/android/quick-start
Purpose: Various functionality, including analytics
How consent is implemented: Automatic data collection upon the first app start is prevented through the setAutoInitEnabled
and setAutoLogAppEventsEnabled
settings. This prevents the collection of analytics without user consent.
Further reduced data collection: None, except that the com.facebook.sdk.AutoInitEnabled
and com.facebook.sdk.AutoLogAppEventsEnabled
are flags set to false
in the AndroidManifest.xml
file to implement consent.
Uses hooks: No
Further details: https://developers.facebook.com/docs/app-events/gdpr-compliance/
Purpose: Ads
How consent is implemented: Automatic data collection upon the first app start is prevented through the setDoNotSell
and setHasUserConsent
settings.
Further reduced data collection: None
Uses hooks: No
Further details: https://dash.applovin.com/documentation/mediation/android/getting-started/privacy
Purpose: Various functionality, including analytics
How consent is implemented: If no consent is given, calls to the build
method (from the FlurryAgent.Builder
class) are blocked. This prevents the start of the SDK without user consent.
Further reduced data collection: None
Uses hooks: Yes
Further details: https://developer.yahoo.com/flurry/docs/integrateflurry/android/
Purpose: Ads
How consent is implemented: If no consent is given, then gdpr_consent_available=false
and gdpr=1
is passed to the init()
method of InMobi.
Further reduced data collection: None
Uses hooks: Yes
Further details: https://support.inmobi.com/monetize/android-guidelines/
Purpose: Ad attribution
How consent is implemented: If no consent is given, calls to the start()
method of AppsFlyer are prevented.
Further reduced data collection: None
Uses hooks: Yes
Further details: https://support.appsflyer.com/hc/en-us/articles/360001422989-User-opt-in-opt-out-in-the-AppsFlyer-SDK
Purpose: Ads
How consent is implemented: Depending on the consent setting, setConsent
and the do_not_sell
flags are set.
Further reduced data collection: Depending on the consent setting, the is_deviceid_optout
flag is set.
Uses hooks: No
Further details: https://developers.is.com/ironsource-mobile/android/regulation-advanced-settings/#step-1
Purpose: Ads
How consent is implemented: Depending on the consent setting, setPrivacyFrameworkRequired
and setPrivacyConsentString
are called. This happens both at the time of initialising the SDK (i.e. on calling AdColony.configure()
) and when the user might change the setting (by calling AdColony.setAppOptions()
). Other appOptions
should be kept intact in this process.
Further reduced data collection: None
Uses hooks: Yes
Further details: https://github.com/AdColony/AdColony-Android-SDK/wiki/Privacy-Laws
Purpose: Ads
How consent is implemented: Consent is passed to the Vungle library through its updateConsentStatus
setting, either setting this to OPTED_IN
or OPTED_OUT
. Additionally, the current consent signal is passed once the initialisation of the Vungle library is finished.
Further reduced data collection: None
Uses hooks: Yes
Further details: https://support.vungle.com/hc/en-us/articles/360047780372-Advanced-Settings
Purpose: User identification
How consent is implemented: Calls to the getAdvertisingIdInfo
method throw an IOException
if no consent is provided. The use of the IOException
is one of the exceptions of the method signature and should be caught by apps in any case.
Further reduced data collection: None
Uses hooks: Yes
Further details: https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient
Before developing our tool, we first studied what consent tools for mobile apps already existed out there. For this purpose, we searched Google and GitHub for the terms “cmp mobile app” and “consent mobile app”.
Name | Relies on IAB? | Native | Open Source | Free | Automatic set-up |
---|---|---|---|---|---|
GDPRConsent | No | Yes | Yes | Yes | No |
gdprsdk | Yes | Yes | Yes | Yes | IAB |
OneTrust App Consent | ? | ? | No | No, no public pricing | |
Usercentrics App Consent | Yes | Yes | Yes | No, €4+/month | IAB |
UniConsent | Yes | ? | No | No, £20+/month | IAB |
TrustArc Mobile App Consent | ? | ? | No | No | |
Choice by Kochava and Quantcast | Yes | Yes | No | No | IAB |
Cookie Information | No | Yes | Yes | No, €125+/month | |
iubenda Consent Solution | Yes | Yes, but not public | No | No, $10+/month | IAB |
Ogury Choice Manager | Yes | Yes | No | No, no public pricing | IAB |
Tamoco Consent SDK | Yes | Yes | No | No, no public pricing | IAB |
CookiePro by OneTrust | Yes | Yes | No | No, $200+/month | IAB |
consentmanager.net | Yes | Yes | No | No, €49+/month | IAB |
FreeCMP by TrueData | ? | Yes | No | No public pricing | |
Osano Consent Management | Yes | Yes, beta | No | No, £470+/month | IAB |
Didomi | Yes | Yes | No | No, €300+/month | IAB |
SFBX CMP | Yes | Yes | No | Yes, with limits | IAB |
Google Consent API (discontinued) | No | Yes | Yes | Yes | No |
Google User Messaging Platform | Yes | Yes | No | Yes | IAB |
Having studied these different tools, most of them did not seem to be aimed at mobile apps (and rather just ports from desktop) or were not mature yet. This motivated our subsequent development of “auto-app-consent”.
Contributions to this project are highly welcome. Help is welcome with testing, improving the stability of the existing code, keeping up with changes of the third-party libraries and contributing new adapters for third-party libraries.
Feel free to file an issue or pull request with any of your ideas!
This project is licensed under GPLv3.