Start using packagecloud in minutes
Join thousands of developers using packagecloud to distribute software securely, consistently, and affordably.
README
last updated: Thu 03/20/25 at 07:43:20 PM bylucas-yupistudios
BioPass ID Fingerprint SDK Android
Latest Version
March 20, 2025 - [v2.1.4]
Table of Contents
Quick Start Guide
First, you will need a license key to use the SDK. To get your license key contact us through our website BioPass ID.
Check out our official documentation for more in depth information on BioPass ID.
1. Prerequisites:
Attention: To use Fingerprint you will need a physical device, Fingerprint does not work on emulators.
- Java 17 or higher
- Kotlin 1.9.0 or highr
- Gradle 8.6 or higher
- Android Gradle Plugin 8.4.0 or higher
- A physical device with a camera
- License key
- Internet connection is required to verify the license
Before proceeding, you should add the following dependencies in your app/build.gradle
file:
dependencies
implementation 'com.biopassid:dlibwrapper:1.0.0'
implementation 'androidx.camera:camera-core:1.3.4'
implementation 'androidx.camera:camera-camera2:1.3.4'
implementation 'androidx.camera:camera-lifecycle:1.3.4'
implementation 'androidx.camera:camera-view:1.3.4'
Then on your settings.gradle
file:
repositories
maven
url "https://packagecloud.io/biopassid/dlibwrapper/maven2"
Change the minimum Android sdk version to 24 (or higher) in your app/build.gradle
file.
minSdkVersion 24
2. Installation
With Gradle
The simplest and easiest way to install the plugin to your project, is to just add the following dependencies to your app/build.gradle
:
dependencies
implementation 'com.biopassid:fingerprintsdk:2.1.4'
Then on your settings.gradle
file:
repositories
maven
url "https://packagecloud.io/biopassid/FingerprintSDKAndroid/maven2"
With Local File
Another alternative to use Fingerprint SDK is to download and install the AAR file locally. Here you can find the latest releases and after downloading place the .aar file in any folder of your choice.
We will use Android Studio for the following steps:
- First, with your project open, go to File --> Project Structure --> Dependencies.
- Then in the Dependencies tab, select your app in the modules tab and click on the plus symbol to show the option to add a JAR/AAR dependency.
- On step 1 input the AAR file path, and select the implementation option on step 2.
- Just rebuild your project and should be ready to use.
3. How to use
Basic Example
By now you should have all the tools available to start using the lib in your own project. You can configure some settings like capture type, output type and the number of fingers to capture. You can launch Fingerprint using the View or Activity. Here is a code example showing how to use Fingerprint SDK.
Using View
1. Create the Person data class
package com.example.fingerprintdemo
import android.graphics.Bitmap
object Person
var fingers: List<Bitmap> = ArrayList()
2. In xml layout of your main activity
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btnCapture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Finger Capture"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. In your main activity
package com.example.fingerprintdemo
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity()
private val TAG = "FingerprintDemo"
private lateinit var btnCapture: Button
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Button in your xml layout responsible for calling the Fingerprint SDK
btnCapture = findViewById(R.id.btnCapture)
// Register ActivityForResult
val intentLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) result: ActivityResult ->
if (result.resultCode == RESULT_OK)
Log.d(TAG, "Images: $Person.fingers")
// Start CameraActivity
btnCapture.setOnClickListener
val intent = Intent(this, CameraActivity::class.java)
intentLauncher.launch(intent)
4. Create a xml layout for camera activity and add FingerprintView
to it
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CameraActivity">
<br.com.biopassid.fingerprintsdk.ui.view.FingerprintView
android:id="@+id/fingerprintView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:licenseKey="your-license-key"
app:numberFingersToCapture="4"
app:textFontFamily="@font/fingerprintsdk_opensans_regular"
app:overlayColor="#80000000"
app:timeToCapture="5"
app:captureCountdownEnabled="true"
app:captureCountdownBackgroundColor="#50888888"
app:captureCountdownProgressColor="#D6A262"
app:captureCountdownTextColor="#FFFFFF"
app:captureType="leftHandFingers"
app:outputType="captureAndSegmentation"
app:fingerEllipseEnabled="true"
app:fingerEllipseColor="#80D6A262"
app:distanceIndicatorEnabled="true"
app:distanceIndicatorSelectedBarColor="#D6A262"
app:distanceIndicatorUnselectedBarColor="#FFFFFF"
app:distanceIndicatorArrowColor="#D6A262"
app:distanceIndicatorTooCloseTextEnabled="true"
app:distanceIndicatorTooCloseTextContent="Muito perto"
app:distanceIndicatorTooCloseTextColor="#FFFFFF"
app:distanceIndicatorTooCloseTextSize="14sp"
app:distanceIndicatorTooFarTextEnabled="true"
app:distanceIndicatorTooFarTextContent="Muito longe"
app:distanceIndicatorTooFarTextColor="#FFFFFF"
app:distanceIndicatorTooFarTextSize="14sp"
app:helpTextEnabled="true"
app:helpTextColor="#FFFFFF"
app:helpTextSize="14sp"
app:helpTextLeftHandMessage="Encaixe a mão esquerda (sem o polegar)\naté o marcador ficar centralizado."
app:helpTextRightHandMessage="Encaixe a mão direita (sem o polegar)\naté o marcador ficar centralizado."
app:helpTextThumbsMessage="Encaixe os polegares\naté o marcador ficar centralizado."
app:backButtonEnabled="true"
app:backButtonBackgroundColor="#00000000"
app:backButtonPadding="0dp"
app:backButtonWidth="56dp"
app:backButtonHeight="56dp"
app:backButtonIconEnabled="true"
app:backButtonIconFile="@drawable/fingerprintsdk_ic_close"
app:backButtonIconColor="#FFFFFF"
app:backButtonIconWidth="32dp"
app:backButtonIconHeight="32dp"
app:backButtonLabelEnabled="false"
app:backButtonLabelContent="Voltar"
app:backButtonLabelColor="#FFFFFF"
app:backButtonLabelSize="14sp" />
</androidx.constraintlayout.widget.ConstraintLayout>
5. Create camera activity
package com.example.fingerprintdemo
import android.graphics.Bitmap
import android.graphics.Rect
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureListener
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureState
import br.com.biopassid.fingerprintsdk.ui.view.FingerprintView
class CameraActivity : AppCompatActivity()
private val TAG = "FingerprintDemo"
private lateinit var fingerprintView: FingerprintView
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
fingerprintView = findViewById(R.id.fingerprintView)
// Defines a callback to handle capture events
fingerprintView.captureListener = object : FingerprintCaptureListener
override fun onFingerCapture(images: List<Bitmap>, error: String?)
if (error != null)
Log.d(TAG, "onFingerCapture error: $error")
Person.fingers = images
setResult(RESULT_OK)
finish()
override fun onFingerDetected(fingerRects: List<Rect>)
Log.d(TAG, "onFingerDetected: $fingerRects")
override fun onStatusChanged(state: FingerprintCaptureState)
Log.d(TAG, "onStatusChanged: $state")
// Initializes fingerprint capture
fingerprintView.start()
Using only Activity
1. In xml layout of your main activity
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btnCapture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Finger Capture"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
2. In your main activity
package com.example.fingerprintdemo
import android.graphics.Bitmap
import android.graphics.Rect
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import br.com.biopassid.fingerprintsdk.Fingerprint
import br.com.biopassid.fingerprintsdk.config.FingerprintConfig
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureListener
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureState
class MainActivity : AppCompatActivity()
private val TAG = "FingerprintDemo"
private lateinit var btnCapture: Button
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Button in your xml layout responsible for calling the Fingerprint SDK
btnCapture = findViewById(R.id.btnCapture)
// Instantiates Fingerprint config by passing your license key
val config = FingerprintConfig(licenseKey = "your-license-key")
// Defines a callback to handle capture events
val callback = object : FingerprintCaptureListener
override fun onFingerCapture(images: List<Bitmap>, error: String?)
Log.d(TAG, "onFingerCapture: $error ?: images")
override fun onFingerDetected(fingerRects: List<Rect>)
Log.d(TAG, "onFingerDetected: $fingerRects")
override fun onStatusChanged(state: FingerprintCaptureState)
Log.d(TAG, "onStatusChanged: $state")
// Initializes fingerprint capture
btnCapture.setOnClickListener
Fingerprint.takeFingerprint(this, config, callback)
Example using Retrofit to call the BioPass ID API
For this example we used the Enroll from the Multibiometrics plan and Retrofit to make http requests.
First, add the Retrofit package. To install the Retrofit
package, add it to the dependencies section of the app/build.gradle
file.
dependencies
implementation 'com.squareup.retrofit2:retrofit:2.5.0'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
Additionally, in your AndroidManifest.xml file, add the permissions.
<!-- Required to fetch data from the internet. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Required to save images to gallery. -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
EnrollPersonRequest
Create the EnrollPersonRequest data class:
package com.example.fingerprintdemo
import com.google.gson.annotations.SerializedName
data class FingerPersonRequest(
@SerializedName("Finger-1") val finger1: String? = null,
@SerializedName("Finger-2") val finger2: String? = null,
@SerializedName("Finger-3") val finger3: String? = null,
@SerializedName("Finger-4") val finger4: String? = null,
@SerializedName("Finger-5") val finger5: String? = null,
@SerializedName("Finger-6") val finger6: String? = null,
@SerializedName("Finger-7") val finger7: String? = null,
@SerializedName("Finger-8") val finger8: String? = null,
@SerializedName("Finger-9") val finger9: String? = null,
@SerializedName("Finger-10") val finger10: String? = null,
)
data class PersonRequest(
@SerializedName("CustomID") val customID: String,
@SerializedName("Fingers") val fingers: List<FingerPersonRequest>
)
data class EnrollPersonRequest(
@SerializedName("Person") val person: PersonRequest
)
EnrollPersonResponse
Create the EnrollPersonResponse data class:
package com.example.fingerprintdemo
import com.google.gson.annotations.SerializedName
data class PersonResponse(
@SerializedName("ClientID") val clientID: String,
@SerializedName("CustomID") val customID: String,
@SerializedName("BioPassID") val bioPassID: String
)
data class EnrollPersonResponse(
@SerializedName("Person") val person: PersonResponse,
@SerializedName("Message") val message: String
)
BioPassIDApi
Here, you will need an API key to be able to make requests to the BioPass ID API. To get your API key contact us through our website BioPass ID.
Create the BioPassIDApi interface to make requests to the BioPass ID API:
package com.example.fingerprintdemo
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST
interface BioPassIDApi
@Headers("Content-Type: application/json", "Ocp-Apim-Subscription-Key: your-api-key")
@POST("multibiometrics/enroll")
fun enrollPerson(@Body enrollPersonRequest: EnrollPersonRequest) : Call<EnrollPersonResponse>
Network
Create the Network class to make requests to the BioPass ID API:
package com.example.fingerprintdemo
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
class Network
companion object
/** Returns a Client Retrofit Instance for Requests
*/
fun getRetrofitInstance() : BioPassIDApi
return Retrofit.Builder()
.baseUrl("https://api.biopassid.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(BioPassIDApi::class.java)
MediaStoreUtils
Create the MediaStoreUtils class to save images to gallery:
package com.example.fingerprintdemo
import android.content.ContentValues
import android.content.Context
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import java.io.File
import java.io.FileOutputStream
import java.io.OutputStream
import java.text.SimpleDateFormat
import java.util.Locale
object MediaStoreUtils
fun saveImage(context: Context, bitmap: Bitmap)
val folderName = "Fingerprint"
val date = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS", Locale.US)
.format(System.currentTimeMillis())
val fileName = "fingerprint_$date.png"
val values = contentValues(bitmap.width, bitmap.height)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/$folderName")
values.put(MediaStore.Images.Media.IS_PENDING, true)
val uri: Uri? = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
if (uri != null)
try
saveImageToStream(bitmap, context.contentResolver.openOutputStream(uri))
values.put(MediaStore.Images.Media.IS_PENDING, false)
context.contentResolver.update(uri, values, null, null)
catch (e: Exception)
e.printStackTrace()
else
val directory = File("$Environment.getExternalStorageDirectory()/Pictures/$folderName")
if (!directory.exists())
directory.mkdirs()
val file = File(directory, fileName)
try
saveImageToStream(bitmap, FileOutputStream(file))
values.put(MediaStore.Images.Media.DATA, file.absolutePath)
context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
catch (e: Exception)
e.printStackTrace()
private fun contentValues(width: Int, height: Int) : ContentValues
val values = ContentValues()
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png")
values.put(MediaStore.Images.Media.WIDTH, width)
values.put(MediaStore.Images.Media.HEIGHT, height)
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000)
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
return values
private fun saveImageToStream(bitmap: Bitmap, outputStream: OutputStream?)
if (outputStream != null)
try
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.close()
catch (e: Exception)
e.printStackTrace()
Using View
1. Create the AppConfig data class
package com.example.fingerprintdemo
import android.graphics.Bitmap
import br.com.biopassid.fingerprintsdk.config.FingerprintConfig
object AppConfig
var config = FingerprintConfig()
var rightHandImages: List<Bitmap> = ArrayList()
var leftHandImages: List<Bitmap> = ArrayList()
var thumbsImages: List<Bitmap> = ArrayList()
2. In xml layout of your main activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<Button
android:id="@+id/btnCaptureRightHand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Capture Right Hand" />
<Button
android:id="@+id/btnCaptureLeftHand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Capture Left Hand" />
<Button
android:id="@+id/btnCaptureThumbs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Capture Thumbs" />
</LinearLayout>
3. In your main activity
package com.example.fingerprintdemo
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.util.Base64
import android.util.Log
import android.widget.Button
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import br.com.biopassid.fingerprintsdk.config.enums.FingerprintCaptureType
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.ByteArrayOutputStream
import java.io.IOException
class MainActivity : AppCompatActivity()
private val writePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE
private var writePermissionGranted = false
private lateinit var permissionsLauncher: ActivityResultLauncher<Array<String>>
private lateinit var btnCaptureRightHand: Button
private lateinit var btnCaptureLeftHand: Button
private lateinit var btnCaptureThumbs: Button
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
permissionsLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) permissions ->
writePermissionGranted = permissions[writePermission] ?: writePermissionGranted
updateOrRequestPermissions()
// Button in your xml layout responsible for calling the Fingerprint SDK
btnCaptureRightHand = findViewById(R.id.btnCaptureRightHand)
btnCaptureLeftHand = findViewById(R.id.btnCaptureLeftHand)
btnCaptureThumbs = findViewById(R.id.btnCaptureThumbs)
// Set your license key
AppConfig.config.licenseKey = "your-license-key"
// Register ActivityForResult
val intentLauncher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) result: ActivityResult ->
if (result.resultCode == RESULT_OK)
var rightThumb: String? = null
var rightIndex: String? = null
var rightMiddle: String? = null
var rightRing: String? = null
var rightLittle: String? = null
var leftThumb: String? = null
var leftIndex: String? = null
var leftMiddle: String? = null
var leftRing: String? = null
var leftLittle: String? = null
if (AppConfig.rightHandImages.isNotEmpty())
// Save images to gallery
AppConfig.rightHandImages.forEach image ->
MediaStoreUtils.saveImage(this@MainActivity, image)
// Encode Bitmap to base64 string
rightLittle = bitmapToBas64(AppConfig.rightHandImages[1])
rightRing = bitmapToBas64(AppConfig.rightHandImages[2])
rightMiddle = bitmapToBas64(AppConfig.rightHandImages[3])
rightIndex = bitmapToBas64(AppConfig.rightHandImages[4])
if (AppConfig.leftHandImages.isNotEmpty())
// Save images to gallery
AppConfig.leftHandImages.forEach image ->
MediaStoreUtils.saveImage(this@MainActivity, image)
// Encode Bitmap to base64 string
leftLittle = bitmapToBas64(AppConfig.leftHandImages[1])
leftRing = bitmapToBas64(AppConfig.leftHandImages[2])
leftMiddle = bitmapToBas64(AppConfig.leftHandImages[3])
leftIndex = bitmapToBas64(AppConfig.leftHandImages[4])
if (AppConfig.thumbsImages.isNotEmpty())
// Save images to gallery
AppConfig.thumbsImages.forEach image ->
MediaStoreUtils.saveImage(this@MainActivity, image)
// Encode Bitmap to base64 string
leftThumb = bitmapToBas64(AppConfig.thumbsImages[1])
rightThumb = bitmapToBas64(AppConfig.thumbsImages[2])
// Send images to API
sendImages(
rightThumb = rightThumb,
rightIndex = rightIndex,
rightMiddle = rightMiddle,
rightRing = rightRing,
rightLittle = rightLittle,
leftThumb = leftThumb,
leftIndex = leftIndex,
leftMiddle = leftMiddle,
leftRing = leftRing,
leftLittle = leftLittle
)
// Start right hand capture
btnCaptureRightHand.setOnClickListener
AppConfig.config.captureType = FingerprintCaptureType.RIGHT_HAND_FINGERS
val intent = Intent(this, CameraActivity::class.java)
intentLauncher.launch(intent)
// Start left hand capture
btnCaptureLeftHand.setOnClickListener
AppConfig.config.captureType = FingerprintCaptureType.LEFT_HAND_FINGERS
val intent = Intent(this, CameraActivity::class.java)
intentLauncher.launch(intent)
// Start thumbs capture
btnCaptureThumbs.setOnClickListener
AppConfig.config.captureType = FingerprintCaptureType.THUMBS
val intent = Intent(this, CameraActivity::class.java)
intentLauncher.launch(intent)
// Helper method used to send images to API
private fun sendImages(
rightThumb: String? = null,
rightIndex: String? = null,
rightMiddle: String? = null,
rightRing: String? = null,
rightLittle: String? = null,
leftThumb: String? = null,
leftIndex: String? = null,
leftMiddle: String? = null,
leftRing: String? = null,
leftLittle: String? = null
)
// Instantiate Enroll request
val enrollPersonRequest = EnrollPersonRequest(
PersonRequest(
"your-customID",
listOf(
FingerPersonRequest(
finger1 = rightThumb,
finger2 = rightIndex,
finger3 = rightMiddle,
finger4 = rightRing,
finger5 = rightLittle,
finger6 = leftThumb,
finger7 = leftIndex,
finger8 = leftMiddle,
finger9 = leftRing,
finger10 = leftLittle
)
)
)
)
// Get retrofit
val retrofit = Network.getRetrofitInstance()
// Execute request to the BioPass ID API
val callback: Call<EnrollPersonResponse> =
retrofit.enrollPerson(enrollPersonRequest)
// Handle API response
callback.enqueue(object : Callback<EnrollPersonResponse?>
override fun onResponse(
call: Call<EnrollPersonResponse?>,
response: Response<EnrollPersonResponse?>
)
Log.d(TAG, "code: $response.code()")
if (response.isSuccessful)
Log.d(TAG, "body: $response.body()")
else
Log.d(TAG, "message: $response.message()")
override fun onFailure(call: Call<EnrollPersonResponse?>, t: Throwable)
Log.e(TAG, "Error trying to call enroll person. ", t)
)
// Helper method used to convert Bitmap to Base64
private fun bitmapToBas64(bitmap: Bitmap): String
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
val byteArray = stream.toByteArray()
try
stream.close()
catch (e: IOException)
e.printStackTrace()
return Base64.encodeToString(byteArray, Base64.NO_WRAP)
// Helper method used to request permissions
private fun updateOrRequestPermissions()
val hasWritePermission = ContextCompat.checkSelfPermission(
this,
writePermission
) == PackageManager.PERMISSION_GRANTED
val isMinSdk29 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
writePermissionGranted = hasWritePermission || isMinSdk29
val permissionsToRequest = mutableListOf<String>()
if (!writePermissionGranted)
permissionsToRequest.add(writePermission)
if (permissionsToRequest.isNotEmpty())
permissionsLauncher.launch(permissionsToRequest.toTypedArray())
companion object
private const val TAG = "FingerprintDemo"
4. Create a xml layout for camera activity and add FingerprintView
to it
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CameraActivity">
<br.com.biopassid.fingerprintsdk.ui.view.FingerprintView
android:id="@+id/fingerprintView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
5. Create camera activity
package com.example.fingerprintdemo
import android.graphics.Bitmap
import android.graphics.Rect
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import br.com.biopassid.fingerprintsdk.config.enums.FingerprintCaptureType
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureListener
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureState
import br.com.biopassid.fingerprintsdk.ui.view.FingerprintView
class CameraActivity : AppCompatActivity()
private lateinit var fingerprintView: FingerprintView
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
fingerprintView = findViewById(R.id.fingerprintView)
fingerprintView.config = AppConfig.config
// Defines a callback to handle capture events
fingerprintView.captureListener = object : FingerprintCaptureListener
override fun onFingerCapture(images: List<Bitmap>, error: String?)
Log.d(TAG, "onFingerCapture: $error ?: images")
AppConfig.rightHandImages.clear()
AppConfig.leftHandImages.clear()
AppConfig.thumbsImages.clear()
when (AppConfig.config.captureType)
FingerprintCaptureType.RIGHT_HAND_FINGERS -> AppConfig.rightHandImages.addAll(images)
FingerprintCaptureType.LEFT_HAND_FINGERS -> AppConfig.leftHandImages.addAll(images)
else -> AppConfig.thumbsImages.addAll(images)
setResult(RESULT_OK)
finish()
override fun onFingerDetected(fingerRects: List<Rect>)
Log.d(TAG, "onFingerDetected: $fingerRects")
override fun onStatusChanged(state: FingerprintCaptureState)
Log.d(TAG, "onStatusChanged: $state")
// Initializes fingerprint capture
fingerprintView.start()
companion object
private const val TAG = "FingerprintDemo"
Using only Activity
1. In xml layout of your main activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<Button
android:id="@+id/btnCaptureRightHand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Capture Right Hand" />
<Button
android:id="@+id/btnCaptureLeftHand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Capture Left Hand" />
<Button
android:id="@+id/btnCaptureThumbs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="Capture Thumbs" />
</LinearLayout>
2. In your main activity
package com.example.fingerprintdemo
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.util.Base64
import android.util.Log
import android.widget.Button
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import br.com.biopassid.fingerprintsdk.Fingerprint
import br.com.biopassid.fingerprintsdk.config.FingerprintConfig
import br.com.biopassid.fingerprintsdk.config.enums.FingerprintCaptureType
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureListener
import br.com.biopassid.fingerprintsdk.engine.FingerprintCaptureState
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.ByteArrayOutputStream
import java.io.IOException
class MainActivity : AppCompatActivity()
private val writePermission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE
private var writePermissionGranted = false
private lateinit var permissionsLauncher: ActivityResultLauncher<Array<String>>
private lateinit var btnCaptureRightHand: Button
private lateinit var btnCaptureLeftHand: Button
private lateinit var btnCaptureThumbs: Button
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
permissionsLauncher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) permissions ->
writePermissionGranted = permissions[writePermission] ?: writePermissionGranted
updateOrRequestPermissions()
// Button in your xml layout responsible for calling the Fingerprint SDK
btnCaptureRightHand = findViewById(R.id.btnCaptureRightHand)
btnCaptureLeftHand = findViewById(R.id.btnCaptureLeftHand)
btnCaptureThumbs = findViewById(R.id.btnCaptureThumbs)
// Instantiates Fingerprint config by passing your license key
val config = FingerprintConfig(licenseKey = "your-license-key")
// Initializes fingerprint capture
btnCaptureRightHand.setOnClickListener
config.captureType = FingerprintCaptureType.RIGHT_HAND_FINGERS
Fingerprint.takeFingerprint(this, config, object : FingerprintCaptureListener
override fun onFingerCapture(images: List<Bitmap>, error: String?)
if (images.isNotEmpty())
// Save images to gallery
images.forEach image ->
MediaStoreUtils.saveImage(this@MainActivity, image)
// Encode Bitmap to base64 string
val rightLittle = bitmapToBas64(images[1])
val rightRing = bitmapToBas64(images[2])
val rightMiddle = bitmapToBas64(images[3])
val rightIndex = bitmapToBas64(images[4])
// Send images to API
sendImages(
rightIndex = rightIndex,
rightMiddle = rightMiddle,
rightRing = rightRing,
rightLittle = rightLittle
)
override fun onFingerDetected(fingerRects: List<Rect>)
override fun onStatusChanged(state: FingerprintCaptureState)
)
btnCaptureLeftHand.setOnClickListener
config.captureType = FingerprintCaptureType.LEFT_HAND_FINGERS
Fingerprint.takeFingerprint(this, config, object : FingerprintCaptureListener
override fun onFingerCapture(images: List<Bitmap>, error: String?)
if (images.isNotEmpty())
// Save images to gallery
images.forEach image ->
MediaStoreUtils.saveImage(this@MainActivity, image)
// Encode Bitmap to base64 string
val leftLittle = bitmapToBas64(images[1])
val leftRing = bitmapToBas64(images[2])
val leftMiddle = bitmapToBas64(images[3])
val leftIndex = bitmapToBas64(images[4])
// Send images to API
sendImages(
leftIndex = leftIndex,
leftMiddle = leftMiddle,
leftRing = leftRing,
leftLittle = leftLittle
)
override fun onFingerDetected(fingerRects: List<Rect>)
override fun onStatusChanged(state: FingerprintCaptureState)
)
btnCaptureThumbs.setOnClickListener
config.captureType = FingerprintCaptureType.THUMBS
Fingerprint.takeFingerprint(this, config, object : FingerprintCaptureListener
override fun onFingerCapture(images: List<Bitmap>, error: String?)
if (images.isNotEmpty())
// Save images to gallery
images.forEach image ->
MediaStoreUtils.saveImage(this@MainActivity, image)
// Encode Bitmap to base64 string
val leftThumb = bitmapToBas64(images[1])
val rightThumb = bitmapToBas64(images[2])
// Send images to API
sendImages(rightThumb = rightThumb, leftThumb = leftThumb)
override fun onFingerDetected(fingerRects: List<Rect>)
override fun onStatusChanged(state: FingerprintCaptureState)
)
// Helper method used to send images to API
private fun sendImages(
rightThumb: String? = null,
rightIndex: String? = null,
rightMiddle: String? = null,
rightRing: String? = null,
rightLittle: String? = null,
leftThumb: String? = null,
leftIndex: String? = null,
leftMiddle: String? = null,
leftRing: String? = null,
leftLittle: String? = null
)
// Instantiate Enroll request
val enrollPersonRequest = EnrollPersonRequest(
PersonRequest(
"your-customID",
listOf(
FingerPersonRequest(
finger1 = rightThumb,
finger2 = rightIndex,
finger3 = rightMiddle,
finger4 = rightRing,
finger5 = rightLittle,
finger6 = leftThumb,
finger7 = leftIndex,
finger8 = leftMiddle,
finger9 = leftRing,
finger10 = leftLittle
)
)
)
)
// Get retrofit
val retrofit = Network.getRetrofitInstance()
// Execute request to the BioPass ID API
val callback: Call<EnrollPersonResponse> =
retrofit.enrollPerson(enrollPersonRequest)
// Handle API response
callback.enqueue(object : Callback<EnrollPersonResponse?>
override fun onResponse(
call: Call<EnrollPersonResponse?>,
response: Response<EnrollPersonResponse?>
)
Log.d(TAG, "code: $response.code()")
if (response.isSuccessful)
Log.d(TAG, "body: $response.body()")
else
Log.d(TAG, "message: $response.message()")
override fun onFailure(call: Call<EnrollPersonResponse?>, t: Throwable)
Log.e(TAG, "Error trying to call enroll person. ", t)
)
// Helper method used to convert Bitmap to Base64
private fun bitmapToBas64(bitmap: Bitmap): String
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
val byteArray = stream.toByteArray()
try
stream.close()
catch (e: IOException)
e.printStackTrace()
return Base64.encodeToString(byteArray, Base64.NO_WRAP)
// Helper method used to request permissions
private fun updateOrRequestPermissions()
val hasWritePermission = ContextCompat.checkSelfPermission(
this,
writePermission
) == PackageManager.PERMISSION_GRANTED
val isMinSdk29 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
writePermissionGranted = hasWritePermission || isMinSdk29
val permissionsToRequest = mutableListOf<String>()
if (!writePermissionGranted)
permissionsToRequest.add(writePermission)
if (permissionsToRequest.isNotEmpty())
permissionsLauncher.launch(permissionsToRequest.toTypedArray())
companion object
private const val TAG = "FingerprintDemo"
4. FingerprintCaptureListener
You can set a custom listener to receive captured fingers as well as finger rectangles and monitor the current capture status, among other features. You can write you own listener following this example:
val listener = object : FingerprintCaptureListener
override fun onFingerCapture(images: List<Bitmap>, error: String?)
// monitor and handle fingers capture
if (error != null)
Log.d("onFingerCapture", "Capture Error: $error")
else
Log.d("onFingerCapture", "Capture: $images[0]")
override fun onFingerDetected(fingerRects: List<Rect>)
// monitor and handle the current state of the capture
override fun onStatusChanged(state: FingerprintCaptureState)
// monitor and handle finger rects
FingerprintCaptureState (enum)
| Name |
| --------------------------------------- |
| FingerprintCaptureState.NO_DETECTION |
| FingerprintCaptureState.MISSING_FINGERS |
| FingerprintCaptureState.TOO_CLOSE |
| FingerprintCaptureState.TOO_FAR |
| FingerprintCaptureState.OK |
| FingerprintCaptureState.STOPPED |
| FingerprintCaptureState.PROCESSING |
| FingerprintCaptureState.MODEL_NOT_FOUND |
5. LicenseKey
First, you will need a license key to use the SDK. To get your license key contact us through our website BioPass ID.
To use BioPass ID Fingerprint you need a license key. To set the license key needed is simple as setting another attribute. Simply doing:
<br.com.biopassid.fingerprintsdk.ui.view.FingerprintView
android:id="@+id/fingerprintView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:licenseKey="your-license-key" />
Configs
FingerprintConfig
| Variable name | Type | Default value |
| ---------------------- | ----------------------------------- | ---------------------------------------------- |
| licenseKey | String | "" |
| numberFingersToCapture | Int | 4 |
| fontFamily | Int | R.font.fingerprintsdk_opensans_regular |
| overlayColor | Int | Color.parseColor("#80000000") |
| timeToCapture | Int | 5 |
| captureType | FingerprintCaptureType | FingerprintCaptureType.LEFT_HAND_FINGERS |
| outputType | FingerprintOutputType | FingerprintOutputType.CAPTURE_AND_SEGMENTATION |
| captureCountdown | FingerprintCaptureCountdownOptions | |
| backButton | FingerprintButtonOptions | |
| helpText | FingerprintHelpTextOptions | |
| fingerEllipse | FingerprintFingerEllipseOptions | |
| distanceIndicator | FingerprintDistanceIndicatorOptions | |
FingerprintCaptureType (enum)
| Name |
| ----------------------------------------- |
| FingerprintCaptureType.RIGHT_HAND_FINGERS |
| FingerprintCaptureType.LEFT_HAND_FINGERS |
| FingerprintCaptureType.THUMBS |
FingerprintOutputType (enum)
| Name |
| ---------------------------------------------- |
| FingerprintOutputType.ONLY_CAPTURE |
| FingerprintOutputType.CAPTURE_AND_SEGMENTATION |
FingerprintCaptureCountdownOptions
| Name | Type | Default value |
| --------------- | ------- | --------------------------- |
| enabled | Boolean | true |
| backgroundColor | Int | Color.GRAY |
| progressColor | Int | Color.parseColor("#D6A262") |
| textColor | Int | Color.WHITE |
FingerprintButtonOptions
| Name | Type | Default value |
| --------------- | ---------------------- | ------------------------ |
| enabled | Boolean | true |
| backgroundColor | Int | Color.TRANSPARENT |
| buttonPadding | Int | 0 |
| buttonSize | Size | Size(56, 56) |
| iconOptions | FingerprintIconOptions | FingerprintIconOptions() |
| labelOptions | FingerprintTextOptions | FingerprintTextOptions() |
FingerprintIconOptions
| Name | Type | Default value |
| --------- | ------- | ---------------------------------- |
| enabled | Boolean | true |
| iconFile | Int | R.drawable.fingerprintsdk_ic_close |
| iconColor | Int | Color.WHITE |
| iconSize | Size | Size(32, 32) |
FingerprintTextOptions
| Name | Type | Default value |
| --------- | ------- | ------------- |
| enabled | Boolean | true |
| content | String | "" |
| textColor | Int | Color.WHITE |
| textSize | Int | 14 |
FingerprintHelpTextOptions
| Name | Type | Default value |
| --------- | --------------------------- | ----------------------------- |
| enabled | Boolean | true |
| messages | FingerprintHelpTextMessages | FingerprintHelpTextMessages() |
| textColor | Int | Color.WHITE |
| textSize | Int | 14 |
FingerprintHelpTextMessages
| Name | Type | Default value |
| ---------------- | ------ | --------------------------------------------------------------------------- |
| leftHandMessage | String | "Encaixe a mão esquerda (sem o polegar)\naté o marcador ficar centralizado" |
| rightHandMessage | String | "Encaixe a mão direita (sem o polegar)\naté o marcador ficar centralizado" |
| thumbsMessage | String | "Encaixe os polegares\naté o marcador ficar centralizado." |
FingerprintFingerEllipseOptions
| Name | Type | Default value |
| ------------ | ------- | ----------------------------- |
| enabled | Boolean | true |
| ellipseColor | Int | Color.parseColor("#80D6A262") |
FingerprintDistanceIndicatorOptions
| Name | Type | Default value |
| ------------------ | ---------------------- | ----------------------------------------------- |
| enabled | Boolean | true |
| selectedBarColor | Int | Color.parseColor("#D6A262") |
| unselectedBarColor | Int | Color.WHITE |
| arrowColor | Int | Color.parseColor("#D6A262") |
| tooCloseText | FingerprintTextOptions | FingerprintTextOptions(content = "Muito perto") |
| tooFarText | FingerprintTextOptions | FingerprintTextOptions(content = "Muito longe") |
How to change font family
You can use the default font family or set one of your own. To set a font family, create a font folder under res directory. Download the font which ever you want and paste it inside font folder. All font names must be only: lowercase a-z, 0-9, or underscore. The structure should be some thing like below.
Then, just set the font family passing the reference of the font family file.
<br.com.biopassid.fingerprintsdk.ui.view.FingerprintView
android:id="@+id/fingerprintView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:licenseKey="your-license-key"
app:textFontFamily="@font/roboto_mono_bold_italic" />
How to change icon
You can use the default icons or define one of your own. To set a icon, download the icon which ever you want and paste it inside drawable folder. The structure should be some thing like below.
Then, just set the icon passing the reference of the icon file.
<br.com.biopassid.fingerprintsdk.ui.view.FingerprintView
android:id="@+id/fingerprintView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:licenseKey="your-license-key"
app:backButtonIconFile="@drawable/ic_baseline_photo_camera" />
Changelog
2.1.4
- Documentation update;
- Fixed crash error caused by OpenCV resize function.
2.1.3
- Documentation update.
- Refactor exposure compensation handling;
- Add distorted image correction on Moto E7.
2.1.2
- Documentation update;
- Fixed validation of number of fingers in FingerprintView.
2.1.1
- Documentation update;
- Dlib has been removed and wrapped in an external lib to avoid conflicts with other BioPasss ID SDKs. Now the dlib wrapper is a dependency, see prerequisites section.
2.1.0
- Documentation update;
- Changed the minimum Android sdk version from 23 to 24;
- Removed dependency on Mobile Vision, see prerequisites section;
- Upgrade from Camera2 to CameraX, see prerequisites section;
- Improvement in the fluidity of the distance indicator;
- Added continuous autofocus;
- Added new time to capture functionality;
- Added countdown view.
2.0.2
- Documentation update;
- Changed the minimum Android sdk version from 21 to 23;
- Upgrade to Gradle 8.6, see prerequisites section;
- Upgrade to Android Gradle Plugin 8.4.0, see prerequisites section;
- Upgrade to Java 17, see prerequisites section;
- Upgrade to Kotlin 1.9.0, see prerequisites section.
2.0.1
- Documentation update;
- Bug fixes.
2.0.0
- Documentation update;
- All code rewritten using Kotlin as standard and no longer Java;
- Updated Gradle Version to 7.5 and Android Gradle Plugin Version to 7.4.2;
- Updated camera API to Camera2;
- FingerprintConfig refactoring:
- Removed showFingerEllipseView and fingerColor, they are now in a new configuration class called FingerprintFingerEllipseOptions;
- Removed showDistanceIndicatorView, distanceIndicatorLineColor, distanceIndicatorHighlightColor, tooCloseText and tooFarText, now they are in a new configuration class called FingerprintDistanceIndicatorOptions.
- Now, in order for the SDK to be initialized, it is necessary to call the start method of FingerprintView.