Mob.ID SDK is a very flexible library for Android.
With MOB.ID you handle your identity and privacy information swiftly, digitally and securely. We at MOB.ID share your convictions and principles. We are always there for you
MOB.ID is your passport to the world
In addition configuration options, MOB.ID provides NFC, Face Detection, Passport Scan and etc. But MOB.ID is also developed-friendly, which means you can fully and easily add it to your project:
- Import dependency into the project
- Fill API keys
- Import additional dependency
Requirements
- Min Android SDK 26
- Kotlin 1.6
Installation
dependencies {
....
implementation("id.mob:api-client:1.1.5")
....
}
Usage
Basics
// Application class
import id.mob.apiclient.MIDApiClient
import id.mob.apiclient.network.MIDApiCallback
class MobIdApplication: Application() {
override fun onCreate() {
super.onCreate()
....
MIDApiClient.initialize(
context = applicationContext,
userId = '[Set_Your_User_Id_or_devide_Id]',
organizationName = "YOUR_ORGANIZATION",
subOrganizationName = "YOUR_SUB_ORGANIZATION",
password = "YOUR_API_PASSWORD",
organizationUrl = "URL_FOR_YOUR_BACKEND_PART",
object:MIDApiCallback {
override fun onSuccess(res: Boolean?) {
Log.d("MID_API", "API init ${if(res == true) "OK" else "failed"}")
}
override fun onFailure(thr: Throwable?) {
Log.e("MID_API", "API init failed", thr)
}
}
)
....
}
Optical check
Firstly you should run optical check from MOB.ID SDK. You should place MIDDocumentScannerView to your layout file to manage document scan with camera (require camera permission)
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
....
<id.mob.apiclient.views.MIDDocumentScannerView
android:id="@+id/cvCameraView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="visible"
app:show_fps="false" />
....
</FrameLayout>
Camera
Then manage camera in your activity or fragment, also you need to obtain a permission from user
class OcrActivity : AppCompatActivity(R.layout.fragment_ocr) {
private lateinit var binding: FragmentOcrBinding
private var cameraGranted: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set listener for event if document needs to be flipped to other side
binding.cvCameraView.setDocumentFlipListener {
binding.cvCameraView.disableView() //turn off scaning for a while
binding.infoView.visibility = View.VISIBLE //show message to flip
}
binding.continueScanBtn.setOnClickListener{
binding.infoView.visibility = View.GONE //hide message to flip
binding.cvCameraView.enableView() //start scanning again
}
// Set listener for document scan process finish
binding.cvCameraView.setDocumentScannedListener { ocrData ->
binding.cvCameraView.disableView() // Turn off camera
Toast.makeText(this, "All data stored",Toast.LENGTH_LONG).show()
// Process data from OCR if you need
.....
}
}
override fun onResume() {
if (cameraGranted) {
binding.cvCameraView.enableView()
Log.d("CameraView", "Started")
} else {
//request camera permission
}
}
override fun onPause() {
binding.cvCameraView.disableView()
super.onPause()
}
}
NFC Chip Scan
Then you should use NFC Chip Scan. Also you need permission to use NFC reader
private fun startNfc() {
val activity = requireActivity()
MIDApiClient.getInstance().readNFCData(activity, callbackForReadingStarted) { result ->
//Callback for reading finished
when {
result.isSuccess -> {
//Show Success
}
result.isFailure -> {
//Show Fail
}
else -> {
//Unclassified exception with NFC
//show Fail
}
}
}
}
Liveness check
Also you can check if person is present behind device by calling liveness check
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android""
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!-- Preview for camera and liveness analyst -->
<id.mob.apiclient.views.MIDLivenessView
android:id="@+id/pv_selfie_camera"
android:layout_width="match_parent"
android:layout_height="match_parent"
<!-- here we setup view for region analysis
if is not set - region assumed all view surface
and command to place face in region will not be enabled
-->
app:faceRegionView="@id/iv_face_oval"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:background="?attr/colorPrimaryBackground" />
<!-- region for analyst -->
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_face_oval"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="80dp"
android:layout_marginVertical="24dp"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintDimensionRatio="3:4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintVertical_bias="0.4"
app:srcCompat="@drawable/ic_face_oval"
app:tint="@color/white" />
....
</FrameLayout>
private fun checkLiveness() {
//Firstly start camera preview
livenessView.launchCamera()
//Start liveness analyst
livenessView.startLivenessCheck(
//set mandatory commands, that should be present always
//they will be placed as first commands
mandatoryList = listOf(
LivenessAction.POSITION_ON_OVAL,
),
//set list for all possible commands
//they will be takey randomly
actionList = listOf(
LivenessAction.LOOK_RIGHT,
LivenessAction.LOOK_LEFT,
LivenessAction.SMILE,
LivenessAction.CLOSE_EYES,
LivenessAction.LOOK_UP,
LivenessAction.LOOK_DOWN
),
//set how many steps should be taken
stepsCount = 3,
//set callback for update UI with command
//when (uiAction.action) {
// LivenessAction.POSITION_ON_OVAL -> R.string.txt_liveness_instruction_position_in_oval
// LivenessAction.LOOK_RIGHT -> R.string.txt_liveness_instruction_turn_right
// LivenessAction.LOOK_LEFT -> R.string.txt_liveness_instruction_turn_left
// LivenessAction.SMILE -> R.string.txt_liveness_instruction_smile
// LivenessAction.CLOSE_EYES -> R.string.txt_liveness_instruction_close_eyes
// LivenessAction.LOOK_UP -> R.string.txt_liveness_instruction_look_up
// LivenessAction.LOOK_DOWN -> R.string.txt_liveness_instruction_look_down
// null -> R.string.txt_liveness_verifying
// }
this@LivenessFragment::updateUiForAction
)
//callback for processing liveness finish
{ livenessResult ->
if (livenessResult.isSuccess && livenessResult.getOrNull() == true) {
onLivenessSuccess()
} else {
onLivenessFailed()
}
}
}
Identity profile
And at last you can create user identity profile
.........
MIDApiClient.getInstance().createRootIdentity(){ res ->
//call back for processing result of identity creation
}
..........