User Consent¶
Part of the Human Scoring use case.
The SDK records how the user interacts with your app, so by default it records nothing until the user agrees. The SDK ships a ready-made consent dialog, and you can replace it with your own UI without losing the guarantee.
When to use it¶
- Always, unless your app already obtains consent before calling
DeaSdk.init— in that case, setrequireConsent: false - To change the wording of the dialog, or translate it
- To let the user withdraw consent from a settings screen
Prerequisites¶
- The SDK is installed and initialized. See the Quick Start.
Usage¶
Show the built-in dialog¶
- The answer is stored on the device. Once the user has answered, later calls return the stored answer without showing anything, so it is safe to call on every launch.
- The dialog follows your app theme's platform: by default a Material dialog on Android and a Cupertino alert on iOS.
- It cannot be dismissed by tapping outside. If it closes any other way (for example the back
button), it returns
falsebut records nothing, so the user is asked again next time.
Change the wording¶
await showDeaConsentDialog(
context,
copy: const ConsentCopy(
title: 'Help us keep bots out',
body: 'We measure how you interact with the app to tell people apart from bots.',
recorded: ['Where you touch, and how hard', 'How the phone moves in your hand'],
notRecorded: ['What you type', "What's on your screen"],
closing: 'You can change this at any time in Settings.',
accept: 'Allow',
decline: 'Not now',
),
);
Pass an empty list to recorded or notRecorded to hide that section. Make sure the lists stay
true for your app.
Choose the dialog style¶
await showDeaConsentDialog(context, style: ConsentDialogStyle.material); // or .cupertino, .adaptive
Use your own UI¶
Draw your own dialog or onboarding step, then record the answer:
await DeaSdk.instance?.setConsent(true); // the user agreed
await DeaSdk.instance?.setConsent(false); // the user declined
Recording starts or stops as soon as setConsent is called; awaiting only waits for the answer to
be stored.
Read the current answer¶
final consent = DeaSdk.instance!.consent;
consent.isAnswered; // false until the user has answered
consent.isGranted; // true only if the user agreed
consent.decision; // ConsentDecision.unknown, .granted or .denied
Withdraw consent¶
Recording stops immediately, and input the SDK was still holding back is discarded. The session is
kept, so if the user agrees again, recording continues in the same session. What was scored before
the withdrawal stays in the session's classification; call
reset() as well to start again from nothing.
Ask again¶
forget() clears the stored answer, so the next showDeaConsentDialog call asks again — for
example when a different account signs in on the same device. Unlike declining, it is not an
answer. With requireConsent on (the default), nothing is recorded until the user answers again.
Shared devices¶
When a different person may use the device each session (a kiosk, a test device), do not store the answer:
With remember: false any stored answer is cleared first, the dialog is shown on every call, and
the new answer is not stored.
Examples¶
Ask on the first screen¶
import 'package:dea_sdk/dea_sdk.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) showDeaConsentDialog(context);
});
}
@override
Widget build(BuildContext context) => const Scaffold(body: Center(child: Text('Home')));
}
A settings switch¶
import 'package:dea_sdk/dea_sdk.dart';
import 'package:flutter/material.dart';
class DeaConsentTile extends StatefulWidget {
const DeaConsentTile({super.key});
@override
State<DeaConsentTile> createState() => _DeaConsentTileState();
}
class _DeaConsentTileState extends State<DeaConsentTile> {
@override
Widget build(BuildContext context) {
final dea = DeaSdk.instance;
return SwitchListTile(
title: const Text('Bot protection'),
subtitle: const Text('Measure how I interact with the app'),
value: dea?.consent.isGranted ?? false,
onChanged: dea == null
? null
: (value) async {
await dea.setConsent(value);
setState(() {});
},
);
}
}
API¶
| Member | Returns | Description |
|---|---|---|
showDeaConsentDialog(context, {copy, style, remember, ask}) |
Future<bool> |
Shows the dialog if needed and returns the answer. ask: false only reads the stored answer |
DeaSdk.setConsent(granted, {remember}) |
Future<void> |
Records the answer |
DeaSdk.consent |
Consent |
The current answer |
Consent.isAnswered |
bool |
Whether the user has answered |
Consent.isGranted |
bool |
Whether the user agreed |
Consent.decision |
ConsentDecision |
unknown, granted or denied |
Consent.forget() |
Future<void> |
Clears the stored answer |
Consent.addListener(listener) / removeListener(listener) |
void |
Be notified when the answer changes |