Biometric Capture
Implementing the Biometric Capture Session in a View-based UI
This example shows how to integrate the Biometric Capture Session to your project. The Biometric Capture Session extracts a frames collection from the camera preview.
This Example app uses ViewBinding
, so enable it with the following (at the end of the android{}
block):
buildFeatures {
viewBinding true
}
When prompted, click Sync Now, and we will be ready to use the Biometric Capture Session in our app.
Create a capture layout.
In the UI for this example app, we use the following layout structure:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CaptureFragment">
<LinearLayout
android:id="@+id/ll_capture_session_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
<Button
android:id="@+id/btn_start_capture"
android:layout_width="170dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="300dp"
android:textColor="#DBD7E4"
android:background="@color/colorPrimary"
android:visibility="gone"/>
</FrameLayout>
This LinealLayout hosts MBCaptureSessionView
.
<LinearLayout
android:id="@+id/ll_capture_session_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
The capture button is enabled when the capture process is not automatic.
<Button
android:id="@+id/btn_start_capture"
android:layout_width="170dp"
android:layout_height="50dp"
android:layout_gravity="center"
android:layout_marginTop="300dp"
android:textColor="#DBD7E4"
android:background="@color/colorPrimary"
android:visibility="gone"/>
Setup CaptureFragment.kt.
CaptureFragment
is the host element for the camera preview. And extends from MBCaptureSessionServiceListener
,MBOnValidatingListener
,MBCountDownListener
and MBCaptureProgressListener
.
class CaptureFragment : Fragment(R.layout.fragment_capture),
MBCaptureSessionListener,
MBOnValidatingListener,
MBCountDownListener,
MBCaptureProgressListener {
private var captureSessionService: MBCaptureSessionService? = null
private lateinit var mBinding : FragmentCaptureBinding
@SuppressLint("UnsafeOptInUsageError")
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mBinding = FragmentCaptureBinding.inflate(inflater,container,false)
val options = MBCaptureSessionOptions.Builder().build()
captureSessionService = MBCaptureSessionService(requireContext(), this, options, this)
mBinding.container.addView(captureSessionService!!.getCaptureSessionView())
captureSessionService!!.startCamera()
if (!captureSessionService!!.getAutomaticCapture()) {
mBinding.btnStartCapture.visibility = View.VISIBLE
mBinding.btnStartCapture.setOnClickListener {
captureSessionService!!.startCaptureSession()
}
}
return mBinding.root
}
override fun onCaptureFinished(result: MBCaptureSessionResult?){ }
override fun onCountdown(timeCounter: Int) { }
override fun onValidating(faceStatus: MBFaceStatus) { }
override fun onFailure(errorEnum: MBCaptureSessionError) { }
override fun onStateChanged(stateEnum: MBCaptureState) { }
override fun onCaptureProgress(captureProgressCounter: Float) { }
}
Creates a CaptureFragment
viewBinding instance:
private lateinit var mBinding : FragmentCaptureBinding
Create MBCaptureSessionService
.This is the communication bridge between the caller and the biometric features.
private var captureSessionService: MBCaptureSessionService? = null
onCreateView
method execution.
@SuppressLint("UnsafeOptInUsageError")
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
mBinding = FragmentCaptureBinding.inflate(inflater,container,false)
val options = MBCaptureSessionOptions.Builder().build()
captureSessionService = MBCaptureSessionService(requireContext(), this, options, this)
mBinding.container.addView(captureSessionService!!.getCaptureSessionView())
captureSessionService!!.startCamera()
if (!captureSessionService!!.getAutomaticCapture()) {
mBinding.btnStartCapture.visibility = View.VISIBLE
mBinding.btnStartCapture.setOnClickListener {
captureSessionService!!.startCaptureSession()
}
}
return mBinding.root
}
Create an instance of MBCaptureSessionOptions
builder. This is the capture session's entry point configuration and it has its own default values . In this case the automaticCapture
is set to false and that means the capture is manual.
val options = MBCaptureSessionOptions.Builder().build()
MBCaptureSessionOptions
Inside the library we have some options for changing behaviour of capturing data:
Variable Name | Type | Default Value |
---|---|---|
numberOfFrameToCollect | number | 3 |
timeBeforeAutomaticCapture | number | 4 |
isDebugging | boolean | false |
autoCaptureEnabled | boolean | true |
payloadOptimization | boolean | false |
cameraQuality | MBCameraOptions | MBCameraOptions |
MBCaptureSessionOption.Builder
arguments are optional.
Options description:
numberOfFrameToCollect
Describes the number of frames to collect during the capture sessionautoCaptureEnabled
Tells whether the capture is automatic or manualtimeBeforeAutomaticCapture
Is the set time in seconds the capture should wait to start collecting frames The text for the countdownLabel can be set using thecountdownLabelText
option.isDebugging
If it is set to false will just display the overlay on the top of the camera. If it is set to true will display all components available ont the top of the camera(timer text, progress bar and face status text).payloadOptimization
It is use to enable or disable the optimization of the payload you send to the backend | reduces the payload size.cameraQuality
It is used to set the options for the camera. It accepts three parameters: A MBTargetResolution instance, this is the resolution in witch the frames are collected. It accepts a MBPreviewScaleTyp instance that is the mode used to scale the camera preview in the view. It can be set to either FIT_CENTER or FILL_CENTER. MBPreviewScaleType.FILL_CENTER will ensure the camera preview is taking up the whole view in both width and height. However, this means that some parts of the image will be cropped from the preview. This does not have any impact on the images captured from the camera. MBPreviewScaleType.FIT_CENTER will ensure that exactly what is captured from the camera is shown in the view. And a MBCameraPosition that describes whether is displayed front or rear camera.
MBTargetResolution
Field | Value |
---|---|
QHD | Size(540, 960) |
HD_720 | Size(720, 1280) |
HD_1080 | Size(1080, 1920) |
HD_4K | Size(2160, 3840) |
MBCaptureSessionInstance
initialization.
captureSessionService = MBCaptureSessionService(requireContext(), this, options, this, null)
MBCaptureSessionService
arguments.
context
Is an instance of the caller's context needed to implement MBCameraService and MBCaptureSessionView.lifecycleOwner
Is an instance of the caller's life cycle owner needed to implement MBCameraService.options
Represents the capture session's entry point configuration for ist correct functioning.callback
Updates the caller with any change during the whole capture process, including a capture result, it has to be set to null while implementing MBCaptureSessionFragment.
Adds the CaptureSessionView as view child to CaptureFragment
.
mBinding.llCaptureSessionViewContainer.addView(captureSessionService!!.getCaptureSessionView())
Starts Camera if camera permission is granted. It is very important to verify the camera permission to get the feature up running.
captureSessionService!!.startCamera()
This block of code enables the capture button if automaticCapture is set to false mining the capture process is manual, or disables it if the automaticCapture is set to true.
if (!captureSessionService!!.getAutomaticCapture()) {
mBinding.btnStartCapture.visibility = View.VISIBLE
mBinding.btnStartCapture.setOnClickListener {
captureSessionService!!.startCaptureSession()
}
}
The function onCaptureFinished
gets a result of the capture process if it is successfully finished. result contains a list of nullable Bitmaps. In this case send it as an argument to another screen by using ViewModel and LiveData. And then I start another activity.
override fun onCaptureFinished(result: MBCaptureSessionResult?){ }
onCaptureFinished
is executed for MBCaptureSessionService
when the capture session has successfully finished. MBCaptureSessionResult
arguments:
faceImage
A high quality image captured after collecting frames.frames
Is the frame collection.serializedData()
Is thefaceImage
andframes
in Protobuf serialization.
Function onFailure
is executed when the capture process fails. MBCaptureSessionError
tells the type of error that occurred.
override fun onFailure(errorEnum: MBCaptureSessionError) { }
MBCaptureSessionError
entries:
UNABLE_TO_OPEN_CAMERA
Describes failure while opening the cameraUNABLE_TO_COLLECT_FRAMES
The capture has is aborted
Function onValidating
is executed when frames are being analyzed.
override fun onValidating(faceStatus: MBFaceStatus) { }
MBFaceStatus
entries:
TOO_FAR_AWAY
Face is too far awayTOO_CLOSE
Face is too closeTOO_FAR_UP
Face is too far upTOO_FAR_LEFT
Face is too far leftTOO_FAR_DOWN
Face is too far downTOO_FAR_RIGHT
Face is too far rightNOT_FOUND
Face not foundTOO_MANY
Too many facesVALID
Face is valid
Function onCountdown
is executed during the automatic capture. timeCounter
is the current time in seconds.
override fun onCountdown(timeCounter: Int) { }
The function onStateChanged
is executed every time the capture state changes. The parameterstateEnum
is a representation of the current state.
MBCaptureState
- INITIALIZING Is the first state and tell when the camera is ready.
- VALIDATING Is the second state and tell when the frames start being analyzed.
- COUNT_DOWN Is the third state and tell when a valid face is found in a single frame. If there is an invalid face in the following frames the state return to VALIDATING.
- CAPTURING CAPTURING is the fourth state and tell when the frames start being collected.If there is an invalid face in the following frames the stage return to VALIDATING.
- CAPTURE_FINISHED Is the last state and tell when the capturing is successfully finished.
- PROCESSING Is the state that tells when the captured frames are being precessed
override fun onStateChanged(stateEnum: MBCaptureState) { }
The method onCaptureProgress
represents the capture progress with arguments values between 0-1.
override fun onCaptureProgress(captureProgressCounter: Float) { }