DEA SDK for Android¶
Detect whether an app session comes from a real person. The SDK observes touch, stylus, mouse, scroll and device-motion input across the screens of your Android app and scores the session on the device.
On this page: Prerequisites · Install · Initialize the SDK · Ask for consent · Use the classification · Verify your setup · Before you release · Next steps
Prerequisites¶
- An
appIdandappKeyfor this app — see Accounts and keys minSdk21 (Android 5.0) or later. Attest needs a device on API 23 (Android 6.0) or later.- Kotlin or Java. The API is written in Kotlin; the samples in this guide are Kotlin.
The SDK is compiled with Kotlin 2.2.20 and Android Gradle Plugin 9.4.0, against compileSdk 35,
with Java 17 source and target compatibility. It ships native code for arm64-v8a, armeabi-v7a,
x86 and x86_64, so it runs on devices and on emulators.
Install¶
Not available yet. The current release, 0.19.0, is not published for Android. DEA's Maven repository,
https://sdk.dep-protocol.com/maven, servesai.dea:dea-sdk0.2.2 only, an earlier release whose API differs from this guide, and Maven Central has no DEA package. There is no dependency line that installs the SDK this guide describes.
The ai.dea:dea-sdk package depends on its companion library ai.dea:dea-base at the same
version, and on Google's Play Integrity library. Do not declare dea-base yourself at a different
version.
Platform setup¶
No setup is needed for capture. The SDK adds the INTERNET permission to your app's manifest
through manifest merging; it asks for no runtime permission. Motion sensors on Android need no
permission.
If your app restricts ABIs with ndk { abiFilters ... } or ABI splits, keep the ABIs your users'
devices need — the SDK cannot score on an ABI that was filtered out.
Attest has additional Play Integrity setup.
Initialize the SDK¶
Initialize once, in your Application.onCreate(), so that capture covers the whole session from
the first screen.
import ai.dea.sdk.DeaConfig
import ai.dea.sdk.DeaSdk
import android.app.Application
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
DeaSdk.init(
this,
DeaConfig(
appId = "YOUR_APP_ID",
appKey = "YOUR_APP_KEY",
),
)
}
}
Register the class in AndroidManifest.xml if you do not have one already:
appId and appKey are the pair DEA issued for this Android app; see
Accounts and keys. The SDK sends appKey in the
X-App-Key header when it registers the device key with DEA (Attest).
Without it, attest() answers UNSUPPORTED without contacting DEA. Reading the classification
does not use appKey: scoring runs on the device.
- Call
initon the main thread. initis safe to call more than once. A repeat call returns the running instance and keeps its options.initnever throws. If the scoring engine cannot start, the SDK keeps capturing without a score, the classification staysINSUFFICIENT, and the SDK reports the problem oncoreFault.- Pass your
Application. The SDK keeps theContextyou pass for as long as it runs, so anActivitypassed here stays in memory after it is destroyed. - Capture is global: the window of every activity, the motion sensors, and app lifecycle. There is
no base
Activityto extend, no view to wrap, and nothing to register per screen. Touches inside a dialog or a popup window, which Android gives a window of its own, are not captured. - At start, the SDK checks DEA's model host for a newer scoring model, in the background. See Model options and Privacy and network.
- Nothing is recorded until the user consents. See the next step.
Note: If you initialize from an
Activityinstead, for example after your own onboarding, the window already on screen is captured only when that activity is theContextyou pass, and the SDK then keeps that activity in memory. Activities started afterinitare captured whicheverContextyou pass.
Anywhere else in your code, get the running instance with DeaSdk.instance:
Ask for consent¶
By default the SDK records nothing until the user agrees. This step is required: an app that never asks collects no data and never gets a classification.
The SDK has a ready-made consent dialog. Show it on your first screen:
import ai.dea.sdk.DeaConsentDialog
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
DeaConsentDialog.show(this) { granted ->
// The user's answer, or the answer already on file.
}
}
}
- The answer is stored on the device. Once the user has answered,
showdisplays nothing and calls back at once with the stored answer, so you can call it on every launch. - Closing the dialog with the back button counts as no for this callback, but is not stored: the user is asked again next time.
- Call it on the main thread, with an activity that is showing.
To ask in your own UI instead, show your prompt when consent.isAnswered is false and record the
answer with setConsent:
import ai.dea.sdk.DeaSdk
import android.app.AlertDialog
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
val dea = DeaSdk.instance ?: return
if (!dea.consent.isAnswered) {
AlertDialog.Builder(this)
.setTitle("Help us keep bots out")
.setMessage("We measure how you interact with the app to tell people apart from bots.")
.setCancelable(false)
.setPositiveButton("Allow") { _, _ -> dea.setConsent(true) }
.setNegativeButton("Not now") { _, _ -> dea.setConsent(false) }
.show()
}
}
}
See User Consent for the dialog's wording, withdrawing, asking again, and shared devices.
Use the classification¶
Read the classification at the moment you make a decision. The read is synchronous and fast enough for the main thread.
import ai.dea.sdk.ClassificationResult
import ai.dea.sdk.DeaSdk
fun onSignUp(form: SignUpForm) {
when (DeaSdk.instance?.getClassification()?.result) {
ClassificationResult.HUMAN -> submitSignUp(form)
ClassificationResult.BOT -> rejectSignUp()
else -> showChallenge() // UNDETERMINED or INSUFFICIENT: a captcha, a delay, a manual review
}
}
getClassification() answers HUMAN, BOT, UNDETERMINED or INSUFFICIENT. What each one
allows is your decision. Right after launch it is INSUFFICIENT: the session is not
sufficient until it has as many
actions — taps, drags, scrolls — as the model asks for, 8 with
the built-in model. See Evidence.
Note: Before you block users on
getClassification(), read Going to production for the state of the model in the current release.
Verify your setup¶
- Turn on debug logging:
- Run a debug build and open Logcat in Android Studio, filtered on
[dea]. Accept your consent prompt and touch the screen. You should see a line per captured event:
If you see nothing after touching the screen, see Troubleshooting.
- Check the SDK from code:
import android.util.Log
import ai.dea.sdk.DeaSdk
val dea = DeaSdk.instance!!
Log.d("MyApp", "ready: ${dea.ready}") // true
Log.d("MyApp", "fault: ${dea.coreFault}") // null
Log.d("MyApp", "consent: ${dea.consent.decision}") // GRANTED
Log.d("MyApp", "model: ${dea.modelInfo}") // its version, and where it came from
val info = dea.sessionInfo
Log.d("MyApp", "session: ${info.session}") // a UUID
Log.d("MyApp", "sdk: ${info.sdk.version}")
Turn debug off before you ship.
Before you release¶
- [ ]
debugisfalse - [ ]
appKeyis passed toDeaSdk.init— see Options - [ ] Your app asks for consent — see User Consent
- [ ] The classification is read at the decision point, with a fallback for
UNDETERMINEDandINSUFFICIENT— see Human Scoring - [ ] Capture is paused on password and payment screens — see Sensitive Screens
- [ ]
reset()is called on logout — see Sessions - [ ]
attest()andrenewAttestation()are called off the main thread — see Attest - [ ] The app is set up for Play Integrity — see Attest
- [ ] You have read Going to production
Next steps¶
- User Consent — record, withdraw and re-ask consent
- Human Scoring — read the classification at a decision point
- Sensitive Screens — pause capture on password and payment screens
- Sessions — start a new session on logout
- Attest — register the device key with DEA
- Options — the options
initaccepts - How scoring works and Privacy and network
- Troubleshooting