Android

Fingerprint Pro identification in native Android apps

Fingerprint Pro's native Android integration allows developers to integrate device identification into native Android apps. Visit the official GitHub repository for examples and package downloads.

Please note that these Pro integrations require using our Fingerprint Pro API and thus need a public API key.

For native device identification for iOS, please go to iOS agent

Installing the agent

Add the repository to Gradle

If your version of Gradle is earlier than 7, add these lines to your build.gradle:

allprojects {   
  repositories {
  ...
  maven { url 'https://maven.fpregistry.io/releases' }
}}

If your version of Gradle is 7 or newer, add these lines to your settings.gradle:

repositories {
  ...
  maven { url 'https://maven.fpregistry.io/releases' }
}

Add dependencies to your build.gradle file

dependencies {
  implementation "com.fingerprint.android:pro:2.1.1"

  // If you use Java for you project, add also this line
  implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

When using Kotlin, be sure to specify the version in your build.gradle file:

buildscript {
    ext.kotlin_version = 'your-kotlin-version'
    ...

Note: You can find your Kotlin version in Android Studio > File > Settings > Languages & Frameworks > Kotlin.

Note: The library depends on kotlin-stdlib. If your application is written in Java, add the kotlin-stdlib dependency first — it's lightweight and has excellent backward/forward compatibility.

Lastly, sync Gradle to synchronize all the dependencies to your Android project.

Get the visitor identifier

Retrieve the visitor identifier using your public API key. You can find your public API key in your dashboard.

Kotlin example:

import com.fingerprintjs.android.fpjs_pro.Configuration
import com.fingerprintjs.android.fpjs_pro.FingerprintJSFactory
...

// Initialization
val factory = FingerprintJSFactory(applicationContext)
val configuration = Configuration(
    apiKey = "<<your_public_api_key>>"
  )
 
val fpjsClient = factory.createInstance(
    configuration
)

// Usage
fpjsClient.getVisitorId { result ->
    val visitorId = result.visitorId
    // Use the visitorId
}

Java example:

import com.fingerprintjs.android.fpjs_pro.Configuration;
import com.fingerprintjs.android.fpjs_pro.FingerprintJS;
import com.fingerprintjs.android.fpjs_pro.FingerprintJSFactory;
...

FingerprintJSFactory factory = new FingerprintJSFactory(this.getApplicationContext());
Configuration configuration = new Configuration(
    "your-public-api-key"
    );

FingerprintJS fpjsClient = factory.createInstance(
    configuration
);

fpjsClient.getVisitorId(visitorIdResponse -> {
    // Use the ID
    String visitorId = visitorIdResponse.getVisitorId();
    return null;
});

How unique and stable is the visitorId?

The ID is completely unique for every device. It is the same for different applications and it does not change after the application is reinstalled. Only factory reset can wipe it out – which is a common and legal case (the device may be resold or gifted to another person).

Configuration

When create instance of the FingerprintJS class there are options that can be configured:

class Configuration @JvmOverloads constructor(
    val apiToken: String,
    val region: Region = Region.US,
    val endpointUrl: String = region.endpointUrl,
    val extendedResponseFormat: Boolean = false
)

Response format

If extendedResponseFormat flag is set in the Configuration class then in the response there will be such fields as shown below:

data class FingerprintJSProResponse(
    val requestId: String,
    val visitorId: String,
    val confidenceScore: ConfidenceScore,
    val visitorFound: Boolean, // Available with extendedResponseFormat == true
    val ipAddress: String, // Available with extendedResponseFormat == true
    val ipLocation: IpLocation?, // Available with extendedResponseFormat == true
    val osName: String, // Available with extendedResponseFormat == true
    val osVersion: String, // Available with extendedResponseFormat == true
    val firstSeenAt: Timestamp, // Available with extendedResponseFormat == true
    val lastSeenAt: Timestamp // Available with extendedResponseFormat == true
)

data class IpLocation(
    val accuracyRadius: Int,
    val latitude: Double,
    val longitude: Double,
    val postalCode: String,
    val timezone: String,
    val city: City,
    val country: Country,
    val continent: Continent,
    val subdivisions: List<Subdivisions>
) {

    data class City(
        val name: String
    )

    data class Country(
        val code: String,
        val name: String
    )

    data class Continent(
        val code: String,
        val name: String
    )

    data class Subdivisions(
        val isoCode: String,
        val name: String
    )
}

data class ConfidenceScore(
    val score: Double
)
  
  
data class Timestamp(
    val global: String,
    val subscription: String
)

Error handling

fpjsClient.getVisitorId(
          listener = { result ->
            // Handle ID
          },
          errorListener = { error ->
            when(error){
                is ApiKeyRequired -> {
                    val requestId = error.requestId
                  // Handle error
              }
                ...
            }
          })

Error is a sealed class


sealed class Error(
    val requestId: String = UNKNOWN,
    val description: String? = UNKNOWN
)

and it might me one of:

  • ApiKeyRequired
  • ApiKeyNotFound
  • ApiKeyExpired
  • RequestCannotBeParsed
  • Failed
  • RequestTimeout
  • TooManyRequest
  • OriginNotAvailable
  • HeaderRestricted
  • NotAvailableForCrawlBots
  • NotAvailableWithoutUA
  • WrongRegion
  • SubscriptionNotActive
  • UnsupportedVersion
  • InstallationMethodRestricted
  • ResponseCannotBeParsed
  • NetworkError
  • UnknownError

Tag support to store custom data with each identification

fpjsClient.getVisitorId(
      tags = mapOf("sessionId" to sessionId),
      listener = { result ->
          // Handle ID
      },
      errorListener = { error ->
          // Handle error
      })

Tags are returned in the webhook response so make sure the map you are passing to the library represents a valid JSON.

Linked ID support

```kotlin
 fpjsClient.getVisitorId(
      linkedId = "your_linked_id",
      listener = { result ->
          // Handle ID
      },
      errorListener = { error ->
          // Handle error
      })
```

You can use both tags and linked id:

fpjsClient.getVisitorId(
     tags = mapOf("sessionId" to sessionId),
     linkedId = "your_linked_id",
     listener = { result ->
          // Handle ID
      },
      errorListener = { error ->
          // Handle error
      })

Additional Resources


Did this page help you?