To support GDPR requirements this library helps manage settings for different tracking services and supports multiple flows to manage when a user agrees to the terms of service and/or the privacy policy.
Those features include:
- Display a list of integrated tracking services that can be enabled or disabled. If supported, they a user can also have their data deleted.
- Display the terms of service / privacy policy in a separate Activity / WebView
The list of integrated services typically contains entries like Firebase Analytics, Crashlytics, etc. The list can be customized via xml and an attribute in the app's manifest.
Each service can show its title and description. They can be enabled or disabled individually and (optionally) provide an option to have the user data deleted.
Be sure to run the demo app
to get an idea on what this library can do for you!
Start by adding the URLs for your terms of service and privacy policy as <meta-data />
to your <application>
tag in the manifest. If your policies don't have a static URL then you can always set them later at runtime. Also include the ID of your XML file that holds the list of integrated services.
<meta-data
android:name="@string/gdpr_sdk__tos"
android:value="@string/tos" />
<meta-data
android:name="@string/gdpr_sdk__policy"
android:value="@string/privacy_policy" />
<meta-data
android:name="@string/gdpr_sdk__services"
android:resource="@xml/gdpr_services" />
Next, create a services.xml
resource file in your res/xml
directory. Here you can list the services integrated in your app.
<services />
:
isOptIn <true|false>
: Defines the default setting for your services, whether they should be optIn by default. If set totrue
, all services will be disabled by default.
<service />
:
id <String>
The ID of the service. This will be used to distinguish between which services are enabled.name <String|StringResource>
The name of the servicedescription <String|StringResource>
The description of the service (optional)isOptIn <true|false>
Whether this service should be optIn and disabled by default. Defaults toservices.isOptIn
.supportsDeletion <true|false>
Whether this service supports deletion of user data. Defaults tofalse
For an example see app/../gdpr_services.xml
The appearance (colors, fonts, ...) can be customized using Android's themes. A few custom attributes were introduced for the styling of the list elements and need to be set as a theme for the GDPRActivity
.
<!-- You can simply extend your app theme and add those 4 attributes,
or use any of the AppCompat themes as parent -->
<style name="AppTheme.GDPR" parent="Theme.AppCompat.DayNight.DarkActionBar">
<!-- Text for subheaders in the settings -->
<item name="gdpr_headerTextAppearance">@style/TextAppearance.AppCompat.Body2</item>
<!-- Body text for descriptions and such -->
<item name="gdpr_textAppearance">@style/TextAppearance.AppCompat.Body1</item>
<!-- Style for the button at the bottom of the confirmation flow -->
<item name="gdpr_confirmButtonStyle">@style/Widget.AppCompat.Button.Borderless.Colored</item>
<!-- Style for the "links" to the ToS and Privacy Policy -->
<item name="gdpr_linkButtonStyle">@style/LinkButton</item>
<!-- Style for other buttons (accept all, delete) -->
<item name="borderlessButtonStyle">@style/BorderlessButton</item>
<!-- Switch style -->
<item name="switchStyle">@style/Switch</item>
</style>
Make sure to use an AppCompat or Bridge (Material Components) theme for this Activity.
<activity
android:name="at.allaboutapps.gdpr.GDPRActivity"
android:theme="@style/AppTheme.GDPR" />
On your registration you should link to the terms of service and privacy policy that the user has to accept. You can use PrivacyPolicySwitch
which provides a link next to a switch, or you can implement your own.
You can use GDPRPolicyManager.instance().newSettingsIntent(showToSInfo = true)
to get an intent to start the Settings Activity.
<at.allaboutapps.gdpr.widget.PrivacyPolicySwitch
android:id="@+id/policy_accepted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I accept the <annotation link="privacy">Privacy Policy</annotation> and <annotation link="tos">Terms of Service</annotation>"
android:paddingEnd="?android:listPreferredItemPaddingEnd"
android:paddingStart="?android:listPreferredItemPaddingStart" />
To keep track of when a user accepted the terms of service you need to update the saved timestamp by calling one of the provided methods. This information is used to infer whether something changed since it was last seen by the user.
GDPRPolicyManager.instance().setPolicyAccepted(true) // if local, uses current timestamp
GDPRPolicyManager.instance().setPolicyAccepted(timestamp) // queried from server
You should query your server about changes to the policy. Call manager.updateLatestPolicyTimestamp(timestamp)
to update the saved timestamp of the last policy changes. You could do this at every app start, or from a background job.
In your Activity you can use manager.shouldShowPolicy()
to check the current status and display a dialog.
You can extend PolicyUpdateDialogFragment
if you need some further customizations on the dialog design.
@Override
protected void onStart() {
super.onStart();
// ... other code
if (GDPRPolicyManager.instance().shouldShowPolicy()) {
PolicyUpdateDialogFragment.newInstance().show(getSupportFragmentManager());
}
}
The library will send broadcasts whenever something changes, e.g. when the user
- accepts the policy, either from calling
setPolicyAccepted
or when the user accepts the new policy from the dialog - enables or disables a service
GdprServiceIntent.ACTION_POLICY_ACCEPTED
and GdprServiceIntent.ACTION_SERVICES_CHANGED
will be sent respectively to any receivers registered in the app.
<receiver
android:name=".ServicesBroadcastReceiver"
android:exported="false">
<intent-filter>
<action android:name="at.allaboutapps.gdpr.SERVICES_CHANGED" />
<action android:name="at.allaboutapps.gdpr.POLICY_ACCEPTED" />
</intent-filter>
</receiver>
In this receiver you should send or queue the updates to the server as well as start/stop your tracking services.