Mantra (MFS 100) Biometric Android Example
Creating a New Project
·
First, we will create a new Android Studio Project.
Adding Jar File
·
So first on the project explorer select Project.
·
Then inside app/lib paste the mantra.mfs100.jar that
we downloaded.
·
Then add dependency in your build.gradle.
implementation files('libs/mantra.mfs100.jar')
Adding jniLibs Folder
·
jniLibs.jar
·
Download
jinLibs.jar file And then Extract.
·
Put
jniLibs folder src/main/
mantra.mfs100.jar
·
mantra.mfs100.jar it is inside
the lib folder app/lib/
build.gradle
apply plugin: 'com.android.application'android {compileSdkVersion 26defaultConfig {applicationId "com.mihirpanchasara.biometricexample"minSdkVersion 15targetSdkVersion 26versionCode 1versionName "1.0"testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"ndk {abiFilters "armeabi-v7a", "x86"}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}repositories {flatDir {dirs 'libs'}}//JNI Lib DeclarationsourceSets.main {jniLibs.srcDirs 'src/main/jniLibs'}}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'com.android.support:appcompat-v7:26.1.0'implementation 'com.android.support.constraint:constraint-layout:1.1.2'testImplementation 'junit:junit:4.12'implementation files('libs/mantra.mfs100.jar')}
string.xml
<resources><string name="app_name">BioMetricExample</string><string name="action_settings">Settings</string><string name="app_title">MANTRA-MFS100-TEST</string><string name="Init">INIT</string><string name="UnInit">UNINIT</string><string name="ExtractISO">ISO(FMR)</string><string name="ExtractWSQ">WSQ</string><string name="MatchISO">MATCH ISO</string><string name="foorLoop">Init/Uninit</string><string name="ClearLog">CLEAR LOG</string><string name="SyncCapture">CAPTURE</string><string name="StopSyncCapture">STOP CAP</string><string name="WriteBit">Write Bit</string><string name="ReadBit">Read Bit</string><string name="ChangeKey">Change Key</string><string name="GetKey">Get Key</string><string-array name="MFS100Ver"><item>41</item><item>31</item></string-array><string name="title_activity_preference">Preference</string></resources>
styles.xml
<style name="title"><item name="android:padding">0dp</item><item name="android:layout_margin">1dp</item><item name="android:textColor">#FFFFFF </item></style><style name="message"><item name="android:padding">0dp</item><item name="android:layout_margin">1dp</item><item name="android:textColor">#000000 </item></style><style name="button"><item name="android:padding">0dp</item><item name="android:layout_width">86dp</item><item name="android:layout_height">35dp</item><item name="android:layout_margin">1dp</item><item name="android:textColor">#FFFFFF </item></style><style name="buttonbig"><item name="android:layout_width">match_parent</item><item name="android:layout_height">35dp</item><item name="android:layout_margin">1dp</item><item name="android:textColor">#FFFFFF </item></style><style name="buttonbig2"><item name="android:layout_width">0dp</item><item name="android:layout_weight">1</item><item name="android:layout_height">35dp</item><item name="android:layout_margin">1dp</item><item name="android:textColor">#FFFFFF </item></style><style name="buttonfull"><item name="android:padding">0dp</item><item name="android:layout_height">35dp</item><item name="android:layout_margin">1dp</item><item name="android:textColor">#FFFFFF </item></style><style name="Theme.Transparent" parent="android:Theme"><item name="android:windowIsTranslucent">true</item><item name="android:windowBackground">@android:color/transparent</item><item name="android:windowContentOverlay">@null</item><item name="android:windowNoTitle">true</item><item name="android:windowIsFloating">true</item><item name="android:backgroundDimEnabled">false</item></style>
xml/config.xml
<?xml version="1.0" encoding="utf-8"?><PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" ><ListPreference android:dialogTitle="MFS100 Version" android:key="MFSVer" android:title="MFS100 Version" android:defaultValue="41" android:entries="@array/MFS100Ver" android:entryValues="@array/MFS100Ver"/></PreferenceScreen>
xml/device_config.xml
<?xml version="1.0" encoding="utf-8"?><resources><usb-device vendor-id="1204" product-id="34323" /><usb-device vendor-id="11279" product-id="4101" /></resources>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.mihirpanchasara.biometricexample"><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.USB_PERMISSION" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MFS100Test"android:configChanges="orientation|screenSize|keyboardHidden"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>
MFS100Test.java
package com.mihirpanchasara.biometricexample;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.View;import android.view.WindowManager;import android.widget.Button;import android.widget.CheckBox;import android.widget.EditText;import android.widget.ImageView;import android.widget.TextView;import android.widget.TextView.BufferType;import android.widget.Toast;import com.mantra.mfs100.FingerData;import com.mantra.mfs100.MFS100;import com.mantra.mfs100.MFS100Event;import java.io.File;import java.io.FileOutputStream;public class MFS100Test extends Activity implements MFS100Event {Button btnInit;Button btnUninit;Button btnSyncCapture;Button btnStopCapture;Button btnMatchISOTemplate;Button btnExtractISOImage;Button btnExtractAnsi;Button btnExtractWSQImage;Button btnClearLog;TextView lblMessage;EditText txtEventLog;ImageView imgFinger;CheckBox cbFastDetection;private enum ScannerAction {Capture, Verify}byte[] Enroll_Template;byte[] Verify_Template;private FingerData lastCapFingerData = null;ScannerAction scannerAction = ScannerAction.Capture;int timeout = 10000;MFS100 mfs100 = null;private boolean isCaptureRunning = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_mfs100_sample);FindFormControls();try {this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);} catch (Exception e) {Log.e("Error", e.toString());}}@Overrideprotected void onStart() {if (mfs100 == null) {mfs100 = new MFS100(this);mfs100.SetApplicationContext(MFS100Test.this);} else {InitScanner();}super.onStart();}protected void onStop() {UnInitScanner();super.onStop();}@Overrideprotected void onDestroy() {if (mfs100 != null) {mfs100.Dispose();}super.onDestroy();}public void FindFormControls() {btnInit = (Button) findViewById(R.id.btnInit);btnUninit = (Button) findViewById(R.id.btnUninit);btnMatchISOTemplate = (Button) findViewById(R.id.btnMatchISOTemplate);btnExtractISOImage = (Button) findViewById(R.id.btnExtractISOImage);btnExtractAnsi = (Button) findViewById(R.id.btnExtractAnsi);btnExtractWSQImage = (Button) findViewById(R.id.btnExtractWSQImage);btnClearLog = (Button) findViewById(R.id.btnClearLog);lblMessage = (TextView) findViewById(R.id.lblMessage);txtEventLog = (EditText) findViewById(R.id.txtEventLog);imgFinger = (ImageView) findViewById(R.id.imgFinger);btnSyncCapture = (Button) findViewById(R.id.btnSyncCapture);btnStopCapture = (Button) findViewById(R.id.btnStopCapture);cbFastDetection = (CheckBox) findViewById(R.id.cbFastDetection);}public void onControlClicked(View v) {switch (v.getId()) {case R.id.btnInit:InitScanner();break;case R.id.btnUninit:UnInitScanner();break;case R.id.btnSyncCapture:scannerAction = ScannerAction.Capture;if (!isCaptureRunning) {StartSyncCapture();}break;case R.id.btnStopCapture:StopCapture();break;case R.id.btnMatchISOTemplate:scannerAction = ScannerAction.Verify;if (!isCaptureRunning) {StartSyncCapture();}break;case R.id.btnExtractISOImage:ExtractISOImage();break;case R.id.btnExtractAnsi:ExtractANSITemplate();break;case R.id.btnExtractWSQImage:ExtractWSQImage();break;case R.id.btnClearLog:ClearLog();break;default:break;}}private void InitScanner() {try {int ret = mfs100.Init();if (ret != 0) {SetTextOnUIThread(mfs100.GetErrorMsg(ret));} else {SetTextOnUIThread("Init success");String info = "Serial: " + mfs100.GetDeviceInfo().SerialNo()+ " Make: " + mfs100.GetDeviceInfo().Make()+ " Model: " + mfs100.GetDeviceInfo().Model()+ "\nCertificate: " + mfs100.GetCertification();SetLogOnUIThread(info);}} catch (Exception ex) {Toast.makeText(this, "Init failed, unhandled exception",Toast.LENGTH_LONG).show();SetTextOnUIThread("Init failed, unhandled exception");}}private void StartSyncCapture() {new Thread(new Runnable() {@Overridepublic void run() {SetTextOnUIThread("");isCaptureRunning = true;try {FingerData fingerData = new FingerData();int ret = mfs100.AutoCapture(fingerData, timeout, cbFastDetection.isChecked());Log.e("StartSyncCapture.RET", ""+ret);if (ret != 0) {SetTextOnUIThread(mfs100.GetErrorMsg(ret));} else {lastCapFingerData = fingerData;final Bitmap bitmap = BitmapFactory.decodeByteArray(fingerData.FingerImage(), 0,fingerData.FingerImage().length);MFS100Test.this.runOnUiThread(new Runnable() {@Overridepublic void run() {imgFinger.setImageBitmap(bitmap);}});SetTextOnUIThread("Capture Success");String log = "\nQuality: " + fingerData.Quality()+ "\nNFIQ: " + fingerData.Nfiq()+ "\nWSQ Compress Ratio: "+ fingerData.WSQCompressRatio()+ "\nImage Dimensions (inch): "+ fingerData.InWidth() + "\" X "+ fingerData.InHeight() + "\""+ "\nImage Area (inch): " + fingerData.InArea()+ "\"" + "\nResolution (dpi/ppi): "+ fingerData.Resolution() + "\nGray Scale: "+ fingerData.GrayScale() + "\nBits Per Pixal: "+ fingerData.Bpp() + "\nWSQ Info: "+ fingerData.WSQInfo();SetLogOnUIThread(log);SetData2(fingerData);}} catch (Exception ex) {SetTextOnUIThread("Error");} finally {isCaptureRunning = false;}}}).start();}private void StopCapture() {try {mfs100.StopAutoCapture();} catch (Exception e) {SetTextOnUIThread("Error");}}private void ExtractANSITemplate() {try {if (lastCapFingerData == null) {SetTextOnUIThread("Finger not capture");return;}byte[] tempData = new byte[2000]; // length 2000 is mandatorybyte[] ansiTemplate;int dataLen = mfs100.ExtractANSITemplate(lastCapFingerData.RawData(), tempData);if (dataLen <= 0) {if (dataLen == 0) {SetTextOnUIThread("Failed to extract ANSI Template");} else {SetTextOnUIThread(mfs100.GetErrorMsg(dataLen));}} else {ansiTemplate = new byte[dataLen];System.arraycopy(tempData, 0, ansiTemplate, 0, dataLen);WriteFile("ANSITemplate.ansi", ansiTemplate);SetTextOnUIThread("Extract ANSI Template Success");}} catch (Exception e) {Log.e("Error", "Extract ANSI Template Error", e);}}private void ExtractISOImage() {try {if (lastCapFingerData == null) {SetTextOnUIThread("Finger not capture");return;}byte[] tempData = new byte[(mfs100.GetDeviceInfo().Width() * mfs100.GetDeviceInfo().Height()) + 1078];byte[] isoImage;int dataLen = mfs100.ExtractISOImage(lastCapFingerData.RawData(), tempData);if (dataLen <= 0) {if (dataLen == 0) {SetTextOnUIThread("Failed to extract ISO Image");} else {SetTextOnUIThread(mfs100.GetErrorMsg(dataLen));}} else {isoImage = new byte[dataLen];System.arraycopy(tempData, 0, isoImage, 0, dataLen);WriteFile("ISOImage.iso", isoImage);SetTextOnUIThread("Extract ISO Image Success");}} catch (Exception e) {Log.e("Error", "Extract ISO Image Error", e);}}private void ExtractWSQImage() {try {if (lastCapFingerData == null) {SetTextOnUIThread("Finger not capture");return;}byte[] tempData = new byte[(mfs100.GetDeviceInfo().Width() * mfs100.GetDeviceInfo().Height()) + 1078];byte[] wsqImage;int dataLen = mfs100.ExtractWSQImage(lastCapFingerData.RawData(), tempData);if (dataLen <= 0) {if (dataLen == 0) {SetTextOnUIThread("Failed to extract WSQ Image");} else {SetTextOnUIThread(mfs100.GetErrorMsg(dataLen));}} else {wsqImage = new byte[dataLen];System.arraycopy(tempData, 0, wsqImage, 0, dataLen);WriteFile("WSQ.wsq", wsqImage);SetTextOnUIThread("Extract WSQ Image Success");}} catch (Exception e) {Log.e("Error", "Extract WSQ Image Error", e);}}private void UnInitScanner() {try {int ret = mfs100.UnInit();if (ret != 0) {SetTextOnUIThread(mfs100.GetErrorMsg(ret));} else {SetLogOnUIThread("Uninit Success");SetTextOnUIThread("Uninit Success");lastCapFingerData = null;}} catch (Exception e) {Log.e("UnInitScanner.EX", e.toString());}}private void WriteFile(String filename, byte[] bytes) {try {String path = Environment.getExternalStorageDirectory()+ "//FingerData";File file = new File(path);if (!file.exists()) {file.mkdirs();}path = path + "//" + filename;file = new File(path);if (!file.exists()) {file.createNewFile();}FileOutputStream stream = new FileOutputStream(path);stream.write(bytes);stream.close();} catch (Exception e1) {e1.printStackTrace();}}private void ClearLog() {txtEventLog.post(new Runnable() {public void run() {txtEventLog.setText("", BufferType.EDITABLE);}});}private void SetTextOnUIThread(final String str) {lblMessage.post(new Runnable() {public void run() {lblMessage.setText(str);}});}private void SetLogOnUIThread(final String str) {txtEventLog.post(new Runnable() {public void run() {txtEventLog.append("\n" + str);}});}public void SetData2(FingerData fingerData) {if (scannerAction.equals(ScannerAction.Capture)) {Enroll_Template = new byte[fingerData.ISOTemplate().length];System.arraycopy(fingerData.ISOTemplate(), 0, Enroll_Template, 0,fingerData.ISOTemplate().length);} else if (scannerAction.equals(ScannerAction.Verify)) {Verify_Template = new byte[fingerData.ISOTemplate().length];System.arraycopy(fingerData.ISOTemplate(), 0, Verify_Template, 0,fingerData.ISOTemplate().length);int ret = mfs100.MatchISO(Enroll_Template, Verify_Template);if (ret < 0) {SetTextOnUIThread("Error: " + ret + "(" + mfs100.GetErrorMsg(ret) + ")");} else {if (ret >= 1400) {SetTextOnUIThread("Finger matched with score: " + ret);} else {SetTextOnUIThread("Finger not matched, score: " + ret);}}}WriteFile("Raw.raw", fingerData.RawData());WriteFile("Bitmap.bmp", fingerData.FingerImage());WriteFile("ISOTemplate.iso", fingerData.ISOTemplate());}@Overridepublic void OnDeviceAttached(int vid, int pid, boolean hasPermission) {int ret;if (!hasPermission) {SetTextOnUIThread("Permission denied");return;}if (vid == 1204 || vid == 11279) {if (pid == 34323) {ret = mfs100.LoadFirmware();if (ret != 0) {SetTextOnUIThread(mfs100.GetErrorMsg(ret));} else {SetTextOnUIThread("Load firmware success");}} else if (pid == 4101) {String key = "Without Key";ret = mfs100.Init();if (ret == 0) {showSuccessLog(key);} else {SetTextOnUIThread(mfs100.GetErrorMsg(ret));}}}}private void showSuccessLog(String key) {SetTextOnUIThread("Init success");String info = "\nKey: " + key + "\nSerial: "+ mfs100.GetDeviceInfo().SerialNo() + " Make: "+ mfs100.GetDeviceInfo().Make() + " Model: "+ mfs100.GetDeviceInfo().Model()+ "\nCertificate: " + mfs100.GetCertification();SetLogOnUIThread(info);}@Overridepublic void OnDeviceDetached() {UnInitScanner();SetTextOnUIThread("Device removed");}@Overridepublic void OnHostCheckFailed(String err) {try {SetLogOnUIThread(err);Toast.makeText(this, err, Toast.LENGTH_LONG).show();} catch (Exception ignored) {}}}
activity_mfs100_sample.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"tools:context=".MFS100Test" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="top"android:orientation="vertical"android:paddingTop="0dp" ><TextViewandroid:id="@+id/lblTitle"style="@style/title"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/title"android:gravity="center"android:padding="5dp"android:text="@string/app_title"android:textSize="20sp"android:textStyle="bold"android:visibility="gone"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="top"android:orientation="vertical"android:paddingTop="5dp" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:layout_marginRight="5dp"android:orientation="horizontal"android:paddingLeft="10dp"android:paddingRight="10dp" ><ImageViewandroid:id="@+id/imgFinger"android:layout_width="100dp"android:layout_height="120dp"android:background="@drawable/imagefinger"android:contentDescription="@string/app_name"android:scaleType="fitXY"android:src="@drawable/finger" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:paddingLeft="5dp" ><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Buttonandroid:id="@+id/btnInit"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="@string/Init" /><Buttonandroid:id="@+id/btnUninit"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="@string/UnInit" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><Buttonandroid:id="@+id/btnSyncCapture"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="@string/SyncCapture" /><Buttonandroid:id="@+id/btnStopCapture"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="@string/StopSyncCapture" /></LinearLayout><CheckBoxandroid:id="@+id/cbFastDetection"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingLeft="5dp"android:text="Fast Finger Detection"android:textColor="@android:color/black"android:textSize="15sp"android:textStyle="bold" /></LinearLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:layout_marginRight="5dp"android:layout_marginTop="1dp"android:orientation="horizontal"android:paddingLeft="10dp"android:paddingRight="10dp" ><Buttonandroid:id="@+id/btnMatchISOTemplate"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="@string/MatchISO" /><Buttonandroid:id="@+id/btnExtractISOImage"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="EXTRACT ISO" /></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:layout_marginRight="5dp"android:layout_marginTop="1dp"android:orientation="horizontal"android:paddingLeft="10dp"android:paddingRight="10dp" ><Buttonandroid:id="@+id/btnExtractAnsi"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="EXTRACT ANSI" /><Buttonandroid:id="@+id/btnExtractWSQImage"style="@style/buttonbig2"android:background="@drawable/button"android:onClick="onControlClicked"android:text="EXTRACT WSQ" /></LinearLayout></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:gravity="top"android:orientation="vertical"android:paddingBottom="3dp"android:paddingTop="5dp" ><TextViewandroid:id="@+id/lblMessage"style="@style/message"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/message"android:gravity="center"android:padding="5dp"android:text=""android:textSize="15dp"android:textStyle="bold" /><EditTextandroid:id="@+id/txtEventLog"style="@style/message"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_weight="0.70"android:background="@drawable/message"android:gravity="top|left"android:inputType="textMultiLine"android:padding="5dp"android:text=""android:textSize="14dp" /><Buttonandroid:id="@+id/btnClearLog"style="@style/buttonfull"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@drawable/button"android:onClick="onControlClicked"android:text="@string/ClearLog" /></LinearLayout></LinearLayout>
No comments:
Post a Comment