Add the Library
Once you have your licence key, follow these steps to add the DeviceAssure Android Library to your project.
System Requirements
Before you begin, ensure your project meets the following requirements:
| Requirement | Version |
|---|---|
| JDK | 11 or higher |
| Minimum SDK | API v21 (Android 5.0) |
| Target API | 34 |
Step 1: Configure Gradle Repositories
Add the DeviceAssure Maven repository to your project's build.gradle file:
repositories {
mavenCentral()
google()
maven { url "https://java-api.deviceatlas.com/<LICENCE_KEY>/" }
}
Replace <LICENCE_KEY> with your DeviceAssure licence key.
Step 2: Add the Dependency
Add the DeviceAssure library dependency to your app's build.gradle file:
Replace <LIBRARY_VERSION> with the latest library version, listed on the Getting Started with DeviceAssure for Apps page.
Runtime Dependencies
The library is written in Kotlin and uses coroutines internally on every validation path, the callback API included. Both of the following are runtime dependencies declared in the library's own Maven POM, so resolving it from the Maven repository (Step 2) pulls them onto your application's runtime classpath automatically — regardless of whether your application applies the Kotlin Android plugin, and whether you're integrating from Java or Kotlin:
| Dependency | Minimum version | Supplied automatically? |
|---|---|---|
org.jetbrains.kotlin:kotlin-stdlib | 1.9.22 | Yes, via the library's own Maven POM |
org.jetbrains.kotlinx:kotlinx-coroutines-android | 1.7.3 | Yes, via the library's own Maven POM |
Each minimum is the version the library itself is compiled against. A newer version of either is fine; an older one may be missing symbols the library references. For coroutines this is about the library's internals rather than your own code — no coroutine type appears in the DeviceAssure API, so there is nothing to match at your call site.
If you add the library as a raw .aar file rather than resolving it from the Maven repository, no dependency information accompanies it, and you must declare both of these yourself:
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.9.22"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
}
Declare the Android coroutines artifact rather than kotlinx-coroutines-core. It brings the core artifact with it and adds the main-thread dispatcher the library uses to deliver results to your Callback, which the core artifact alone does not supply.
Kotlin callers using the suspending API write their own coroutine builder (for example lifecycleScope.launch { }) to call into it. That's compile-time code of your own, and a runtime dependency resolved transitively from the POM above is not visible on your compile classpath even though it's already present at runtime — so add coroutines as your own compile dependency too if you use the suspending API, on either integration route.
Important: On the raw-
.aarroute, both failures appear at runtime, not at build time. Without the standard library the first call into DeviceAssure fails withNoClassDefFoundError: kotlin/jvm/internal/Intrinsics; without coroutines it fails with aNoClassDefFoundErroron akotlinx/coroutinesclass. The build succeeds either way, so this only appears when the library is first used.
Step 3: Permissions
Integrating the DeviceAssure library adds the following permissions to your application automatically, and none of them needs to be requested at runtime:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.QUERY_ADVANCED_PROTECTION_MODE" />
READ_PHONE_STATE is not merged in. If your application needs the TAC and Manufacturer Code on Android 9 (API 28) and lower, it must declare and request that permission itself, as described below.
These permissions can be overridden by your host application if needed.
Permission Details
| Permission | Merged automatically | Purpose |
|---|---|---|
INTERNET | Yes | Required to send collected data to the DeviceAssure service |
ACCESS_NETWORK_STATE | Yes | Required to check network connectivity |
CAMERA | Yes | Used to read camera hardware characteristics as part of the device profile. Does not require a runtime grant — the characteristics are read without opening the camera. |
BLUETOOTH | Yes | Used to query Bluetooth capabilities. An install-time permission — no runtime request is required. |
ACCESS_WIFI_STATE | Yes | Used to read the supported Wi-Fi standards and Wi-Fi features (Aware, Direct, Passpoint, RTT) as part of the device profile. An install-time permission — no runtime request is required. |
QUERY_ADVANCED_PROTECTION_MODE | Yes | Used by the DeviceAssure library to detect Android Advanced Protection status on Android 16 (API 36) and higher. An install-time permission — no runtime request is required, and the check is skipped on devices below API 36. |
READ_PHONE_STATE | No | Optional, and must be declared by your own application. Required to obtain the TAC and Manufacturer Code on Android 9 (API 28) and lower. For Android 10 (API 29) and higher, TAC and Manufacturer Code will be collected without requiring this permission. The library also withholds two further telephony properties — hearing aid compatibility and TTY mode support — unless it is granted, on API 23 and higher; that is a library guard rather than an Android requirement. |
Note: The permissions merged in above will appear in your app's merged manifest (and therefore its store listing), but none needs to be declared or requested by your application.
READ_PHONE_STATEis the only permission your host application must declare and request itself.Note: The TAC (Type Allocation Code) is a non-PII property that identifies the make and model of the device and is used to validate the device. Omitting it may result in an incomplete validation.
Declaring and Requesting READ_PHONE_STATE
To obtain the TAC and Manufacturer Code on Android 9 (API 28) and lower, declare the permission in your own application's manifest:
READ_PHONE_STATE is also a runtime ("dangerous") permission. On Android 6.0 (API 23) through Android 9 (API 28), declaring it in the manifest is not enough — your application must also request it at runtime and have it granted before the TAC can be read.
The requirement stops at Android 9 because of how the TAC is obtained on each platform:
- Android 9 (API 28) and lower — the TAC is derived from the device's IMEI, which is protected by
READ_PHONE_STATE. Without the granted permission the IMEI, and therefore the TAC, cannot be read. - Android 10 (API 29) and higher — the platform returns the TAC directly without exposing the IMEI, so no phone-state permission is required.
Note: The TAC is not the only thing affected. The DeviceAssure library reads two further telephony properties — hearing aid compatibility and TTY mode support — only when
READ_PHONE_STATEhas been granted, on Android 6.0 (API 23) and higher. This is a guard inside the library rather than an Android requirement: neither property needs a permission at the platform level. It does mean they are omitted from the device profile without the permission, on every Android version, including Android 10 and above where the TAC itself needs none. Validation still proceeds; the profile is simply less complete. The guard is expected to be removed in a future release.Important: The DeviceAssure library checks permission status but does not request permissions itself. Your host application is responsible for requesting any required permissions before calling
DeviceAssure.check()orDeviceAssure.getData(). If the permission has not been granted on Android 9 and below, validation still proceeds but the TAC is omitted, which may result in an incomplete validation.
Transport Security
The library validates the TLS certificate of the endpoint it sends data to, against the device's trust store, and will refuse to send the request if the certificate cannot be validated.
The DeviceAssure service's own certificate is publicly issued, so a standard integration needs no configuration for this and no action on your part.
If your application restricts trust with a network security configuration, the DeviceAssure endpoints must remain trusted under it, or validation requests will fail.
See Also
- Basic Integration - Integrate DeviceAssure into your application
- Client to Server - Direct validation from the app
- Server to Server - Validation via your backend server