diff --git a/.travis.yml b/.travis.yml
index d8a6d132..00112ce0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,3 +18,4 @@ script:
- ./gradlew clean :BlinkIDDirectApiDemo:assembleRelease
- ./gradlew clean :BlinkIDRandomScanDemo:assembleRelease
- ./gradlew clean :BlinkIDImageListenerDemo:assembleRelease
+ - ./gradlew clean :BlinkIDCustomCombinedDemo:assembleRelease
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/.gitignore b/BlinkIDDemo/BlinkIDCustomCombinedDemo/.gitignore
new file mode 100644
index 00000000..796b96d1
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/build.gradle b/BlinkIDDemo/BlinkIDCustomCombinedDemo/build.gradle
new file mode 100644
index 00000000..eef77694
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/build.gradle
@@ -0,0 +1,30 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "25.0.2"
+
+ defaultConfig {
+ applicationId "com.microblink.blinkid"
+ minSdkVersion 16
+ targetSdkVersion 25
+ versionCode 1
+ versionName "1.0"
+
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile("com.microblink:blinkid:${rootProject.ext.blinkIdVersion}@aar") {
+ transitive = true
+ }
+ compile project(':LibResult')
+ compile "com.android.support:percent:${rootProject.ext.appCompatVersion}"
+
+}
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/proguard-rules.pro b/BlinkIDDemo/BlinkIDCustomCombinedDemo/proguard-rules.pro
new file mode 100644
index 00000000..64bf4475
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /usr/local/opt/android-sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/AndroidManifest.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..09ab5348
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/AndroidManifest.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/CustomVerificationFlowActivity.java b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/CustomVerificationFlowActivity.java
new file mode 100644
index 00000000..0520061a
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/CustomVerificationFlowActivity.java
@@ -0,0 +1,1191 @@
+package com.microblink.blinkid;
+
+import android.annotation.TargetApi;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.SoundPool;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.RawRes;
+import android.support.annotation.StringRes;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.app.AppCompatActivity;
+import android.view.InflateException;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.microblink.blinkid.managers.DocumentViewfinderManager;
+import com.microblink.detectors.DetectorResult;
+import com.microblink.detectors.mrz.MrzDetectorResult;
+import com.microblink.geometry.Rectangle;
+import com.microblink.hardware.SuccessCallback;
+import com.microblink.hardware.camera.AutoFocusRequiredButNotSupportedException;
+import com.microblink.hardware.camera.CameraResolutionTooSmallException;
+import com.microblink.hardware.camera.CameraType;
+import com.microblink.hardware.orientation.Orientation;
+import com.microblink.image.ImageListener;
+import com.microblink.metadata.DetectionMetadata;
+import com.microblink.metadata.GlareMetadata;
+import com.microblink.metadata.ImageMetadata;
+import com.microblink.metadata.Metadata;
+import com.microblink.metadata.MetadataListener;
+import com.microblink.metadata.MetadataSettings;
+import com.microblink.metadata.OcrMetadata;
+import com.microblink.metadata.RecognitionResultMetadata;
+import com.microblink.recognition.FeatureNotSupportedException;
+import com.microblink.recognition.InvalidLicenceKeyException;
+import com.microblink.recognition.RecognizerError;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.RecognitionResults;
+import com.microblink.recognizers.blinkid.CombinedRecognitionResult;
+import com.microblink.recognizers.blinkid.CombinedRecognizerSettings;
+import com.microblink.recognizers.settings.RecognitionSettings;
+import com.microblink.recognizers.settings.RecognizerSettings;
+import com.microblink.util.CameraPermissionManager;
+import com.microblink.util.Log;
+import com.microblink.view.CameraAspectMode;
+import com.microblink.view.CameraEventsListener;
+import com.microblink.view.NonLandscapeOrientationNotSupportedException;
+import com.microblink.view.NotSupportedReason;
+import com.microblink.view.OnActivityFlipListener;
+import com.microblink.view.OrientationAllowedListener;
+import com.microblink.view.ocrResult.IOcrResultView;
+import com.microblink.view.ocrResult.OcrResultDotsView;
+import com.microblink.view.recognition.ParcelableScanResultListener;
+import com.microblink.view.recognition.RecognitionType;
+import com.microblink.view.recognition.RecognizerView;
+import com.microblink.view.recognition.ScanResultListener;
+import com.microblink.view.viewfinder.PointSetView;
+import com.microblink.view.viewfinder.ViewfinderShapeView;
+
+/**
+ * Scan activity designed for scanning documents by using combined recognizers
+ * ({@link com.microblink.recognizers.blinkid.CombinedRecognizerSettings}). Scanning is performed
+ * in multiple steps, in each step single side/part of the document is being scanned.
+ */
+public class CustomVerificationFlowActivity extends AppCompatActivity implements CameraEventsListener, ScanResultListener, MetadataListener, OnActivityFlipListener {
+
+ /**
+ * Key for setting the license key
+ */
+ public static final String EXTRAS_LICENSE_KEY = "EXTRAS_LICENSE_KEY";
+
+ /**
+ * Key for setting the license owner
+ */
+ public static final String EXTRAS_LICENSEE = "EXTRAS_LICENSEE";
+
+ /**
+ * Combined recognizer settings. Must be instance of the {@link CombinedRecognizerSettings}.
+ */
+ public static final String EXTRAS_COMBINED_RECOGNIZER_SETTINGS = "EXTRAS_COMBINED_RECOGNIZER_SETTINGS";
+
+ /**
+ * Expected value type is {@link CameraType} - type of camera to be used for document scan
+ * (back facing, front facing, default)
+ */
+ public static final String EXTRAS_COMBINED_CAMERA_TYPE = "EXTRAS_CAMERA_TYPE";
+
+ /**
+ * Key for obtaining result of the combined recognizer after scanning is done and activity has finished.
+ */
+ public static final String EXTRAS_COMBINED_RECOGNITION_RESULT = "EXTRAS_COMBINED_RECOGNIZER_RESULT";
+
+ /**
+ * Resource ID of sound which is to be played after finishing the scan
+ * procedure.
+ */
+ public static final String EXTRAS_BEEP_RESOURCE = "EXTRAS_BEEP_RESOURCE";
+
+ /**
+ * Define an {@link ImageListener} that will obtain images that are being processed.
+ * Make sure that your ImageListener implementation correctly implements Parcelable
+ * interface with static CREATOR field. Without this, you might encounter a runtime error.
+ */
+ public static final String EXTRAS_IMAGE_LISTENER = "EXTRAS_IMAGE_LISTENER";
+
+ /**
+ * Define a {@link com.microblink.metadata.MetadataSettings.ImageMetadataSettings} that will define
+ * which images will be sent to {@link ImageListener} set via {@link #EXTRAS_IMAGE_LISTENER} extra.
+ * If not set, {@link ImageListener} set via {@link #EXTRAS_IMAGE_LISTENER} will receive all possible
+ * images.
+ */
+ public static final String EXTRAS_IMAGE_METADATA_SETTINGS = "EXTRAS_IMAGE_METADATA_SETTINGS";
+
+ /**
+ * Key for passing a {@link ParcelableScanResultListener} with callback that will be called when
+ * valid recognition result is available (for each result that is produced by activated recognizers).
+ * When scan result listener is passed to the activity, recognition results will not be returned
+ * to the caller activity through result intent. Scan result listener must be used in cases when
+ * size of the recognition results exceeds the allowed Android intent size limit.
+ */
+ public static final String EXTRAS_SCAN_RESULT_LISTENER = "EXTRAS_SCAN_RESULT_LISTENER";
+
+ /**
+ * Force using legacy Camera API even on Lollipop devices that support new Camera2 API.
+ * Use this only if you have problems with camera management on Lollipop devices.
+ */
+ public static final String EXTRAS_USE_LEGACY_CAMERA_API = "EXTRAS_USE_LEGACY_CAMERA_API";
+
+ /**
+ * String resource ID for the title of the warning dialog that is shown when combined recognizer
+ * data does not pass validation (e.g. document sides don't match).
+ */
+ public static final String EXTRAS_WARNING_DIALOG_NOT_MATCH_TITLE_RES = "EXTRAS_WARNING_DIALOG_NOT_MATCH_TITLE";
+ /**
+ * String resource ID for the message of the warning dialog that is shown when combined recognizer
+ * data does not pass validation (e.g. document sides don't match).
+ */
+ public static final String EXTRAS_WARNING_DIALOG_NOT_MATCH_MESSAGE_RES = "EXTRAS_WARNING_DIALOG_NOT_MATCH_MESSAGE";
+ /**
+ * String resource ID for the button text of the warning dialog that is shown when combined recognizer
+ * data does not pass validation (e.g. document sides don't match).
+ */
+ public static final String EXTRAS_WARNING_DIALOG_NOT_MATCH_BUTTON_TEXT_RES = "EXTRAS_WARNING_DIALOG_NOT_MATCH_BUTTON_TEXT";
+
+ /**
+ * Resource ID of the string that will be shown above document scan viewfinder when scanning of the first side of the document
+ * is starting.
+ */
+ public static final String EXTRAS_SPLASH_MSG_RES_DOCUMENT_FIRST_SIDE = "EXTRAS_SPLASH_MSG_RES_DOCUMENT_FIRST_SIDE";
+ /**
+ * Drawable resource id of the image that will be shown above document scan viewfinder when scanning of the
+ * first side of the document is starting.
+ */
+ public static final String EXTRAS_SPLASH_ICON_RES_DOCUMENT_FIRST_SIDE = "EXTRAS_SPLASH_ICON_RES_DOCUMENT_FIRST_SIDE";
+
+ /**
+ * Resource ID of the string that will be shown above document scan viewfinder when scanning of the second side of the document
+ * is starting.
+ */
+ public static final String EXTRAS_SPLASH_MSG_RES_DOCUMENT_SECOND_SIDE = "EXTRAS_SPLASH_MSG_RES_DOCUMENT_SECOND_SIDE";
+ /**
+ * Drawable resource id of the image that will be shown above document scan viewfinder when scanning of the
+ * second side of the document is starting.
+ */
+ public static final String EXTRAS_SPLASH_ICON_RES_DOCUMENT_SECOND_SIDE = "EXTRAS_SPLASH_ICON_RES_DOCUMENT_SECOND_SIDE";
+
+ /**
+ * String resource ID of the scan instructions that will be shown to the user as camera overlay during recognition
+ * of the first side of the document.
+ */
+ public static final String EXTRAS_INSTRUCTIONS_DOCUMENT_FIRST_SIDE = "EXTRAS_INSTRUCTIONS_DOCUMENT_FIRST_SIDE";
+
+ /**
+ * String resource ID of the scan instructions that will be shown to the user as camera overlay during recognition
+ * of the second side of the document.
+ */
+ public static final String EXTRAS_INSTRUCTIONS_DOCUMENT_SECOND_SIDE = "EXTRAS_INSTRUCTIONS_DOCUMENT_SECOND_SIDE";
+
+ /** Duration of the glare message in milliseconds*/
+ private static final long GLARE_MESSAGE_DURATION = 1500;
+ /** Duration of the splash screen when camera is starting (after the camera preview has started) */
+ private static final long SPLASH_DURATION_CAMERA_STARTING = 500;
+ /** Duration of the splash screen when next side of the document should be scanned */
+ private static final long SPLASH_DURATION_NEXT_SIDE = 1000;
+ /** Duration of the alpha animation on splash screen in milliseconds */
+ private static final long SPLASH_FADE_ANIMATION_DURATION = 500;
+
+ private static final int TORCH_ID = 0x25;
+
+ /** Handler associated withe the main thread. */
+ protected Handler mHandler = new Handler(Looper.getMainLooper());
+
+ /** Flag which indicates whether torch(flashlight) is on or off. */
+ private boolean mTorchOn = false;
+
+ /**
+ * Status overlay container, part of the screen where message (user instructions)
+ * and document icon (indicates document side) is shown.
+ */
+ private View mStatusOverlay;
+ /**
+ * Icon of the current document (document side) that is being scanned.
+ */
+ private ImageView mStatusImage;
+ /**
+ * Message (user instructions) for the current document (document side).
+ */
+ private TextView mStatusMsg;
+ /**
+ * Text view where messages about glare status are printed.
+ */
+ private TextView mGlareMsg;
+
+ /** Torch menu item from the action bar, if the action bar is hidden, it will be {@code null} */
+ private MenuItem mTorchItem = null;
+ /** Torch image button from the camera overlay, if the action bar is shown, it will be {@code null}
+ * because torch button from the action bar will be used. */
+ private ImageButton mIbTorch = null;
+
+ /** Document viewfinder manager that is used for showing the splash screens over the viewfinder */
+ private DocumentViewfinderManager mDocumentViewfinderManager;
+
+ @StringRes
+ private int mSplashMsgDocFirstSide;
+
+ @StringRes
+ private int mSplashMsgDocSecondSide;
+
+ @StringRes
+ private int mInstructionsDocFirstSide;
+
+ @StringRes
+ private int mInstructionsDocSecondSide;
+
+ @DrawableRes
+ private int mSplashIconDocFirstSide = R.drawable.frontid_white;
+
+ @DrawableRes
+ private int mSplashIconDocSecondSide = R.drawable.backid_white;
+
+ private static final int MRZ_DETECTION_POINT_RADIUS = 7;
+ private static final int NUM_MS_BEFORE_TIMEOUT_DEFAULT = 30_000;
+
+ protected RecognizerView mRecognizerView;
+
+ private SoundPool mSoundPool;
+ private @RawRes int mSoundResourceId = -1;
+ private int mSoundId;
+
+ /** CameraPermissionManager is provided helper class that can be used to obtain the permission to use camera.
+ * It is used on Android 6.0 (API level 23) or newer.
+ */
+ private CameraPermissionManager mCameraPermissionManager;
+ private MetadataSettings.ImageMetadataSettings mImageMetadataSettings;
+
+ /** View which shows OCR result over the camera preview. */
+ private IOcrResultView mOcrView;
+ /** View which shows MRZ detection points. */
+ private PointSetView mMrzPointsView = null;
+
+ private CombinedRecognizerSettings mCombinedRecognizerSettings;
+
+ private BaseRecognitionResult mCombinedRecognitionResult;
+ private BaseRecognitionResult mCombinedFirstSideResult;
+
+ private ImageListener mImageListener;
+ private ParcelableScanResultListener mScanResultListener;
+
+ private CombinedSide mCurrentCombinedSide = CombinedSide.FIRST_SIDE;
+ private CameraType mCombinedCameraType = CameraType.CAMERA_BACKFACE;
+
+ /** Camera overlay container. */
+ private FrameLayout mCameraOverlayRoot;
+
+ @StringRes
+ int mDialogNotMatchTitleRes;
+ @StringRes
+ int mDialogNotMatchMessageRes;
+ @StringRes
+ int mDialogNotMatchButtonTextRes;
+
+
+ protected enum ActivityState {
+ DESTROYED,
+ CREATED,
+ STARTED,
+ RESUMED
+ }
+
+ private enum CombinedSide {
+ FIRST_SIDE,
+ SECOND_SIDE
+ }
+
+ private ActivityState mActivityState = ActivityState.DESTROYED;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ActionBar ab = getSupportActionBar();
+ if (ab != null) {
+ // show back icon in the app bar
+ ab.setDisplayHomeAsUpEnabled(true);
+ }
+ // initially torch is turned off
+ mTorchOn = false;
+ try {
+ setContentView(R.layout.activity_custom_verification_flow);
+ } catch (InflateException ie) {
+ Throwable cause = ie.getCause();
+ while (cause.getCause() != null) {
+ cause = cause.getCause();
+ }
+ if (cause instanceof NonLandscapeOrientationNotSupportedException) {
+ Log.e(this, "NonLandscapeOrientationNotSupported");
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ if (Build.VERSION.SDK_INT >= 11) {
+ recreate();
+ }
+ return;
+ } else {
+ throw ie;
+ }
+ }
+
+ Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+
+ mSoundResourceId = extras.getInt(EXTRAS_BEEP_RESOURCE, 0);
+
+ mDialogNotMatchTitleRes = extras.getInt(EXTRAS_WARNING_DIALOG_NOT_MATCH_TITLE_RES);
+ mDialogNotMatchMessageRes = extras.getInt(EXTRAS_WARNING_DIALOG_NOT_MATCH_MESSAGE_RES);
+ mDialogNotMatchButtonTextRes = extras.getInt(EXTRAS_WARNING_DIALOG_NOT_MATCH_BUTTON_TEXT_RES);
+
+ CameraType cameraType = extras.getParcelable(EXTRAS_COMBINED_CAMERA_TYPE);
+ if (cameraType != null) {
+ mCombinedCameraType = cameraType;
+ }
+
+ mImageListener = extras.getParcelable(EXTRAS_IMAGE_LISTENER);
+ if (mImageListener != null) {
+ // check if user has set image metadata settings
+ mImageMetadataSettings = extras.getParcelable(EXTRAS_IMAGE_METADATA_SETTINGS);
+ }
+
+ mScanResultListener = extras.getParcelable(EXTRAS_SCAN_RESULT_LISTENER);
+
+ mCombinedRecognizerSettings = extras.getParcelable(EXTRAS_COMBINED_RECOGNIZER_SETTINGS);
+
+ boolean useLegacyCamera = extras.getBoolean(EXTRAS_USE_LEGACY_CAMERA_API, false);
+
+ String licenseKey, licensee;
+ licenseKey = extras.getString(EXTRAS_LICENSE_KEY);
+ licensee = extras.getString(EXTRAS_LICENSEE);
+
+ mCombinedRecognizerSettings = extras.getParcelable(EXTRAS_COMBINED_RECOGNIZER_SETTINGS);
+ if (mCombinedRecognizerSettings == null) {
+ throw new NullPointerException("Combined recognizer settings are required.");
+ }
+
+ mInstructionsDocFirstSide = extras.getInt(EXTRAS_INSTRUCTIONS_DOCUMENT_FIRST_SIDE, R.string.tooltip_front_id);
+ mInstructionsDocSecondSide = extras.getInt(EXTRAS_INSTRUCTIONS_DOCUMENT_SECOND_SIDE, R.string.tooltip_back_id);
+ mSplashMsgDocFirstSide = extras.getInt(EXTRAS_SPLASH_MSG_RES_DOCUMENT_FIRST_SIDE, R.string.splash_msg_id_front);
+ mSplashMsgDocSecondSide = extras.getInt(EXTRAS_SPLASH_MSG_RES_DOCUMENT_SECOND_SIDE, R.string.splash_msg_id_back);
+ mSplashIconDocFirstSide = extras.getInt(EXTRAS_SPLASH_ICON_RES_DOCUMENT_FIRST_SIDE, R.drawable.frontid_white);
+ mSplashIconDocSecondSide = extras.getInt(EXTRAS_SPLASH_ICON_RES_DOCUMENT_SECOND_SIDE, R.drawable.backid_white);
+
+ initRecognizerView(licenseKey, licensee, useLegacyCamera);
+ } else {
+ throw new NullPointerException("CustomVerificationFlowActivity requires intent extras: license key and recognizer settings");
+ }
+
+ ViewGroup vgRoot = (ViewGroup) findViewById(R.id.rootRecognizerView);
+
+ mCameraPermissionManager = new CameraPermissionManager(this);
+ View permissionOverlay = mCameraPermissionManager.getAskPermissionOverlay();
+ if (permissionOverlay != null) {
+ vgRoot.addView(permissionOverlay);
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ AudioAttributes audioAttrs = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
+ .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+ .build();
+ mSoundPool = new SoundPool.Builder().setMaxStreams(1).setAudioAttributes(audioAttrs).build();
+ } else {
+ mSoundPool = createOldSoundPool();
+ }
+
+ if (mSoundResourceId > 0) {
+ mSoundId = mSoundPool.load(this, mSoundResourceId, 1);
+ setVolumeControlStream(AudioManager.STREAM_MUSIC);
+ }
+
+ }
+
+ private void initRecognizerView(String licenseKey, String licensee, boolean forceUseLegacyCamera) {
+ mRecognizerView = (RecognizerView) findViewById(R.id.recognizerView);
+
+ try {
+ if (licensee == null) {
+ mRecognizerView.setLicenseKey(licenseKey);
+ } else {
+ mRecognizerView.setLicenseKey(licenseKey, licensee);
+ }
+ } catch (InvalidLicenceKeyException exc) {
+ Log.e(this, exc, "INVALID LICENCE KEY");
+ }
+
+ mRecognizerView.setForceUseLegacyCamera(forceUseLegacyCamera);
+ mRecognizerView.setRecognitionSettings(buildRecognitionSettings());
+
+ mRecognizerView.setCameraType(mCombinedCameraType);
+ // set camera aspect mode to FILL - this will use the entire surface
+ // for camera preview, instead of letterboxing it
+ mRecognizerView.setAspectMode(CameraAspectMode.ASPECT_FILL);
+ // scan result listener will be notified when scan result gets available
+ mRecognizerView.setScanResultListener(this);
+ // camera events listener receives events such as when camera preview has started
+ // or there was an error while starting the camera
+ mRecognizerView.setCameraEventsListener(this);
+ mRecognizerView.setInitialOrientation(Orientation.ORIENTATION_PORTRAIT);
+ mRecognizerView.setPinchToZoomAllowed(false);
+
+ // orientation allowed listener is asked if orientation is allowed when device orientation
+ // changes - if orientation is allowed, rotatable views will be rotated to that orientation
+ mRecognizerView.setOrientationAllowedListener(new OrientationAllowedListener() {
+ @Override
+ public boolean isOrientationAllowed(Orientation orientation) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ // if in multi window mode, all orientations are allowed
+ return isInMultiWindowMode();
+ }
+ // only initial portrait orientation is allowed if not in multi window mode
+ return false;
+ }
+ });
+
+ mRecognizerView.setMetadataListener(this, createMetadataSettings(mImageMetadataSettings));
+
+ // all activity lifecycle events must be passed on to RecognizerView, this method is called
+ // from activity onCreate
+ mRecognizerView.create();
+
+ mMrzPointsView = new PointSetView(this, null, mRecognizerView.getHostScreenOrientation(), MRZ_DETECTION_POINT_RADIUS, ContextCompat.getColor(this, R.color.mrz_point_color));
+ mRecognizerView.addChildView(mMrzPointsView, false);
+ mOcrView = new OcrResultDotsView(this, null, mRecognizerView.getHostScreenOrientation());
+ mRecognizerView.addChildView(mOcrView.getView(), false);
+
+ mCameraOverlayRoot = new FrameLayout(this);
+ mCameraOverlayRoot.setLayoutParams(
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ mCameraOverlayRoot.addView(createCombinedStepCameraOverlay());
+ // camera overlay is rotatable = true
+ mRecognizerView.addChildView(mCameraOverlayRoot, true);
+ }
+
+ private MetadataSettings createMetadataSettings(MetadataSettings.ImageMetadataSettings imageMetadataSettings) {
+ MetadataSettings metadataSettings = new MetadataSettings();
+ if (mImageListener != null) {
+ // if not set, then enable all images
+ if (imageMetadataSettings == null) {
+ // enable all images
+ imageMetadataSettings = new MetadataSettings.ImageMetadataSettings();
+ imageMetadataSettings.setCurrentVideoFrameEnabled(true);
+ imageMetadataSettings.setDewarpedImageEnabled(true);
+ imageMetadataSettings.setSuccessfulScanFrameEnabled(true);
+
+ MetadataSettings.ImageMetadataSettings.DebugImageMetadataSettings dims = new MetadataSettings.ImageMetadataSettings.DebugImageMetadataSettings();
+ dims.setAll(true);
+
+ imageMetadataSettings.setDebugImageMetadataSettings(dims);
+ }
+ metadataSettings.setImageMetadataSettings(imageMetadataSettings);
+ }
+ metadataSettings.setOcrMetadataAllowed(true);
+ metadataSettings.setDetectionMetadataAllowed(true);
+ // obtaining of partial result metadata must be enabled to get notification and result
+ // from the first part/side of the document when it is successfully scanned
+ metadataSettings.setPartialResultMetadataAllowed(true);
+ // enable obtaining of glare metadata (glare detection status)
+ metadataSettings.setGlareMetadataAllowed(true);
+ return metadataSettings;
+ }
+
+ /** Builds recognition settings with chosen combined recognizer settings. */
+ private RecognitionSettings buildRecognitionSettings() {
+ RecognitionSettings settings = new RecognitionSettings();
+ settings.setNumMsBeforeTimeout(NUM_MS_BEFORE_TIMEOUT_DEFAULT);
+ settings.setRecognizerSettingsArray(new RecognizerSettings[]{mCombinedRecognizerSettings});
+ return settings;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mActivityState = ActivityState.STARTED;
+ if (mRecognizerView != null) {
+ // all activity lifecycle events must be passed on to RecognizerView
+ mRecognizerView.start();
+ }
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mActivityState = ActivityState.RESUMED;
+ onGlareStatus(false);
+ clearScanIndicatorViews();
+ if (mCurrentCombinedSide == CombinedSide.SECOND_SIDE) {
+ // when resume() on recognizer view is called, hard reset is called which resets the combined recognizer to scan first
+ // side again and appropriate UI changes should be performed if the combined recognizer is not
+ // in the initial state
+ mCurrentCombinedSide = CombinedSide.FIRST_SIDE;
+ initStep(false);
+ } else {
+ reportStepStart(false);
+ }
+ if (mRecognizerView != null) {
+ // all activity lifecycle events must be passed on to RecognizerView
+ mRecognizerView.resume();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ mActivityState = ActivityState.STARTED;
+ if (mRecognizerView != null) {
+ // all activity lifecycle events must be passed on to RecognizerView
+ mRecognizerView.pause();
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mActivityState = ActivityState.CREATED;
+ if (mRecognizerView != null) {
+ // all activity lifecycle events must be passed on to RecognizerView
+ mRecognizerView.stop();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mActivityState = ActivityState.DESTROYED;
+ if (mRecognizerView != null) {
+ // all activity lifecycle events must be passed on to RecognizerView
+ mRecognizerView.destroy();
+ }
+ if (mSoundPool != null) {
+ try {
+ mSoundPool.release();
+ } catch (IllegalStateException ignorable) {}
+ mSoundPool = null;
+ mSoundId = -1;
+ }
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ if (mRecognizerView == null) {
+ return;
+ }
+ // update recognizer view configuration
+ mRecognizerView.changeConfiguration(newConfig);
+ // update orientation on OCR result views
+ if (mOcrView != null) {
+ mOcrView.setHostActivityOrientation(mRecognizerView.getHostScreenOrientation());
+ }
+ if (mMrzPointsView != null) {
+ mMrzPointsView.setHostActivityOrientation(mRecognizerView.getHostScreenOrientation());
+ }
+ }
+
+
+ @Override
+ public void onCameraPreviewStarted() {
+ // pause scanning until the splash screen is cleared
+ // splash screen has been shown in onStartCombinedFirstSide or in onStartCombinedSecondSide
+ // that has been called before
+ pauseScanning();
+
+ if (!mRecognizerView.isCameraTorchSupported()) {
+ // if application bar is hidden mIbTorch is used, otherwise
+ // menu item mTorchItem is used
+ if (mTorchItem != null) {
+ mTorchItem.setVisible(false);
+ }
+ if (mIbTorch != null) {
+ mIbTorch.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ if (mActivityState == ActivityState.RESUMED) {
+ mRecognizerView.setMeteringAreas(new RectF[]{new Rectangle(0.33f, 0.33f, 0.33f, 0.33f).toRectF() }, true);
+ }
+
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ // clear splash screen and resume scanning (true)
+ clearSplashScreen(true);
+ }
+ }, SPLASH_DURATION_CAMERA_STARTING);
+ }
+
+ @Override
+ public void onCameraPreviewStopped() {
+ // do nothing
+ }
+
+ @Override
+ public void onError(Throwable ex) {
+ String defaultDialogTitle = getString(R.string.mbWarningTitle);
+ if (ex instanceof CameraResolutionTooSmallException) {
+ Log.e(this, ex, "Camera resolution too low!");
+ handleError(defaultDialogTitle, getString(R.string.FeatureUnsuportedDevice));
+ } else if (ex instanceof RecognizerError) {
+ Log.e(this, ex, "There was an error starting a native recognizer. Reason: {}", ex.getMessage());
+ handleError(defaultDialogTitle, getString(R.string.mbErrorInitializing));
+ } else if (ex instanceof UnsatisfiedLinkError) {
+ Log.e(this, ex, "Native library not loaded!");
+ handleError(defaultDialogTitle, getString(R.string.mbErrorInitializing));
+ } else if (ex instanceof AutoFocusRequiredButNotSupportedException) {
+ Log.e(this, ex, "Autofocus required, but not supported!");
+ handleError(defaultDialogTitle, getNotSupportedReasonDescription(NotSupportedReason.NO_AUTOFOCUS_CAMERA));
+ } else if (ex instanceof FeatureNotSupportedException) {
+ handleError(defaultDialogTitle, getNotSupportedReasonDescription(((FeatureNotSupportedException) ex).getReason()));
+ } else if (ex instanceof SecurityException) {
+ Log.e(this, ex, "Camera permission not given!");
+ handleError(defaultDialogTitle, getString(R.string.mbCameraNotAllowed));
+ } else {
+ handleError(defaultDialogTitle, getString(R.string.mbCameraNotReady));
+ }
+ }
+
+ private void handleError(String title, String message) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(title)
+ .setMessage(message)
+ .setNeutralButton(getString(R.string.mbOK), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+
+ }).setCancelable(false);
+
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ }
+
+ private String getNotSupportedReasonDescription(NotSupportedReason reason) {
+ switch (reason) {
+ case CUSTOM_UI_FORBIDDEN:
+ return getString(R.string.CustomUIForbidden);
+ case INVALID_LICENSE_KEY:
+ return getString(R.string.InvalidLicense);
+ case UNSUPPORTED_ANDROID_VERSION:
+ return getString(R.string.FeatureUnsuportedAndroidVersion);
+ case NO_AUTOFOCUS_CAMERA:
+ return getString(R.string.FeatureUnsuportedAutofocus);
+ case BLACKLISTED_DEVICE:
+ case NO_CAMERA:
+ case UNSUPPORTED_PROCESSOR_ARCHITECTURE:
+ return getString(R.string.FeatureUnsuportedDevice);
+ }
+ return null;
+ }
+
+ @Override
+ @TargetApi(23)
+ public void onCameraPermissionDenied() {
+ // use camera permission manager to ask for camera permission
+ mCameraPermissionManager.askForCameraPermission();
+ }
+
+ @Override
+ @TargetApi(23)
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ // use camera permission manager to handle request permission result
+ mCameraPermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+
+ @Override
+ public void onAutofocusFailed() {
+ clearScanIndicatorViews();
+ }
+
+ @Override
+ public void onAutofocusStarted(Rect[] focusAreas) {
+ // do nothing
+ }
+
+ @Override
+ public void onAutofocusStopped(Rect[] focusAreas) {
+ // do nothing
+ }
+
+ @Override
+ public void onMetadataAvailable(Metadata metadata) {
+ // This method will be called when metadata becomes available during recognition process.
+ // Here, for every metadata type that is allowed through metadata settings,
+ // desired actions can be performed.
+
+ // detection metadata contains detection locations
+ if (metadata instanceof DetectionMetadata) {
+ final DetectorResult detectionResult = ((DetectionMetadata) metadata).getDetectionResult();
+ // DetectorResult can be null - this means that detection has failed
+ if (detectionResult == null) {
+ // clear MRZ detection points
+ clearScanIndicatorViews();
+ } else if (detectionResult instanceof MrzDetectorResult) {
+ if (mMrzPointsView != null) {
+ MrzDetectorResult res = (MrzDetectorResult) detectionResult;
+ // show MRZ detection points
+ mMrzPointsView.setPointsDetectionResult(res.getPointsDetectorResult());
+ }
+ }
+ } else if (metadata instanceof OcrMetadata) {
+ // show points over the OCR result
+ mOcrView.addOcrResult(((OcrMetadata) metadata).getOcrResult());
+ if (mMrzPointsView != null) {
+ // clear MRZ detection points
+ mMrzPointsView.setPointsDetectionResult(null);
+ }
+ } else if (metadata instanceof GlareMetadata) {
+ // report glare status
+ onGlareStatus(((GlareMetadata) metadata).isGlareDetected());
+ } else if (metadata instanceof ImageMetadata) {
+ // report image metadata to image listener
+ mImageListener.onImageAvailable(((ImageMetadata) metadata).getImage());
+ } else if (metadata instanceof RecognitionResultMetadata) {
+ // when first side is scanned, RecognitionResultMetadata will be returned
+ BaseRecognitionResult result = ((RecognitionResultMetadata) metadata).getScannedResult();
+ if (mCurrentCombinedSide == CombinedSide.FIRST_SIDE) {
+ // prepare UI and activity for the second part/side of the document
+ soundNotification();
+ mCurrentCombinedSide = CombinedSide.SECOND_SIDE;
+ mCombinedFirstSideResult = result;
+ clearScanIndicatorViews();
+ reportStepStart(true);
+ }
+ }
+ }
+
+ /** Clears OCR scan indicator view and MRZ detection points view. */
+ private void clearScanIndicatorViews() {
+ if (mOcrView != null) {
+ mOcrView.clearOcrResults();
+ }
+ if (mMrzPointsView != null) {
+ mMrzPointsView.setPointsDetectionResult(null);
+ }
+ }
+
+ @Override
+ public void onActivityFlip() {
+ if (mRecognizerView != null) {
+ if (mOcrView != null) {
+ mOcrView.setHostActivityOrientation(mRecognizerView.getHostScreenOrientation());
+ }
+ if (mMrzPointsView != null) {
+ mMrzPointsView.setHostActivityOrientation(mRecognizerView.getHostScreenOrientation());
+ }
+ }
+ }
+
+ @Override
+ public void onScanningDone(@Nullable RecognitionResults results) {
+ if (results == null) {
+ return;
+ }
+ final BaseRecognitionResult[] resultArray = results.getRecognitionResults();
+ // pause scanning, be careful to resume scanning later
+ pauseScanning();
+ // we expect one recognition result int he array
+ if (resultArray != null && resultArray.length == 1) {
+ BaseRecognitionResult result = resultArray[0];
+ if (results.getRecognitionType() == RecognitionType.SUCCESSFUL && result instanceof CombinedRecognitionResult) {
+ // play beep sound
+ soundNotification();
+ if (mScanResultListener != null) {
+ mScanResultListener.onScanningDone(results);
+ }
+ mCombinedRecognitionResult = result;
+ if (!((CombinedRecognitionResult) result).isDocumentDataMatch()) {
+ // document data does not match on all parts/sides of the document
+ // scan again and show scan again dialog to the user
+ @StringRes int titleRes = mDialogNotMatchTitleRes == 0 ? R.string.mbAlertTitle : mDialogNotMatchTitleRes;
+ @StringRes int messageRes = mDialogNotMatchMessageRes == 0 ? R.string.mbDataNotMatchMsg : mDialogNotMatchMessageRes;
+ @StringRes int buttonTextRes = mDialogNotMatchButtonTextRes == 0 ? R.string .mbScanAgain : mDialogNotMatchButtonTextRes;
+ new AlertDialog.Builder(this)
+ .setTitle(titleRes)
+ .setMessage(messageRes)
+ .setCancelable(false)
+ .setPositiveButton(buttonTextRes, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ restartVerification();
+ resumeScanning();
+ }
+ })
+ .create()
+ .show();
+ return;
+ }
+ finishWithResults();
+ return;
+ }
+ }
+ resumeScanning();
+ }
+
+ /** Finishes the activity (with scan results if scan result listener is not set). */
+ private void finishWithResults() {
+ Intent intent = new Intent();
+ if (mScanResultListener == null) {
+ // if scan result listener is set, do not return results through intent extras
+ intent.putExtra(EXTRAS_COMBINED_RECOGNITION_RESULT, mCombinedRecognitionResult);
+ }
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ /** Restarts verification flow and clears all previously stored data */
+ private void restartVerification() {
+ if (mCurrentCombinedSide != null) {
+ mCurrentCombinedSide = CombinedSide.FIRST_SIDE;
+ }
+ initStep(true);
+ }
+
+ /** Initializes the current step - updates recognition settings.
+ * @param isCameraPreviewStarted whether the camera preview is started. */
+ private void initStep(boolean isCameraPreviewStarted) {
+ clearScanIndicatorViews();
+ mCameraOverlayRoot.removeAllViews();
+ mCameraOverlayRoot.addView(createCombinedStepCameraOverlay());
+
+ // clear previous results
+ mCombinedFirstSideResult = null;
+
+ RecognitionSettings settings = buildRecognitionSettings();
+ mRecognizerView.reconfigureRecognizers(settings);
+ reportStepStart(isCameraPreviewStarted);
+ }
+
+ private void reportStepStart(boolean isCameraPreviewStarted) {
+ switch (mCurrentCombinedSide) {
+ case FIRST_SIDE:
+ onStartCombinedFirstSide(isCameraPreviewStarted);
+ break;
+ case SECOND_SIDE:
+ onStartCombinedSecondSide(isCameraPreviewStarted, mCombinedFirstSideResult);
+ break;
+ }
+ }
+
+ private void soundNotification() {
+ if (mSoundPool != null && mSoundId != -1) {
+ mSoundPool.play(mSoundId, 1.f, 1.f, 1, 0, 1.f);
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ private SoundPool createOldSoundPool(){
+ return new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
+ }
+
+ /** */
+ private void resumeScanning() {
+ if (mRecognizerView == null) {
+ return;
+ }
+ if (mCurrentCombinedSide == CombinedSide.SECOND_SIDE) {
+ // do not reset the internal state of the combined recognizer because it will scan the first
+ // part/side again
+ mRecognizerView.resumeScanning(false);
+ } else {
+ // if first part/side is being scanned, reset internal recognition state
+ mRecognizerView.resumeScanning(true);
+ }
+ }
+
+ private void pauseScanning() {
+ if (mRecognizerView != null) {
+ mRecognizerView.pauseScanning();
+ }
+ }
+
+ /**
+ * Creates and returns camera overlay view for the combined verification step.
+ * @return created camera overlay view.
+ */
+ @NonNull
+ private View createCombinedStepCameraOverlay() {
+ View documentOverlay = getLayoutInflater().inflate(R.layout.id_card_camera_overlay, mRecognizerView, false);
+
+ mStatusOverlay = documentOverlay.findViewById(R.id.statusOverlay);
+ mGlareMsg = (TextView) documentOverlay.findViewById(R.id.tvGlareMessage);
+ mStatusImage = (ImageView) mStatusOverlay.findViewById(R.id.ivStatusImg);
+ mStatusMsg = (TextView) mStatusOverlay.findViewById(R.id.tvStatusMsg);
+
+ View torchContainer = documentOverlay.findViewById(R.id.torchContainer);
+ if (getSupportActionBar() != null) {
+ // if action bar is shown, torch button from action bar is used
+ torchContainer.setVisibility(View.GONE);
+ } else {
+ // when action bar is hidden, viewfinder top margin is not needed because
+ // torch button layout is used which has appropriate margins
+ View viewfinderMargin = documentOverlay.findViewById(R.id.viewfinderMarginTop);
+ if (viewfinderMargin != null) {
+ viewfinderMargin.setVisibility(View.GONE);
+ }
+ mIbTorch = (ImageButton) torchContainer.findViewById(R.id.torchButton);
+ setTorchButtonIcon(mTorchOn);
+ mIbTorch.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mRecognizerView.setTorchState(!mTorchOn, new SuccessCallback() {
+ @Override
+ public void onOperationDone(boolean success) {
+ if (success) {
+ mTorchOn = !mTorchOn;
+ setTorchButtonIcon(mTorchOn);
+ }
+ }
+ });
+ }
+ });
+ }
+
+ mDocumentViewfinderManager = new DocumentViewfinderManager(
+ (ViewfinderShapeView) documentOverlay.findViewById(R.id.viewfinderRectangle),
+ (TextView) documentOverlay.findViewById(R.id.tvCardMessage),
+ (ImageView) documentOverlay.findViewById(R.id.ivCardIcon)
+ );
+
+ return documentOverlay;
+ }
+
+ private void setTorchButtonIcon(final boolean torchOn) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (mIbTorch == null) {
+ return;
+ }
+ if (torchOn) {
+ mIbTorch.setImageResource(R.drawable.ic_flash_on_24dp);
+ } else {
+ mIbTorch.setImageResource(R.drawable.ic_flash_off_24dp);
+ }
+ }
+ });
+ }
+
+ /**
+ * Method that is called when combined recognizer is set to scan first side and recognition
+ * is started.
+ * @param isCameraPreviewStarted whether camera preview has been already started or not. If the
+ * camera preview has not been started yet (value is {@code false}),
+ * method {@link #onCameraPreviewStarted()} will be called when/if
+ * the camera is successfully started.
+ */
+ private void onStartCombinedFirstSide(boolean isCameraPreviewStarted) {
+ // do not pause scanning if the camera preview has not been started yet because this
+ // method can be called multiple times when camera permission is not granted which
+ // will cause that scanning will not be properly resumed later (pause is counted)
+ if (isCameraPreviewStarted) {
+ pauseScanning();
+ }
+ showDocumentSplashScreen(mSplashMsgDocFirstSide, mSplashIconDocFirstSide);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mStatusMsg.setText(getText(mInstructionsDocFirstSide));
+ mStatusImage.setImageResource(R.drawable.frontid_white);
+ String title = getString(R.string.activity_title_step_front_side);
+ setActivityTitle(title);
+ }
+ });
+ if (isCameraPreviewStarted) {
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ clearSplashScreen(true);
+ }
+ }, SPLASH_DURATION_NEXT_SIDE);
+ }
+ }
+
+ /**
+ * Method that is called when combined recognizer is set to scan second part/side
+ * (only if it exists) and recognition is started.
+ * @param isCameraPreviewStarted whether camera preview has been already started or not. If the
+ * camera preview has not been started yet (value is {@code false}),
+ * method {@link #onCameraPreviewStarted()} will be called when/if
+ * the camera is successfully started.
+ * @param combinedFirstSideResult recognition result for the first side of the combined document
+ * that has been scanned
+ */
+ private void onStartCombinedSecondSide(boolean isCameraPreviewStarted, BaseRecognitionResult combinedFirstSideResult) {
+ // do not pause scanning if the camera preview has not been started yet because this
+ // method can be called multiple times when camera permission is not granted which
+ // will cause that scanning will not be properly resumed later (pause is counted)
+ if (isCameraPreviewStarted) {
+ pauseScanning();
+ }
+ showDocumentSplashScreen(mSplashMsgDocSecondSide, mSplashIconDocSecondSide);
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mStatusMsg.setText(getText(mInstructionsDocSecondSide));
+ mStatusImage.setImageResource(R.drawable.backid_white);
+ String title = getString(R.string.activity_title_step_back_side);
+ setActivityTitle(title);
+ }
+ });
+ if (isCameraPreviewStarted) {
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ clearSplashScreen(true);
+ }
+ }, SPLASH_DURATION_NEXT_SIDE);
+ }
+ }
+
+ /**
+ * Sets the activity title in the action bar.
+ * @param title activity title.
+ */
+ protected void setActivityTitle(String title) {
+ ActionBar ab = getSupportActionBar();
+ if (ab != null) {
+ ab.setTitle(title);
+ }
+ }
+
+ /**
+ * Method that is called during recognition process when/if the glare is detected on the
+ * scanned document.
+ * @param glareDetected whether glare is detected or not.
+ */
+ private void onGlareStatus(boolean glareDetected) {
+ if (mGlareMsg != null) {
+ if (glareDetected) {
+ mGlareCountDownTimer.cancel();
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mGlareMsg.setVisibility(View.VISIBLE);
+
+ }
+ });
+ mGlareCountDownTimer.start();
+ }
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ mTorchItem = menu.add(Menu.NONE, TORCH_ID, Menu.NONE, R.string.action_torch);
+ mTorchItem.setIcon(R.drawable.ic_flash_off_24dp);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ mTorchItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(final MenuItem item) {
+ int id = item.getItemId();
+ if (id == TORCH_ID) {
+ mRecognizerView.setTorchState(!mTorchOn, new SuccessCallback() {
+ @Override
+ public void onOperationDone(boolean success) {
+ if (success) {
+ mTorchOn = !mTorchOn;
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ if (mTorchOn) {
+ item.setIcon(R.drawable.ic_flash_on_24dp);
+ } else {
+ item.setIcon(R.drawable.ic_flash_off_24dp);
+ }
+ }
+ });
+ }
+ }
+ });
+ return true;
+ } else if (id == android.R.id.home) {
+ setResult(RESULT_CANCELED);
+ super.onBackPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void showDocumentSplashScreen(@StringRes int splashMessage, @DrawableRes int splashImageResID) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mStatusOverlay.setVisibility(View.INVISIBLE);
+ }
+ });
+ // show splash screen on document viewfinder manager
+ if (mDocumentViewfinderManager != null) {
+ mDocumentViewfinderManager.showSplashScreen(
+ getString(splashMessage),
+ splashImageResID,
+ R.color.viewfinder_inner_splash
+ );
+ }
+ }
+
+ /**
+ * Clears currently shown splash screen and resumes scanning if requested.
+ * @param resumeScanning whether resume scanning will be called or not.
+ */
+ protected void clearSplashScreen(final boolean resumeScanning) {
+ if (mDocumentViewfinderManager != null) {
+ mDocumentViewfinderManager.clearSplashScreen(0, SPLASH_FADE_ANIMATION_DURATION, new Runnable() {
+ @Override
+ public void run() {
+ if (mStatusOverlay != null) {
+ mStatusOverlay.setVisibility(View.VISIBLE);
+ }
+ if (resumeScanning) {
+ resumeScanning();
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Timer that is used for implementing minimal duration of the glare message.
+ */
+ private CountDownTimer mGlareCountDownTimer = new CountDownTimer(GLARE_MESSAGE_DURATION, GLARE_MESSAGE_DURATION) {
+ @Override
+ public void onTick(long l) {
+ // do nothing
+ }
+
+ @Override
+ public void onFinish() {
+ if (mActivityState == ActivityState.RESUMED && mGlareMsg != null) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ mGlareMsg.setVisibility(View.INVISIBLE);
+ }
+ });
+ }
+ }
+ };
+
+}
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/MainActivity.java b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/MainActivity.java
new file mode 100644
index 00000000..f64b785a
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/MainActivity.java
@@ -0,0 +1,208 @@
+package com.microblink.blinkid;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.microblink.Config;
+import com.microblink.activity.ScanActivity;
+import com.microblink.hardware.camera.CameraType;
+import com.microblink.libresult.ResultActivity;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.RecognitionResults;
+import com.microblink.recognizers.blinkid.CombinedRecognizerSettings;
+import com.microblink.recognizers.blinkid.austria.combined.AustrianIDCombinedRecognizerSettings;
+import com.microblink.recognizers.blinkid.croatia.combined.CroatianIDCombinedRecognizerSettings;
+import com.microblink.recognizers.blinkid.czechia.combined.CzechIDCombinedRecognizerSettings;
+import com.microblink.recognizers.blinkid.serbia.combined.SerbianIDCombinedRecognizerSettings;
+import com.microblink.recognizers.blinkid.singapore.combined.SingaporeIDCombinedRecognizerSettings;
+import com.microblink.recognizers.blinkid.slovakia.combined.SlovakIDCombinedRecognizerSettings;
+import com.microblink.recognizers.blinkid.slovenia.combined.SlovenianIDCombinedRecognizerSettings;
+import com.microblink.util.Log;
+import com.microblink.util.RecognizerCompatibility;
+import com.microblink.util.RecognizerCompatibilityStatus;
+import com.microblink.view.recognition.RecognitionType;
+
+import java.util.ArrayList;
+
+public class MainActivity extends AppCompatActivity {
+
+ public static final int MY_BLINKID_REQUEST_CODE = 0x101;
+
+ private ListElement[] mElements;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ // check if BlinkID is supported on the device
+ RecognizerCompatibilityStatus supportStatus = RecognizerCompatibility.getRecognizerCompatibilityStatus(this);
+ if (supportStatus != RecognizerCompatibilityStatus.RECOGNIZER_SUPPORTED) {
+ Toast.makeText(this, "BlinkID is not supported! Reason: " + supportStatus.name(), Toast.LENGTH_LONG).show();
+ }
+
+ // build list elements
+ buildElements();
+ ListView lv = (ListView) findViewById(R.id.documentList);
+ ArrayAdapter listAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, mElements);
+ lv.setAdapter(listAdapter);
+ lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ startActivityForResult(buildScanIntent(mElements[position].getCombinedRecognizerSettings()), MY_BLINKID_REQUEST_CODE);
+ }
+ });
+ }
+
+ /**
+ * Builds scan intent for {@link CustomVerificationFlowActivity} with given combined recognizer settings.
+ * @param combinedRecognizerSettings settings for the combined recognizer that will be used.
+ * @return scan intent for {@link CustomVerificationFlowActivity} with given combined recognizer settings
+ */
+ private Intent buildScanIntent(CombinedRecognizerSettings combinedRecognizerSettings) {
+ Intent intent = new Intent(this, CustomVerificationFlowActivity.class);
+ intent.putExtra(CustomVerificationFlowActivity.EXTRAS_LICENSE_KEY, Config.LICENSE_KEY);
+ intent.putExtra(CustomVerificationFlowActivity.EXTRAS_COMBINED_RECOGNIZER_SETTINGS, combinedRecognizerSettings);
+ intent.putExtra(CustomVerificationFlowActivity.EXTRAS_BEEP_RESOURCE, R.raw.beep);
+ intent.putExtra(CustomVerificationFlowActivity.EXTRAS_COMBINED_CAMERA_TYPE, (Parcelable) CameraType.CAMERA_BACKFACE);
+ return intent;
+ }
+
+ /**
+ * This method is used to build the array of ListElement objects. Each ListElement
+ * object will have its title that will be shown in ListView and prepared
+ * {@link CombinedRecognizerSettings}.
+ */
+ private void buildElements() {
+ ArrayList elements = new ArrayList();
+
+ elements.add(buildAustrianIDCombinedElement());
+ elements.add(buildCroatianIDCombinedElement());
+ elements.add(buildChechIDCombinedElement());
+ elements.add(buildSerbianIDCombinedElement());
+ elements.add(buildSingaporeIDCombinedElement());
+ elements.add(buildSlovakIDCombinedElement());
+ elements.add(buildSlovenianIDCombinedElement());
+
+ mElements = new ListElement[elements.size()];
+ elements.toArray(mElements);
+ }
+
+ private ListElement buildAustrianIDCombinedElement() {
+ AustrianIDCombinedRecognizerSettings ausIDCombined = new AustrianIDCombinedRecognizerSettings();
+
+ return new ListElement("Austrian ID combined", ausIDCombined);
+ }
+
+ private ListElement buildCroatianIDCombinedElement() {
+ CroatianIDCombinedRecognizerSettings croIDCombined = new CroatianIDCombinedRecognizerSettings();
+ return new ListElement("Croatian ID combined", croIDCombined);
+ }
+
+ private ListElement buildChechIDCombinedElement() {
+ CzechIDCombinedRecognizerSettings czechIDCombined = new CzechIDCombinedRecognizerSettings();
+
+ return new ListElement("Czech ID combined", czechIDCombined);
+ }
+
+ private ListElement buildSerbianIDCombinedElement() {
+ SerbianIDCombinedRecognizerSettings serbianIDCombined = new SerbianIDCombinedRecognizerSettings();
+
+ return new ListElement("Serbian ID combined", serbianIDCombined);
+ }
+
+ private ListElement buildSingaporeIDCombinedElement() {
+ SingaporeIDCombinedRecognizerSettings singaporeIDCombined = new SingaporeIDCombinedRecognizerSettings();
+
+ return new ListElement("Singapore ID combined", singaporeIDCombined);
+ }
+
+ private ListElement buildSlovakIDCombinedElement() {
+ SlovakIDCombinedRecognizerSettings svkIDCombined = new SlovakIDCombinedRecognizerSettings();
+
+ return new ListElement("Slovak ID combined", svkIDCombined);
+ }
+
+ private ListElement buildSlovenianIDCombinedElement() {
+ SlovenianIDCombinedRecognizerSettings svnIDCombined = new SlovenianIDCombinedRecognizerSettings();
+
+ return new ListElement("Slovenian ID combined", svnIDCombined);
+ }
+
+ /**
+ * This method is invoked after returning from scan activity. You can obtain
+ * scan results here
+ */
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ // onActivityResult is called whenever we are returned from activity started
+ // with startActivityForResult. We need to check request code to determine
+ // that we have really returned from BlinkID activity.
+ if (requestCode == MY_BLINKID_REQUEST_CODE) {
+
+ // make sure BlinkID activity returned result
+ if (resultCode == CustomVerificationFlowActivity.RESULT_OK && data != null) {
+
+ BaseRecognitionResult combinedResult = data.getParcelableExtra(CustomVerificationFlowActivity.EXTRAS_COMBINED_RECOGNITION_RESULT);
+ if (combinedResult != null) {
+ // prepare recognition results for ResultActivity, it accepts RecognitionResults extra
+ data.putExtra(ScanActivity.EXTRAS_RECOGNITION_RESULTS, new RecognitionResults(new BaseRecognitionResult[]{combinedResult}, RecognitionType.SUCCESSFUL));
+ } else {
+ Log.e(this, "Unable to retrieve recognition results!");
+ }
+ // set intent's component to ResultActivity and pass its contents
+ // to ResultActivity. ResultActivity will show how to extract
+ // data from result.
+ data.setComponent(new ComponentName(this, ResultActivity.class));
+ startActivity(data);
+ } else {
+ // if BlinkID activity did not return result, user has probably
+ // pressed Back button and cancelled scanning
+ Toast.makeText(this, "Scan cancelled!", Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+
+ /**
+ * Element of {@link ArrayAdapter} for {@link ListView} that holds information about title
+ * which should be displayed in the list and
+ * {@link com.microblink.recognizers.blinkid.CombinedRecognizerSettings} that should be used
+ * when scan activity is started on click.
+ */
+ private class ListElement {
+ private String mTitle;
+ private CombinedRecognizerSettings mCombinedRecognizerSettings;
+
+ public String getTitle() {
+ return mTitle;
+ }
+
+ public CombinedRecognizerSettings getCombinedRecognizerSettings() {
+ return mCombinedRecognizerSettings;
+ }
+
+ public ListElement(String title, CombinedRecognizerSettings combinedRecognizerSettings) {
+ mTitle = title;
+ mCombinedRecognizerSettings = combinedRecognizerSettings;
+ }
+
+ /**
+ * Used by array adapter to determine list element text
+ */
+ @Override
+ public String toString() {
+ return getTitle();
+ }
+ }
+}
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/managers/DocumentViewfinderManager.java b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/managers/DocumentViewfinderManager.java
new file mode 100644
index 00000000..d5ec55ea
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/managers/DocumentViewfinderManager.java
@@ -0,0 +1,97 @@
+package com.microblink.blinkid.managers;
+
+import android.animation.Animator;
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.ColorRes;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.microblink.view.viewfinder.ViewfinderShapeView;
+
+/**
+ * Document viewfinder manager that should be used for showing the splash screens over the viewfinder.
+ */
+public class DocumentViewfinderManager {
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private ViewfinderShapeView mCardViewfinder;
+ private TextView mTvMessage;
+ private ImageView mIvIcon;
+
+ /**
+ * Constructor which accepts viewfinder overlay views.
+ * @param cardViewfinder viewfinder view.
+ * @param tvMessage text view for displaying viewfinder text messages.
+ * @param ivIcon icon view that is used for displaying document icon.
+ */
+ public DocumentViewfinderManager(@NonNull ViewfinderShapeView cardViewfinder, @NonNull TextView tvMessage, @NonNull ImageView ivIcon) {
+ mCardViewfinder = cardViewfinder;
+ mTvMessage = tvMessage;
+ mIvIcon = ivIcon;
+ }
+
+ /**
+ * Shows splash message over the viewfinder with given background.
+ * @param message splash text message.
+ * @param icon document icon.
+ * @param backgroundColorResourceID resource ID of the splash message background color.
+ */
+ public void showSplashScreen(@NonNull final String message, @DrawableRes final int icon, @ColorRes final int backgroundColorResourceID) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mIvIcon.setImageResource(icon);
+ mTvMessage.setText(message);
+ mTvMessage.setVisibility(View.VISIBLE);
+ mIvIcon.setVisibility(View.VISIBLE);
+ mCardViewfinder.setInnerColor(ContextCompat.getColor(mCardViewfinder.getContext(), backgroundColorResourceID));
+ mCardViewfinder.setInnerAlpha(ViewfinderAnimationUtil.MAX_VIEWFINDER_ALPHA);
+ mTvMessage.setAlpha(1f);
+ mIvIcon.setAlpha(1f);
+ }
+ });
+ }
+
+ /**
+ * Clears splash screen with alpha animation after the given delay.
+ * @param delay delay in milliseconds before clear animation will be started.
+ * @param animationDuration duration of the clear alpha animation in milliseconds.
+ */
+ public void clearSplashScreen(long delay, long animationDuration) {
+ clearSplashScreen(delay, animationDuration);
+ }
+
+ /**
+ * Clears splash screen with alpha animation after the given delay and executes the given
+ * {@link Runnable} when animation finishes.
+ * @param delay delay in milliseconds before clear animation will be started.
+ * @param animationDuration duration of the clear alpha animation in milliseconds.
+ * @param animationEndRunnable runnable to be executed when animation finishes.
+ */
+ public void clearSplashScreen(long delay, final long animationDuration, final Runnable animationEndRunnable) {
+ mHandler.postDelayed(new Runnable() {
+ @Override
+ public void run() {
+ Animator anim = ViewfinderAnimationUtil.createSplashAnimation(animationDuration, new Runnable() {
+ @Override
+ public void run() {
+ mCardViewfinder.setInnerAlpha(0);
+ mIvIcon.setVisibility(View.INVISIBLE);
+ mTvMessage.setVisibility(View.INVISIBLE);
+ if (animationEndRunnable != null) {
+ animationEndRunnable.run();
+ }
+ }
+ }, mCardViewfinder, mTvMessage, mIvIcon);
+ anim.start();
+ }
+ }, delay);
+ }
+
+}
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/managers/ViewfinderAnimationUtil.java b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/managers/ViewfinderAnimationUtil.java
new file mode 100644
index 00000000..edea769f
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/java/com/microblink/blinkid/managers/ViewfinderAnimationUtil.java
@@ -0,0 +1,48 @@
+package com.microblink.blinkid.managers;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.support.annotation.NonNull;
+import android.view.View;
+
+import com.microblink.view.viewfinder.ViewfinderShapeView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by igrce on 01/12/2016.
+ */
+
+public class ViewfinderAnimationUtil {
+
+ public static final float MAX_VIEWFINDER_ALPHA = 0.67f;
+
+ public static AnimatorSet createSplashAnimation(long animationDuration, @NonNull final Runnable animationEndRunnable, ViewfinderShapeView viewfinderTarget, View... viewTargets) {
+ List animators = new ArrayList<>();
+
+ ObjectAnimator viewfinderAnimator = ObjectAnimator.ofFloat(viewfinderTarget, "innerAlpha", MAX_VIEWFINDER_ALPHA, 0);
+ viewfinderAnimator.setDuration(animationDuration);
+ animators.add(viewfinderAnimator);
+
+ for (View v : viewTargets) {
+ ObjectAnimator animator = ObjectAnimator.ofFloat(v, "alpha", 1, 0);
+ animator.setDuration(animationDuration);
+ animators.add(animator);
+ }
+
+ AnimatorSet animatorSet = new AnimatorSet();
+ animatorSet.playTogether(animators);
+ animatorSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (animationEndRunnable != null) {
+ animationEndRunnable.run();
+ }
+ }
+ });
+ return animatorSet;
+ }
+}
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/drawable/bg_status_msg.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/drawable/bg_status_msg.xml
new file mode 100644
index 00000000..858b948e
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/drawable/bg_status_msg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/activity_custom_verification_flow.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/activity_custom_verification_flow.xml
new file mode 100644
index 00000000..ad21aacc
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/activity_custom_verification_flow.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/activity_main.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..8c8975b1
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/activity_main.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/id_card_camera_overlay.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/id_card_camera_overlay.xml
new file mode 100644
index 00000000..8ec4b4b0
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/layout/id_card_camera_overlay.xml
@@ -0,0 +1,197 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-hdpi/ic_launcher.png b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100755
index 00000000..57f7fcac
Binary files /dev/null and b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-mdpi/ic_launcher.png b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100755
index 00000000..4bdca657
Binary files /dev/null and b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xhdpi/ic_launcher.png b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100755
index 00000000..970952b7
Binary files /dev/null and b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xxhdpi/ic_launcher.png b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100755
index 00000000..993300da
Binary files /dev/null and b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100755
index 00000000..928975ca
Binary files /dev/null and b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/raw/beep.mp3 b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/raw/beep.mp3
new file mode 100644
index 00000000..8c4a6dee
Binary files /dev/null and b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/raw/beep.mp3 differ
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/colors.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/colors.xml
new file mode 100644
index 00000000..9aaf7f3c
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ @android:color/white
+ @android:color/black
+ #FF4081
+
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/strings.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/strings.xml
new file mode 100644
index 00000000..8214b55a
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ Blink ID Combined Custom Demo
+ Custom Combined
+
diff --git a/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/styles.xml b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/styles.xml
new file mode 100644
index 00000000..880cf69d
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDCustomCombinedDemo/src/main/res/values/styles.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
diff --git a/BlinkIDDemo/BlinkIDDemo/src/main/AndroidManifest.xml b/BlinkIDDemo/BlinkIDDemo/src/main/AndroidManifest.xml
index 1d03dff2..2652f44e 100644
--- a/BlinkIDDemo/BlinkIDDemo/src/main/AndroidManifest.xml
+++ b/BlinkIDDemo/BlinkIDDemo/src/main/AndroidManifest.xml
@@ -36,6 +36,11 @@
android:name="com.microblink.libresult.ResultActivity"
android:screenOrientation="sensor" >
+
+
+
\ No newline at end of file
diff --git a/BlinkIDDemo/BlinkIDDemo/src/main/java/com/microblink/blinkid/MenuActivity.java b/BlinkIDDemo/BlinkIDDemo/src/main/java/com/microblink/blinkid/MenuActivity.java
index 00739410..f1b83a55 100644
--- a/BlinkIDDemo/BlinkIDDemo/src/main/java/com/microblink/blinkid/MenuActivity.java
+++ b/BlinkIDDemo/BlinkIDDemo/src/main/java/com/microblink/blinkid/MenuActivity.java
@@ -18,6 +18,7 @@
import com.microblink.activity.ScanCard;
import com.microblink.activity.SegmentScanActivity;
import com.microblink.activity.ShowOcrResultMode;
+import com.microblink.activity.VerificationFlowActivity;
import com.microblink.help.HelpActivity;
import com.microblink.libresult.ResultActivity;
import com.microblink.ocr.ScanConfiguration;
@@ -29,27 +30,37 @@
import com.microblink.recognizers.blinkbarcode.simnumber.SimNumberRecognizerSettings;
import com.microblink.recognizers.blinkbarcode.usdl.USDLRecognizerSettings;
import com.microblink.recognizers.blinkbarcode.zxing.ZXingRecognizerSettings;
+import com.microblink.recognizers.blinkid.CombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.austria.back.AustrianIDBackSideRecognizerSettings;
+import com.microblink.recognizers.blinkid.austria.combined.AustrianIDCombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.austria.front.AustrianIDFrontSideRecognizerSettings;
import com.microblink.recognizers.blinkid.croatia.back.CroatianIDBackSideRecognizerSettings;
+import com.microblink.recognizers.blinkid.croatia.combined.CroatianIDCombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.croatia.front.CroatianIDFrontSideRecognizerSettings;
import com.microblink.recognizers.blinkid.czechia.back.CzechIDBackSideRecognizerSettings;
+import com.microblink.recognizers.blinkid.czechia.combined.CzechIDCombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.czechia.front.CzechIDFrontSideRecognizerSettings;
import com.microblink.recognizers.blinkid.eudl.EUDLCountry;
import com.microblink.recognizers.blinkid.eudl.EUDLRecognizerSettings;
+import com.microblink.recognizers.blinkid.germany.back.GermanIDBackSideRecognizerSettings;
import com.microblink.recognizers.blinkid.germany.front.GermanIDFrontSideRecognizerSettings;
-import com.microblink.recognizers.blinkid.germany.mrz.GermanIDMRZSideRecognizerSettings;
+import com.microblink.recognizers.blinkid.germany.old.front.GermanOldIDRecognizerSettings;
+import com.microblink.recognizers.blinkid.germany.passport.GermanPassportRecognizerSettings;
import com.microblink.recognizers.blinkid.malaysia.IKadRecognizerSettings;
import com.microblink.recognizers.blinkid.malaysia.MyKadRecognizerSettings;
import com.microblink.recognizers.blinkid.mrtd.MRTDRecognizerSettings;
import com.microblink.recognizers.blinkid.romania.front.RomanianIDFrontSideRecognizerSettings;
import com.microblink.recognizers.blinkid.serbia.back.SerbianIDBackSideRecognizerSettings;
+import com.microblink.recognizers.blinkid.serbia.combined.SerbianIDCombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.serbia.front.SerbianIDFrontSideRecognizerSettings;
import com.microblink.recognizers.blinkid.singapore.back.SingaporeIDBackRecognizerSettings;
+import com.microblink.recognizers.blinkid.singapore.combined.SingaporeIDCombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.singapore.front.SingaporeIDFrontRecognizerSettings;
import com.microblink.recognizers.blinkid.slovakia.back.SlovakIDBackSideRecognizerSettings;
+import com.microblink.recognizers.blinkid.slovakia.combined.SlovakIDCombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.slovakia.front.SlovakIDFrontSideRecognizerSettings;
import com.microblink.recognizers.blinkid.slovenia.back.SlovenianIDBackSideRecognizerSettings;
+import com.microblink.recognizers.blinkid.slovenia.combined.SlovenianIDCombinedRecognizerSettings;
import com.microblink.recognizers.blinkid.slovenia.front.SlovenianIDFrontSideRecognizerSettings;
import com.microblink.recognizers.blinkocr.parser.licenseplates.LicensePlatesParserSettings;
import com.microblink.recognizers.blinkocr.parser.vin.VinParserSettings;
@@ -60,6 +71,7 @@
import com.microblink.util.RecognizerCompatibilityStatus;
import com.microblink.util.templating.CroatianIDBackSide;
import com.microblink.util.templating.CroatianIDFrontSide;
+import com.microblink.view.recognition.RecognitionType;
import java.util.ArrayList;
@@ -116,32 +128,16 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_BLINKID_REQUEST_CODE) {
// make sure BlinkID activity returned result
- if (resultCode == ScanActivity.RESULT_OK && data != null) {
+ if (resultCode == Activity.RESULT_OK && data != null) {
- // depending on settings, we may have multiple scan results.
- // we first need to obtain list of recognition results
Bundle extras = data.getExtras();
- RecognitionResults results = data.getParcelableExtra(ScanActivity.EXTRAS_RECOGNITION_RESULTS);
- BaseRecognitionResult[] resArray = null;
- if (results != null) {
- // get array of recognition results
- resArray = results.getRecognitionResults();
- }
- if (resArray != null) {
- Log.i(this, "Data count: " + resArray.length);
- int i = 1;
-
- for (BaseRecognitionResult res : resArray) {
- Log.i(this, "Data #" + Integer.valueOf(i++).toString());
-
- // Each element in resultArray inherits BaseRecognitionResult class and
- // represents the scan result of one of activated recognizers that have
- // been set up.
-
- res.log();
+ if (extras != null && extras.getParcelable(ScanActivity.EXTRAS_RECOGNITION_RESULTS) == null) {
+ // VerificationFlowActivity does not return results as RecognitionResults object, prepare RecognitionResults
+ // from combined recognizer result
+ BaseRecognitionResult combinedResult = extras.getParcelable(VerificationFlowActivity.EXTRAS_COMBINED_RECOGNITION_RESULT);
+ if (combinedResult != null) {
+ data.putExtra(ScanActivity.EXTRAS_RECOGNITION_RESULTS, new RecognitionResults(new BaseRecognitionResult[]{combinedResult}, RecognitionType.SUCCESSFUL));
}
- } else {
- Log.e(this, "Unable to retrieve recognition results!");
}
// set intent's component to ResultActivity and pass its contents
@@ -237,6 +233,19 @@ private Intent buildIntent(RecognizerSettings[] settArray, Class> target, Inte
return intent;
}
+ /**
+ * This method will build scan intent for {@link com.microblink.activity.VerificationFlowActivity}
+ * with given combined recognizer settings.
+ * @param combinedRecognizerSettings settings for the combined recognizer that will be used.
+ */
+ private Intent buildCombinedIntent(CombinedRecognizerSettings combinedRecognizerSettings) {
+ Intent intent = new Intent(this, VerificationFlowActivity.class);
+ intent.putExtra(VerificationFlowActivity.EXTRAS_LICENSE_KEY, Config.LICENSE_KEY);
+ intent.putExtra(VerificationFlowActivity.EXTRAS_COMBINED_RECOGNIZER_SETTINGS, combinedRecognizerSettings);
+ intent.putExtra(VerificationFlowActivity.EXTRAS_BEEP_RESOURCE, R.raw.beep);
+ return intent;
+ }
+
/**
* Builds intent for segment scan.
* @param configArray Array of scan configurations. Each scan configuration
@@ -273,16 +282,24 @@ private void buildElements() {
// ID document list entry
elements.add(buildMrtdElement());
elements.add(buildAustrianIDElement());
+ elements.add(buildAustrianIDCombinedElement());
elements.add(buildCroatianIDElement());
+ elements.add(buildCroatianIDCombinedElement());
elements.add(buildCzechIDElement());
- elements.add( buildGermanIDElement() );
+ elements.add(buildChechIDCombinedElement());
+ elements.add(buildGermanIDElement());
+ elements.add(buildGermanPassportElement());
elements.add(buildMyKadElement());
- elements.add( buildIKadElement() );
- elements.add( bildRomanianElement() );
+ elements.add(buildIKadElement());
+ elements.add(bildRomanianElement());
elements.add(buildSingaporeIDElement());
+ elements.add(buildSingaporeIDCombinedElement());
elements.add(buildSerbianIDElement());
+ elements.add(buildSerbianIDCombinedElement());
elements.add(buildSlovakIDElement());
- elements.add( buildSlovenianIDElement() );
+ elements.add(buildSlovakIDCombinedElement());
+ elements.add(buildSlovenianIDElement());
+ elements.add(buildSlovenianIDCombinedElement());
// DL list entries
elements.add(buildAustrianDLElement());
@@ -297,7 +314,7 @@ private void buildElements() {
// elements.add( buildAztecElement() );
elements.add(buildPDF417Element());
elements.add(buildBardecoderElement());
- elements.add( buildSimNumberElement() );
+ elements.add(buildSimNumberElement());
elements.add(buildZXingElement());
// Blink OCR entries
@@ -343,9 +360,16 @@ private ListElement buildCzechIDElement() {
private ListElement buildGermanIDElement() {
GermanIDFrontSideRecognizerSettings deFront = new GermanIDFrontSideRecognizerSettings();
- GermanIDMRZSideRecognizerSettings deMRZ = new GermanIDMRZSideRecognizerSettings();
+ GermanIDBackSideRecognizerSettings deBack = new GermanIDBackSideRecognizerSettings();
+ GermanOldIDRecognizerSettings deOld = new GermanOldIDRecognizerSettings();
- return new ListElement( "German ID", buildIntent( new RecognizerSettings[] { deFront, deMRZ }, ScanCard.class, null ));
+ return new ListElement( "German ID", buildIntent( new RecognizerSettings[] { deFront, deBack, deOld }, ScanCard.class, null ));
+ }
+
+ private ListElement buildGermanPassportElement() {
+ GermanPassportRecognizerSettings dePassport = new GermanPassportRecognizerSettings();
+
+ return new ListElement("German Passport", buildIntent(new RecognizerSettings[]{dePassport}, ScanCard.class, null));
}
private ListElement buildSingaporeIDElement() {
@@ -434,6 +458,48 @@ private ListElement bildRomanianElement () {
return new ListElement("Romanian ID", buildIntent( new RecognizerSettings[] { romanianSettings }, ScanCard.class, null ));
}
+ private ListElement buildCroatianIDCombinedElement() {
+ CroatianIDCombinedRecognizerSettings croIDCombined = new CroatianIDCombinedRecognizerSettings();
+
+ return new ListElement("Croatian ID combined", buildCombinedIntent(croIDCombined));
+ }
+
+ private ListElement buildSerbianIDCombinedElement() {
+ SerbianIDCombinedRecognizerSettings serbianIDCombined = new SerbianIDCombinedRecognizerSettings();
+
+ return new ListElement("Serbian ID combined", buildCombinedIntent(serbianIDCombined));
+ }
+
+ private ListElement buildSlovenianIDCombinedElement() {
+ SlovenianIDCombinedRecognizerSettings svnIDCombined = new SlovenianIDCombinedRecognizerSettings();
+
+ return new ListElement("Slovenian ID combined", buildCombinedIntent(svnIDCombined));
+ }
+
+ private ListElement buildSlovakIDCombinedElement() {
+ SlovakIDCombinedRecognizerSettings svkIDCombined = new SlovakIDCombinedRecognizerSettings();
+
+ return new ListElement("Slovak ID combined", buildCombinedIntent(svkIDCombined));
+ }
+
+ private ListElement buildSingaporeIDCombinedElement() {
+ SingaporeIDCombinedRecognizerSettings singaporeIDCombined = new SingaporeIDCombinedRecognizerSettings();
+
+ return new ListElement("Singapore ID combined", buildCombinedIntent(singaporeIDCombined));
+ }
+
+ private ListElement buildChechIDCombinedElement() {
+ CzechIDCombinedRecognizerSettings czechIDCombined = new CzechIDCombinedRecognizerSettings();
+
+ return new ListElement("Czech ID combined", buildCombinedIntent(czechIDCombined));
+ }
+
+ private ListElement buildAustrianIDCombinedElement() {
+ AustrianIDCombinedRecognizerSettings ausIDCombined = new AustrianIDCombinedRecognizerSettings();
+
+ return new ListElement("Austrian ID combined", buildCombinedIntent(ausIDCombined));
+ }
+
private ListElement buildPDF417Element() {
// prepare settings for PDF417 barcode recognizer
Pdf417RecognizerSettings pdf417 = new Pdf417RecognizerSettings();
diff --git a/BlinkIDDemo/BlinkIDDemo/src/main/res/values/styles.xml b/BlinkIDDemo/BlinkIDDemo/src/main/res/values/styles.xml
new file mode 100644
index 00000000..90317b65
--- /dev/null
+++ b/BlinkIDDemo/BlinkIDDemo/src/main/res/values/styles.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/Config.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/Config.java
index ecacb949..bbe5f8c8 100644
--- a/BlinkIDDemo/LibResult/src/main/java/com/microblink/Config.java
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/Config.java
@@ -6,5 +6,5 @@
public class Config {
// obtain your licence key at http://microblink.com/login or
// contact us at http://help.microblink.com
- public static final String LICENSE_KEY = "MSHLU4AX-CBMEPGOI-RN7IJWQZ-UEOLNT4Y-GD4K5X42-OJL66HTK-CYGA2P3E-O4CIHSF2";
+ public static final String LICENSE_KEY = "5BEQCHO7-SN6ILFQX-DG72BRZK-OMGZ6SGP-TAYPRLW7-TJZFP3Y6-NILAZLNC-TY4XVA6L";
}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/ResultFragment.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/ResultFragment.java
index 6a9c0e60..a12a9efa 100644
--- a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/ResultFragment.java
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/ResultFragment.java
@@ -17,6 +17,7 @@
import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
import com.microblink.libresult.extract.RecognitionResultEntry;
import com.microblink.libresult.extract.austria.AustrianIDBackSideRecognitionResultExtractor;
+import com.microblink.libresult.extract.austria.AustrianIDCombinedRecognitionResultExtractor;
import com.microblink.libresult.extract.austria.AustrianIDFrontSideRecognitionResultExtractor;
import com.microblink.libresult.extract.barcode.AztecRecognitionResultExtractor;
import com.microblink.libresult.extract.barcode.BardecoderRecognitionResultExtractor;
@@ -24,24 +25,32 @@
import com.microblink.libresult.extract.barcode.ZXingRecognitionResultExtractor;
import com.microblink.libresult.extract.blinkInput.BlinkOcrRecognitionResultExtractor;
import com.microblink.libresult.extract.croatia.CroatianIDBackSideRecognitionResultExtractor;
+import com.microblink.libresult.extract.croatia.CroatianIDCombinedRecognitionResultExtractor;
import com.microblink.libresult.extract.croatia.CroatianIDFrontSideRecognitionResultExtractor;
import com.microblink.libresult.extract.czechia.CzechIDBackSideRecognitionResultExtractor;
+import com.microblink.libresult.extract.czechia.CzechIDCombinedRecognitionResultExtractor;
import com.microblink.libresult.extract.czechia.CzechIDFrontSideRecognitionResultExtractor;
import com.microblink.libresult.extract.eudl.EUDLRecognitionResultExtractor;
+import com.microblink.libresult.extract.germany.GermanIDBackSideRecognitionResultExtractor;
import com.microblink.libresult.extract.germany.GermanIDFrontSideRecognitionResultExtractor;
-import com.microblink.libresult.extract.germany.GermanIDMRZSideRecognitionResultExtractor;
+import com.microblink.libresult.extract.germany.GermanOldIDRecognitionResultExtractor;
+import com.microblink.libresult.extract.germany.GermanPassportRecognitionResultExtractor;
import com.microblink.libresult.extract.malaysia.IKadRecognitionResultExtractor;
import com.microblink.libresult.extract.malaysia.MyKadRecognitionResultExtractor;
import com.microblink.libresult.extract.mrtd.MRTDRecognitionResultExtractor;
import com.microblink.libresult.extract.romania.RomanianIDFrontSideRecognitionResultExtractor;
import com.microblink.libresult.extract.serbia.SerbianIDBackRecognitionResultExtractor;
+import com.microblink.libresult.extract.serbia.SerbianIDCombinedRecognitionResultExtractor;
import com.microblink.libresult.extract.serbia.SerbianIDFrontRecognitionResultExtractor;
import com.microblink.libresult.extract.simnumber.SimNumberRecognitionResultExtractor;
import com.microblink.libresult.extract.singapore.SingaporeIDBackRecognitionResultExtractor;
+import com.microblink.libresult.extract.singapore.SingaporeIDCombinedRecognitionResultExtractor;
import com.microblink.libresult.extract.singapore.SingaporeIDFrontRecognitionResultExtractor;
import com.microblink.libresult.extract.slovakia.SlovakIDBackSideRecognitionResultExtractor;
+import com.microblink.libresult.extract.slovakia.SlovakIDCombinedRecognitionResultExtractor;
import com.microblink.libresult.extract.slovakia.SlovakIDFrontSideRecognitionResultExtractor;
import com.microblink.libresult.extract.slovenia.SlovenianIDBackRecognitionResultExtractor;
+import com.microblink.libresult.extract.slovenia.SlovenianIDCombinedRecognitionResultExtractor;
import com.microblink.libresult.extract.slovenia.SlovenianIDFrontRecognitionResultExtractor;
import com.microblink.locale.LanguageUtils;
import com.microblink.recognizers.BaseRecognitionResult;
@@ -51,25 +60,34 @@
import com.microblink.recognizers.blinkbarcode.simnumber.SimNumberScanResult;
import com.microblink.recognizers.blinkbarcode.zxing.ZXingScanResult;
import com.microblink.recognizers.blinkid.austria.back.AustrianIDBackSideRecognitionResult;
+import com.microblink.recognizers.blinkid.austria.combined.AustrianIDCombinedRecognitionResult;
import com.microblink.recognizers.blinkid.austria.front.AustrianIDFrontSideRecognitionResult;
import com.microblink.recognizers.blinkid.croatia.back.CroatianIDBackSideRecognitionResult;
+import com.microblink.recognizers.blinkid.croatia.combined.CroatianIDCombinedRecognitionResult;
import com.microblink.recognizers.blinkid.croatia.front.CroatianIDFrontSideRecognitionResult;
import com.microblink.recognizers.blinkid.czechia.back.CzechIDBackSideRecognitionResult;
+import com.microblink.recognizers.blinkid.czechia.combined.CzechIDCombinedRecognitionResult;
import com.microblink.recognizers.blinkid.czechia.front.CzechIDFrontSideRecognitionResult;
import com.microblink.recognizers.blinkid.eudl.EUDLRecognitionResult;
+import com.microblink.recognizers.blinkid.germany.back.GermanIDBackSideRecognitionResult;
import com.microblink.recognizers.blinkid.germany.front.GermanIDFrontSideRecognitionResult;
-import com.microblink.recognizers.blinkid.germany.mrz.GermanIDMRZSideRecognitionResult;
+import com.microblink.recognizers.blinkid.germany.old.front.GermanOldIDRecognitionResult;
+import com.microblink.recognizers.blinkid.germany.passport.GermanPassportRecognitionResult;
import com.microblink.recognizers.blinkid.malaysia.IKadRecognitionResult;
import com.microblink.recognizers.blinkid.malaysia.MyKadRecognitionResult;
import com.microblink.recognizers.blinkid.mrtd.MRTDRecognitionResult;
import com.microblink.recognizers.blinkid.romania.front.RomanianIDFrontSideRecognitionResult;
import com.microblink.recognizers.blinkid.serbia.back.SerbianIDBackSideRecognitionResult;
+import com.microblink.recognizers.blinkid.serbia.combined.SerbianIDCombinedRecognitionResult;
import com.microblink.recognizers.blinkid.serbia.front.SerbianIDFrontSideRecognitionResult;
import com.microblink.recognizers.blinkid.singapore.back.SingaporeIDBackRecognitionResult;
+import com.microblink.recognizers.blinkid.singapore.combined.SingaporeIDCombinedRecognitionResult;
import com.microblink.recognizers.blinkid.singapore.front.SingaporeIDFrontRecognitionResult;
import com.microblink.recognizers.blinkid.slovakia.back.SlovakIDBackSideRecognitionResult;
+import com.microblink.recognizers.blinkid.slovakia.combined.SlovakIDCombinedRecognitionResult;
import com.microblink.recognizers.blinkid.slovakia.front.SlovakIDFrontSideRecognitionResult;
import com.microblink.recognizers.blinkid.slovenia.back.SlovenianIDBackSideRecognitionResult;
+import com.microblink.recognizers.blinkid.slovenia.combined.SlovenianIDCombinedRecognitionResult;
import com.microblink.recognizers.blinkid.slovenia.front.SlovenianIDFrontSideRecognitionResult;
import com.microblink.recognizers.blinkocr.BlinkOCRRecognitionResult;
@@ -121,37 +139,55 @@ public void onCreate(Bundle savedInstanceState) {
if (mData instanceof SingaporeIDFrontRecognitionResult) {
mResultExtractor = new SingaporeIDFrontRecognitionResultExtractor(getActivity());
} else if ( mData instanceof SingaporeIDBackRecognitionResult) {
- mResultExtractor = new SingaporeIDBackRecognitionResultExtractor( getActivity() );
+ mResultExtractor = new SingaporeIDBackRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof SingaporeIDCombinedRecognitionResult) {
+ mResultExtractor = new SingaporeIDCombinedRecognitionResultExtractor(getActivity());
} else if (mData instanceof AustrianIDBackSideRecognitionResult) {
mResultExtractor = new AustrianIDBackSideRecognitionResultExtractor(getActivity());
} else if (mData instanceof AustrianIDFrontSideRecognitionResult) {
mResultExtractor = new AustrianIDFrontSideRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof AustrianIDCombinedRecognitionResult) {
+ mResultExtractor = new AustrianIDCombinedRecognitionResultExtractor(getActivity());
} else if (mData instanceof CroatianIDBackSideRecognitionResult) {
mResultExtractor = new CroatianIDBackSideRecognitionResultExtractor(getActivity());
} else if (mData instanceof CroatianIDFrontSideRecognitionResult) {
mResultExtractor = new CroatianIDFrontSideRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof CroatianIDCombinedRecognitionResult) {
+ mResultExtractor = new CroatianIDCombinedRecognitionResultExtractor(getActivity());
} else if (mData instanceof CzechIDBackSideRecognitionResult) {
mResultExtractor = new CzechIDBackSideRecognitionResultExtractor(getActivity());
} else if (mData instanceof CzechIDFrontSideRecognitionResult) {
mResultExtractor = new CzechIDFrontSideRecognitionResultExtractor(getActivity());
- } else if (mData instanceof GermanIDMRZSideRecognitionResult) {
- mResultExtractor = new GermanIDMRZSideRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof CzechIDCombinedRecognitionResult) {
+ mResultExtractor = new CzechIDCombinedRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof GermanIDBackSideRecognitionResult) {
+ mResultExtractor = new GermanIDBackSideRecognitionResultExtractor(getActivity());
} else if (mData instanceof GermanIDFrontSideRecognitionResult) {
mResultExtractor = new GermanIDFrontSideRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof GermanOldIDRecognitionResult) {
+ mResultExtractor = new GermanOldIDRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof GermanPassportRecognitionResult) {
+ mResultExtractor = new GermanPassportRecognitionResultExtractor(getActivity());
} else if (mData instanceof RomanianIDFrontSideRecognitionResult) {
mResultExtractor = new RomanianIDFrontSideRecognitionResultExtractor(getActivity());
} else if (mData instanceof SlovakIDBackSideRecognitionResult) {
mResultExtractor = new SlovakIDBackSideRecognitionResultExtractor(getActivity());
} else if (mData instanceof SlovakIDFrontSideRecognitionResult) {
mResultExtractor = new SlovakIDFrontSideRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof SlovakIDCombinedRecognitionResult) {
+ mResultExtractor = new SlovakIDCombinedRecognitionResultExtractor(getActivity());
} else if (mData instanceof SerbianIDBackSideRecognitionResult) {
mResultExtractor = new SerbianIDBackRecognitionResultExtractor(getActivity());
} else if (mData instanceof SerbianIDFrontSideRecognitionResult) {
mResultExtractor = new SerbianIDFrontRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof SerbianIDCombinedRecognitionResult) {
+ mResultExtractor = new SerbianIDCombinedRecognitionResultExtractor(getActivity());
} else if (mData instanceof SlovenianIDBackSideRecognitionResult) {
mResultExtractor = new SlovenianIDBackRecognitionResultExtractor(getActivity());
} else if (mData instanceof SlovenianIDFrontSideRecognitionResult) {
mResultExtractor = new SlovenianIDFrontRecognitionResultExtractor(getActivity());
+ } else if (mData instanceof SlovenianIDCombinedRecognitionResult) {
+ mResultExtractor = new SlovenianIDCombinedRecognitionResultExtractor(getActivity());
} else if (mData instanceof IKadRecognitionResult) {
mResultExtractor = new IKadRecognitionResultExtractor(getActivity());
} else if(mData instanceof MRTDRecognitionResult) {
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/austria/AustrianIDCombinedRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/austria/AustrianIDCombinedRecognitionResultExtractor.java
new file mode 100644
index 00000000..083c5829
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/austria/AustrianIDCombinedRecognitionResultExtractor.java
@@ -0,0 +1,114 @@
+package com.microblink.libresult.extract.austria;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.austria.combined.AustrianIDCombinedRecognitionResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by igrce on 09/01/17.
+ */
+public class AustrianIDCombinedRecognitionResultExtractor implements IBaseRecognitionResultExtractor {
+
+ private List mExtractedData;
+
+ private RecognitionResultEntry.Builder mBuilder;
+
+ public AustrianIDCombinedRecognitionResultExtractor(Context context) {
+ mBuilder = new RecognitionResultEntry.Builder(context);
+ mExtractedData = new ArrayList<>();
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof AustrianIDCombinedRecognitionResult) {
+ // result is obtained from scanning both sides of Austrian ID
+ AustrianIDCombinedRecognitionResult combinedResult = (AustrianIDCombinedRecognitionResult) result;
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPLastName,
+ combinedResult.getLastName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPFirstName,
+ combinedResult.getFirstName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentNumber,
+ combinedResult.getIdentityCardNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSex,
+ combinedResult.getSex()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfBirth,
+ combinedResult.getDateOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPHeight,
+ combinedResult.getHeight(),
+ "m"
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPlaceOfBirth,
+ combinedResult.getPlaceOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssuingAuthority,
+ combinedResult.getIssuingAuthority()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ combinedResult.getDateOfIssuance()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfExpiry,
+ combinedResult.getDocumentDateOfExpiry()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPrincipalResidenceAtIssuance,
+ combinedResult.getPrincipalResidenceAtIssuance()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPEyeColour,
+ combinedResult.getEyeColour()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPMRZVerified,
+ combinedResult.isMRZVerified()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBothSidesMatch,
+ combinedResult.isDocumentDataMatch()
+ ));
+
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/croatia/CroatianIDCombinedRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/croatia/CroatianIDCombinedRecognitionResultExtractor.java
new file mode 100644
index 00000000..61f6a380
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/croatia/CroatianIDCombinedRecognitionResultExtractor.java
@@ -0,0 +1,119 @@
+package com.microblink.libresult.extract.croatia;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.croatia.combined.CroatianIDCombinedRecognitionResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by Boris on 29/11/16.
+ */
+
+public class CroatianIDCombinedRecognitionResultExtractor implements IBaseRecognitionResultExtractor {
+
+ private List mExtractedData;
+
+ private RecognitionResultEntry.Builder mBuilder;
+
+ public CroatianIDCombinedRecognitionResultExtractor(Context context) {
+ mBuilder = new RecognitionResultEntry.Builder(context);
+ mExtractedData = new ArrayList<>();
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof CroatianIDCombinedRecognitionResult) {
+ // result is obtained from scanning both sides of Croatian ID
+ CroatianIDCombinedRecognitionResult combinedResult = (CroatianIDCombinedRecognitionResult) result;
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPLastName,
+ combinedResult.getLastName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPFirstName,
+ combinedResult.getFirstName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentNumber,
+ combinedResult.getIdentityCardNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSex,
+ combinedResult.getSex()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPCitizenship,
+ combinedResult.getCitizenship()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfBirth,
+ combinedResult.getDateOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfExpiry,
+ combinedResult.getDocumentDateOfExpiry()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddress,
+ combinedResult.getAddress()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentForNonResidents,
+ combinedResult.documentForNonResident()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssuingAuthority,
+ combinedResult.getIssuingAuthority()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ combinedResult.getDocumentDateOfIssue()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPersonalNumber,
+ combinedResult.getPersonalIdentificationNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPMRZVerified,
+ combinedResult.isMRZVerified()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBothSidesMatch,
+ combinedResult.isDocumentDataMatch()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBilingual,
+ combinedResult.isDocumentBilingual()
+ ));
+
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/czechia/CzechIDCombinedRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/czechia/CzechIDCombinedRecognitionResultExtractor.java
new file mode 100644
index 00000000..b368c127
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/czechia/CzechIDCombinedRecognitionResultExtractor.java
@@ -0,0 +1,108 @@
+package com.microblink.libresult.extract.czechia;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.czechia.combined.CzechIDCombinedRecognitionResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Extractor of CzechIDCombinedRecognitionResult
+ */
+public class CzechIDCombinedRecognitionResultExtractor implements IBaseRecognitionResultExtractor {
+
+ private List mExtractedData;
+
+ private RecognitionResultEntry.Builder mBuilder;
+
+ public CzechIDCombinedRecognitionResultExtractor(Context context) {
+ mBuilder = new RecognitionResultEntry.Builder(context);
+ mExtractedData = new ArrayList<>();
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof CzechIDCombinedRecognitionResult) {
+ // result is obtained from scanning both sides of Czech ID
+ CzechIDCombinedRecognitionResult combinedResult = (CzechIDCombinedRecognitionResult) result;
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPLastName,
+ combinedResult.getLastName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPFirstName,
+ combinedResult.getFirstName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentNumber,
+ combinedResult.getIdentityCardNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSex,
+ combinedResult.getSex()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPNationality,
+ combinedResult.getNationality()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfBirth,
+ combinedResult.getDateOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfExpiry,
+ combinedResult.getDocumentDateOfExpiry()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddress,
+ combinedResult.getAddress()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssuingAuthority,
+ combinedResult.getIssuingAuthority()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ combinedResult.getDocumentDateOfIssue()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPersonalNumber,
+ combinedResult.getPersonalIdentificationNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPMRZVerified,
+ combinedResult.isMRZVerified()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBothSidesMatch,
+ combinedResult.isDocumentDataMatch()
+ ));
+
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanIDBackSideRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanIDBackSideRecognitionResultExtractor.java
new file mode 100644
index 00000000..b8c451fc
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanIDBackSideRecognitionResultExtractor.java
@@ -0,0 +1,110 @@
+package com.microblink.libresult.extract.germany;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.libresult.extract.mrtd.MRTDRecognitionResultExtractor;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.germany.back.GermanIDBackSideRecognitionResult;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Created by daniel on 4/12/17.
+ */
+public class GermanIDBackSideRecognitionResultExtractor extends MRTDRecognitionResultExtractor {
+
+ public GermanIDBackSideRecognitionResultExtractor(Context context) {
+ super(context);
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof GermanIDBackSideRecognitionResult) {
+ GermanIDBackSideRecognitionResult deIDBackResult = (GermanIDBackSideRecognitionResult) result;
+
+ String address = deIDBackResult.getAddress();
+ if (address != null && !address.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddress,
+ address
+ ));
+ }
+
+ String zipCode = deIDBackResult.getAddressZipCode();
+ if (zipCode != null && !zipCode.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddressZipCode,
+ zipCode
+ ));
+ }
+
+ String city = deIDBackResult.getAddressCity();
+ if (city != null && !city.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddressCity,
+ city
+ ));
+ }
+
+ String street = deIDBackResult.getAddressStreet();
+ if (street != null && !street.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddressStreet,
+ street
+ ));
+ }
+
+ String houseNumber = deIDBackResult.getAddressHouseNumber();
+ if (houseNumber != null && !houseNumber.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddressHouseNumber,
+ houseNumber
+ ));
+ }
+
+ String authority = deIDBackResult.getAuthority();
+ if (authority != null && !authority.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAuthority,
+ authority
+ ));
+ }
+
+ Date dateOfIssue = deIDBackResult.getDateOfIssue();
+ if (dateOfIssue != null) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ dateOfIssue
+ ));
+ }
+
+ String eyeColor = deIDBackResult.getEyeColour();
+ if (eyeColor != null && !eyeColor.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPEyeColour,
+ eyeColor
+ ));
+ }
+
+ int height = deIDBackResult.getHeight();
+ if (height != 0) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPHeight,
+ Integer.toString(height) + " cm"
+ ));
+ }
+
+
+ super.extractMRZData(deIDBackResult);
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanOldIDRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanOldIDRecognitionResultExtractor.java
new file mode 100644
index 00000000..72e00834
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanOldIDRecognitionResultExtractor.java
@@ -0,0 +1,45 @@
+package com.microblink.libresult.extract.germany;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.libresult.extract.mrtd.MRTDRecognitionResultExtractor;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.germany.old.front.GermanOldIDRecognitionResult;
+
+import java.util.List;
+
+/**
+ * Created by daniel on 4/12/17.
+ */
+
+public class GermanOldIDRecognitionResultExtractor extends MRTDRecognitionResultExtractor {
+
+ public GermanOldIDRecognitionResultExtractor(Context context) {
+ super(context);
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof GermanOldIDRecognitionResult) {
+ GermanOldIDRecognitionResult deOldIdResult = (GermanOldIDRecognitionResult) result;
+
+ String placeOfBirth = deOldIdResult.getPlaceOfBirth();
+ if (placeOfBirth != null) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPlaceOfBirth,
+ placeOfBirth
+ ));
+ }
+
+ super.extractMRZData(deOldIdResult);
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanIDMRZSideRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanPassportRecognitionResultExtractor.java
similarity index 54%
rename from BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanIDMRZSideRecognitionResultExtractor.java
rename to BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanPassportRecognitionResultExtractor.java
index de7a822b..3aeb64a1 100644
--- a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanIDMRZSideRecognitionResultExtractor.java
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/germany/GermanPassportRecognitionResultExtractor.java
@@ -3,20 +3,21 @@
import android.content.Context;
import com.microblink.libresult.R;
-import com.microblink.recognizers.BaseRecognitionResult;
-import com.microblink.recognizers.blinkid.germany.mrz.GermanIDMRZSideRecognitionResult;
import com.microblink.libresult.extract.RecognitionResultEntry;
import com.microblink.libresult.extract.mrtd.MRTDRecognitionResultExtractor;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.germany.passport.GermanPassportRecognitionResult;
import java.util.Date;
import java.util.List;
/**
- * Created by igrce on 26/08/16.
+ * Created by mateja on 3/22/17.
*/
-public class GermanIDMRZSideRecognitionResultExtractor extends MRTDRecognitionResultExtractor {
- public GermanIDMRZSideRecognitionResultExtractor(Context context) {
+public class GermanPassportRecognitionResultExtractor extends MRTDRecognitionResultExtractor {
+
+ public GermanPassportRecognitionResultExtractor(Context context) {
super(context);
}
@@ -26,18 +27,26 @@ public List extractData(BaseRecognitionResult result) {
return mExtractedData;
}
- if (result instanceof GermanIDMRZSideRecognitionResult) {
- GermanIDMRZSideRecognitionResult deIDMrzResult = (GermanIDMRZSideRecognitionResult) result;
+ if (result instanceof GermanPassportRecognitionResult) {
+ GermanPassportRecognitionResult dePassResult = (GermanPassportRecognitionResult) result;
- String address = deIDMrzResult.getAddress();
- if (address != null && !address.isEmpty()) {
+ String name = dePassResult.getName();
+ if (name != null && !name.isEmpty()) {
mExtractedData.add(mBuilder.build(
- R.string.PPAddress,
- address
+ R.string.PPFirstName,
+ name
));
}
- String authority = deIDMrzResult.getAuthority();
+ String surname = dePassResult.getSurname();
+ if (surname != null && !surname.isEmpty()) {
+ mExtractedData.add(mBuilder.build(
+ R.string.PPLastName,
+ surname
+ ));
+ }
+
+ String authority = dePassResult.getAuthority();
if (authority != null && !authority.isEmpty()) {
mExtractedData.add(mBuilder.build(
R.string.PPAuthority,
@@ -45,7 +54,7 @@ public List extractData(BaseRecognitionResult result) {
));
}
- Date dateOfIssue = deIDMrzResult.getDateOfIssue();
+ Date dateOfIssue = dePassResult.getDateOfIssue();
if (dateOfIssue != null) {
mExtractedData.add(mBuilder.build(
R.string.PPIssueDate,
@@ -53,23 +62,15 @@ public List extractData(BaseRecognitionResult result) {
));
}
- String eyeColor = deIDMrzResult.getEyeColour();
- if (eyeColor != null && !eyeColor.isEmpty()) {
- mExtractedData.add(mBuilder.build(
- R.string.PPEyeColour,
- eyeColor
- ));
- }
-
- int height = deIDMrzResult.getHeight();
- if (height != 0) {
+ String nat = dePassResult.getNationality();
+ if (nat != null && !nat.isEmpty()) {
mExtractedData.add(mBuilder.build(
- R.string.PPHeight,
- Integer.toString(height) + " cm"
+ R.string.PPNationality,
+ nat
));
}
- String placeOfBirth = deIDMrzResult.getPlaceOfBirth();
+ String placeOfBirth = dePassResult.getPlaceOfBirth();
if (placeOfBirth != null) {
mExtractedData.add(mBuilder.build(
R.string.PPPlaceOfBirth,
@@ -77,7 +78,7 @@ public List extractData(BaseRecognitionResult result) {
));
}
- super.extractMRZData(deIDMrzResult);
+ super.extractMRZData(dePassResult);
}
return mExtractedData;
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/malaysia/MyKadRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/malaysia/MyKadRecognitionResultExtractor.java
index 6c7e5d45..6902d739 100644
--- a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/malaysia/MyKadRecognitionResultExtractor.java
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/malaysia/MyKadRecognitionResultExtractor.java
@@ -9,6 +9,7 @@
import com.microblink.recognizers.blinkid.malaysia.MyKadRecognitionResult;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
/**
@@ -36,7 +37,17 @@ public List extractData(BaseRecognitionResult result) {
mExtractedData.add(mBuilder.build(R.string.PPFullName, myKadResult.getOwnerFullName()));
mExtractedData.add(mBuilder.build(R.string.PPAddress, myKadResult.getOwnerAddress()));
- mExtractedData.add(mBuilder.build(R.string.PPDateOfBirth, myKadResult.getOwnerBirthDate()));
+ mExtractedData.add(mBuilder.build(R.string.PPAddressStreet, myKadResult.getOwnerAddressStreet()));
+ mExtractedData.add(mBuilder.build(R.string.PPAddressZipCode, myKadResult.getOwnerAddressZipCode()));
+ mExtractedData.add(mBuilder.build(R.string.PPAddressCity, myKadResult.getOwnerAddressCity()));
+ mExtractedData.add(mBuilder.build(R.string.PPAddressState, myKadResult.getOwnerAddressState()));
+
+ Date birthDate = myKadResult.getOwnerBirthDate();
+ if (birthDate != null) {
+ mExtractedData.add(mBuilder.build(R.string.PPDateOfBirth, birthDate));
+ } else {
+ mExtractedData.add(mBuilder.build(R.string.PPDateOfBirth, myKadResult.getRawBirthDate()));
+ }
mExtractedData.add(mBuilder.build(R.string.PPSex, myKadResult.getOwnerSex()));
mExtractedData.add(mBuilder.build(R.string.PPReligion, myKadResult.getOwnerReligion()));
mExtractedData.add(mBuilder.build(R.string.PPNRICNumber, myKadResult.getNRICNumber()));
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/serbia/SerbianIDCombinedRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/serbia/SerbianIDCombinedRecognitionResultExtractor.java
new file mode 100644
index 00000000..82a4dfe8
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/serbia/SerbianIDCombinedRecognitionResultExtractor.java
@@ -0,0 +1,103 @@
+package com.microblink.libresult.extract.serbia;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.serbia.combined.SerbianIDCombinedRecognitionResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by daniel on 3/27/17.
+ */
+public class SerbianIDCombinedRecognitionResultExtractor implements IBaseRecognitionResultExtractor {
+
+ private List mExtractedData;
+
+ private RecognitionResultEntry.Builder mBuilder;
+
+ public SerbianIDCombinedRecognitionResultExtractor(Context context) {
+ mBuilder = new RecognitionResultEntry.Builder(context);
+ mExtractedData = new ArrayList<>();
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof SerbianIDCombinedRecognitionResult) {
+ // result is obtained from scanning both sides of Serbian ID
+ SerbianIDCombinedRecognitionResult combinedResult = (SerbianIDCombinedRecognitionResult) result;
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentNumber,
+ combinedResult.getIdentityCardNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfExpiry,
+ combinedResult.getDocumentDateOfExpiry()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ combinedResult.getDocumentDateOfIssue()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPersonalNumber,
+ combinedResult.getJMBG()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPFirstName,
+ combinedResult.getFirstName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPLastName,
+ combinedResult.getLastName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPNationality,
+ combinedResult.getNationality()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfBirth,
+ combinedResult.getDocumentDateOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssuer,
+ combinedResult.getIssuer()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSex,
+ combinedResult.getSex()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPMRZVerified,
+ combinedResult.isMRZVerified()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBothSidesMatch,
+ combinedResult.isDocumentDataMatch()
+ ));
+
+
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/singapore/SingaporeIDCombinedRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/singapore/SingaporeIDCombinedRecognitionResultExtractor.java
new file mode 100644
index 00000000..08fe54fc
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/singapore/SingaporeIDCombinedRecognitionResultExtractor.java
@@ -0,0 +1,97 @@
+package com.microblink.libresult.extract.singapore;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.singapore.combined.SingaporeIDCombinedRecognitionResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by daniel on 2/23/17.
+ */
+
+public class SingaporeIDCombinedRecognitionResultExtractor implements IBaseRecognitionResultExtractor {
+
+
+ private List mExtractedData;
+
+ private RecognitionResultEntry.Builder mBuilder;
+
+ public SingaporeIDCombinedRecognitionResultExtractor(Context context) {
+ mBuilder = new RecognitionResultEntry.Builder(context);
+ mExtractedData = new ArrayList<>();
+ }
+
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof SingaporeIDCombinedRecognitionResult) {
+ // result is obtained from scanning both sides of Croatian ID
+ SingaporeIDCombinedRecognitionResult combinedResult = (SingaporeIDCombinedRecognitionResult) result;
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPFullName,
+ combinedResult.getName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPBloodGroup,
+ combinedResult.getBloodGroup()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPNRICNumber,
+ combinedResult.getCardNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSex,
+ combinedResult.getSex()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPRace,
+ combinedResult.getRace()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfBirth,
+ combinedResult.getDateOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPCountryOfBirth,
+ combinedResult.getCountryOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddress,
+ combinedResult.getAddress()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ combinedResult.getDocumentDateOfIssue()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBothSidesMatch,
+ combinedResult.isDocumentDataMatch()
+ ));
+
+ }
+
+ return mExtractedData;
+ }
+
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/slovakia/SlovakIDCombinedRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/slovakia/SlovakIDCombinedRecognitionResultExtractor.java
new file mode 100644
index 00000000..6091ebbc
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/slovakia/SlovakIDCombinedRecognitionResultExtractor.java
@@ -0,0 +1,123 @@
+package com.microblink.libresult.extract.slovakia;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.slovakia.combined.SlovakIDCombinedRecognitionResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by daniel on 2/17/17.
+ */
+
+public class SlovakIDCombinedRecognitionResultExtractor implements IBaseRecognitionResultExtractor {
+
+ private List mExtractedData;
+
+ private RecognitionResultEntry.Builder mBuilder;
+
+ public SlovakIDCombinedRecognitionResultExtractor(Context context) {
+ mBuilder = new RecognitionResultEntry.Builder(context);
+ mExtractedData = new ArrayList<>();
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof SlovakIDCombinedRecognitionResult) {
+ // result is obtained from scanning both sides of Croatian ID
+ SlovakIDCombinedRecognitionResult combinedResult = (SlovakIDCombinedRecognitionResult) result;
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPLastName,
+ combinedResult.getLastName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPFirstName,
+ combinedResult.getFirstName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentNumber,
+ combinedResult.getIdentityCardNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSex,
+ combinedResult.getSex()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPNationality,
+ combinedResult.getNationality()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfBirth,
+ combinedResult.getDateOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfExpiry,
+ combinedResult.getDocumentDateOfExpiry()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddress,
+ combinedResult.getAddress()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssuingAuthority,
+ combinedResult.getIssuingAuthority()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ combinedResult.getDocumentDateOfIssue()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPersonalNumber,
+ combinedResult.getPersonalIdentificationNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSurnameAtBirth,
+ combinedResult.getSurnameAtBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSpecialRemarks,
+ combinedResult.getSpecialRemarks()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPlaceOfBirth,
+ combinedResult.getCombinedPlaceOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPMRZVerified,
+ combinedResult.isMRZVerified()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBothSidesMatch,
+ combinedResult.isDocumentDataMatch()
+ ));
+
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/slovenia/SlovenianIDCombinedRecognitionResultExtractor.java b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/slovenia/SlovenianIDCombinedRecognitionResultExtractor.java
new file mode 100644
index 00000000..ee8a6bb6
--- /dev/null
+++ b/BlinkIDDemo/LibResult/src/main/java/com/microblink/libresult/extract/slovenia/SlovenianIDCombinedRecognitionResultExtractor.java
@@ -0,0 +1,109 @@
+package com.microblink.libresult.extract.slovenia;
+
+import android.content.Context;
+
+import com.microblink.libresult.R;
+import com.microblink.libresult.extract.IBaseRecognitionResultExtractor;
+import com.microblink.libresult.extract.RecognitionResultEntry;
+import com.microblink.recognizers.BaseRecognitionResult;
+import com.microblink.recognizers.blinkid.slovenia.combined.SlovenianIDCombinedRecognitionResult;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by daniel on 2/7/17.
+ */
+
+public class SlovenianIDCombinedRecognitionResultExtractor implements IBaseRecognitionResultExtractor {
+
+ private List mExtractedData;
+
+ private RecognitionResultEntry.Builder mBuilder;
+
+ public SlovenianIDCombinedRecognitionResultExtractor(Context context) {
+ mBuilder = new RecognitionResultEntry.Builder(context);
+ mExtractedData = new ArrayList<>();
+ }
+
+ @Override
+ public List extractData(BaseRecognitionResult result) {
+
+ if (result == null) {
+ return mExtractedData;
+ }
+
+ if (result instanceof SlovenianIDCombinedRecognitionResult) {
+ // result is obtained from scanning both sides of Croatian ID
+ SlovenianIDCombinedRecognitionResult combinedResult = (SlovenianIDCombinedRecognitionResult) result;
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPLastName,
+ combinedResult.getLastName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPFirstName,
+ combinedResult.getFirstName()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentNumber,
+ combinedResult.getIdentityCardNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPSex,
+ combinedResult.getSex()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPCitizenship,
+ combinedResult.getCitizenship()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfBirth,
+ combinedResult.getDateOfBirth()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDateOfExpiry,
+ combinedResult.getDocumentDateOfExpiry()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPAddress,
+ combinedResult.getAddress()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssuingAuthority,
+ combinedResult.getIssuingAuthority()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPIssueDate,
+ combinedResult.getDocumentDateOfIssue()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPPersonalNumber,
+ combinedResult.getPersonalIdentificationNumber()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPMRZVerified,
+ combinedResult.isMRZVerified()
+ ));
+
+ mExtractedData.add(mBuilder.build(
+ R.string.PPDocumentBothSidesMatch,
+ combinedResult.isDocumentDataMatch()
+ ));
+
+ }
+
+ return mExtractedData;
+ }
+}
diff --git a/BlinkIDDemo/LibResult/src/main/res/values/resultActivityStrings.xml b/BlinkIDDemo/LibResult/src/main/res/values/resultActivityStrings.xml
index 61d0d4aa..1d3ff6af 100644
--- a/BlinkIDDemo/LibResult/src/main/res/values/resultActivityStrings.xml
+++ b/BlinkIDDemo/LibResult/src/main/res/values/resultActivityStrings.xml
@@ -20,6 +20,7 @@
OPT1OPT2MRZ text
+ MRZ verifiedFirst name
@@ -39,6 +40,10 @@
Extended barcode dataSim number
+
+ Document for non residents
+ Document bilingual
+
Full nameReligion
@@ -76,4 +81,14 @@
Valid fromValid until
+
+ Address ZIP code
+ Address street
+ Address city
+ Address state
+ Address house number
+
+
+ Document Both Sides Match
+
\ No newline at end of file
diff --git a/BlinkIDDemo/build.gradle b/BlinkIDDemo/build.gradle
index 214c6c44..e8e0f0e7 100644
--- a/BlinkIDDemo/build.gradle
+++ b/BlinkIDDemo/build.gradle
@@ -19,8 +19,9 @@ allprojects {
// versions of libraries that all modules require
project.ext {
- blinkIdVersion = '3.6.0'
+ blinkIdVersion = '3.7.0'
compileSdkVersion = 25
targetSdkVersion = 25
buildToolsVersion = '25.0.2'
+ appCompatVersion = '25.1.0'
}
\ No newline at end of file
diff --git a/BlinkIDDemo/settings.gradle b/BlinkIDDemo/settings.gradle
index 9da85344..b8eca2ff 100644
--- a/BlinkIDDemo/settings.gradle
+++ b/BlinkIDDemo/settings.gradle
@@ -1 +1 @@
-include ':BlinkIDDemo', ':BlinkIDDemoCustomUI', ':BlinkIDDirectApiDemo', ':BlinkIDDemoCustomSegmentScan', ':LibResult', ':BlinkIDDetectorDemo', ':BlinkIDRandomScanDemo', ':BlinkIDImageListenerDemo'
+include ':BlinkIDDemo', ':BlinkIDDemoCustomUI', ':BlinkIDDirectApiDemo', ':BlinkIDDemoCustomSegmentScan', ':LibResult', ':BlinkIDDetectorDemo', ':BlinkIDRandomScanDemo', ':BlinkIDImageListenerDemo', ':BlinkIDCustomCombinedDemo'
diff --git a/LibBlinkID-javadoc.jar b/LibBlinkID-javadoc.jar
index cc09fa66..3bb82b7d 100644
Binary files a/LibBlinkID-javadoc.jar and b/LibBlinkID-javadoc.jar differ
diff --git a/LibBlinkID.aar b/LibBlinkID.aar
index e999aa54..eec08e9a 100644
Binary files a/LibBlinkID.aar and b/LibBlinkID.aar differ
diff --git a/README.md b/README.md
index a590af9e..f82e80b4 100644
--- a/README.md
+++ b/README.md
@@ -42,6 +42,7 @@ See below for more information about how to integrate _BlinkID_ SDK into your ap
* [Customization of `ScanCard` activity](#scanActivityCustomization)
* [Customization of `SegmentScanActivity` activity](#segmentScanActivityCustomization)
* [Customization of `RandomScanActivity` activity](#randomScanActivityCustomization)
+ * [Using `VerificationFlowActivity` and combined recognizers for scanning multiple parts/sides of the document](#verifiactionFlowActivity)
* [Embedding `RecognizerView` into custom scan activity](#recognizerView)
* [`RecognizerView` reference](#recognizerViewReference)
* [Using direct API for recognition of Android Bitmaps](#directAPI)
@@ -63,9 +64,12 @@ See below for more information about how to integrate _BlinkID_ SDK into your ap
* [Scanning back side of Czech ID documents](#czID_back)
* [Scanning and combining results from front and back side of Czech ID documents](#czechIDCombined)
* [Scanning front side of German ID documents](#germanID_front)
- * [Scanning MRZ side of German ID documents](#germanID_MRZ)
+ * [Scanning back side of German ID documents](#germanID_back)
+ * [Scanning front side of the older German ID documents](#germanID_oldFront)
+ * [Scanning German passports](#germanPassport)
* [Scanning front side of Serbian ID documents](#serbianID_front)
* [Scanning back side of Serbian ID documents](#serbianID_back)
+ * [Scanning and combining results from front and back side of Serbian ID documents](#serbianIDCombined)
* [Scanning front side of Slovak ID documents](#slovakID_front)
* [Scanning back side of Slovak ID documents](#slovakID_back)
* [Scanning and combining results from front and back side of Slovak ID documents](#svkIDCombined)
@@ -112,6 +116,7 @@ The package contains Android Archive (AAR) that contains everything you need to
- _BlinkIDDemo_ module demonstrates quick and simple integration of _BlinkID_ library
- _BlinkIDDemoCustomUI_ demonstrates advanced integration within custom scan activity
+- _BlinkIDCustomCombinedDemo_ demonstrates advanced custom UI integration and usage of the combined recognizers within a custom scan activity.
- _BlinkIDDemoCustomSegmentScan_ demonstrates advanced integration of SegmentScan feature within custom scan activity. It also demonstrates how to perform generic OCR of full camera frame, how to draw OCR results on screen and how to obtain [OcrResult](https://blinkid.github.io/blinkid-android/com/microblink/results/ocr/OcrResult.html) object for further processing.
- _BlinkIDDetectorDemo_ demonstrates how to perform document detection and obtain dewarped image of detected document
- _BlinkIDDirectApiDemo_ demonstrates how to perform scanning of [Android Bitmaps](https://developer.android.com/reference/android/graphics/Bitmap.html)
@@ -128,6 +133,7 @@ The library contains several activities that are responsible for camera control
- `Pdf417ScanActivity` is designed for scanning barcodes
- `SegmentScanActivity` is specifically designed for segment scanning. Unlike other activities, `SegmentScanActivity` does not extend `BaseScanActivity`, so it requires a bit different initialization parameters. Please see _BlinkIDDemo_ app for example and read [section about customizing `SegmentScanActivity`](#segmentScanActivityCustomization).
- `RandomScanActivity` is similar to _SegmentScanActivity_ but it does not force the user to scan text segments in the predefined order.
+- `VerificationFlowActivity` is designed for scanning multiple parts/sides of the document by using provided combined recognizers.
You can also create your own scanning UI - you just need to embed `RecognizerView` into your activity and pass activity's lifecycle events to it and it will control the camera and recognition process. For more information, see [Embedding `RecognizerView` into custom scan activity](#recognizerView).
@@ -158,7 +164,7 @@ After that, you just need to add _BlinkID_ as a dependency to your application (
```
dependencies {
- compile('com.microblink:blinkid:3.6.0@aar') {
+ compile('com.microblink:blinkid:3.7.0@aar') {
transitive = true
}
}
@@ -179,7 +185,7 @@ Current version of Android Studio will not automatically import javadoc from mav
1. In Android Studio project sidebar, ensure [project view is enabled](https://developer.android.com/sdk/installing/studio-androidview.html)
2. Expand `External Libraries` entry (usually this is the last entry in project view)
-3. Locate `blinkid-3.6.0` entry, right click on it and select `Library Properties...`
+3. Locate `blinkid-3.7.0` entry, right click on it and select `Library Properties...`
4. A `Library Properties` pop-up window will appear
5. Click the second `+` button in bottom left corner of the window (the one that contains `+` with little globe)
6. Window for definining documentation URL will appear
@@ -204,7 +210,7 @@ Open your `pom.xml` file and add these directives as appropriate:
com.microblinkblinkid
- 3.6.0
+ 3.7.0aar
@@ -220,7 +226,7 @@ Open your `pom.xml` file and add these directives as appropriate:
```
dependencies {
compile project(':LibBlinkID')
- compile "com.android.support:appcompat-v7:25.2.0"
+ compile "com.android.support:appcompat-v7:25.3.0"
}
```
5. If you plan to use ProGuard, add following lines to your `proguard-rules.pro`:
@@ -685,6 +691,115 @@ With this extra you can set the resource ID of the sound to be played when the s
intent.putExtra(RandomScanActivity.EXTRAS_BEEP_RESOURCE, R.raw.beep);
```
+## Using `VerificationFlowActivity` and combined recognizers for scanning multiple parts/sides of the document
+
+`VerificationFlowActivity` is designed for scanning multiple parts/sides of the document by using provided combined recognizers, which are subclasses of the [CombinedRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/CombinedRecognizerSettings.html).
+
+Combined recognizers are special types of recognizers that are implemented for scanning multiple parts/sides of the document in predefined order. They combine results from individual scans to boost accuracy and merge them into the final result. For example, if front and back side of the ID card is scanned and the same information can be read from the front and back side, its scanned values will be compared and combined in order to return the final value with higher confidence.
+
+Document scan is performed in multiple steps with predefined order. When some step is completed `VerificationFlowActivity` will make appropriate UI changes to inform the user to scan next part/side of the document. You can start recognition process by starting `VerificationFlowActivity` activity with Intent initialized in the following way:
+
+```java
+// Intent for VerificationFlowActivity Activity
+Intent intent = new Intent(this, VerificationFlowActivity.class);
+
+// set your license key
+// obtain your license key at http://microblink.com/login or
+// contact us at http://help.microblink.com
+intent.putExtra(VerificationFlowActivity.EXTRAS_LICENSE_KEY, Config.getLicenseKey());
+
+// create appropriate combined recognizer settings for your type of the document
+CombinedRecognizerSettings recognizerSettings = createCombinedRecognizerSettings();
+// pass recognizer settings through intent extras
+intent.putExtra(VerificationFlowActivity.EXTRAS_COMBINED_RECOGNIZER_SETTINGS, recognizerSettings);
+// Starting Activity
+startActivityForResult(intent, MY_REQUEST_CODE);
+```
+
+After `VerificationFlowActivity` activity finishes the scan, it will return to the calling activity and will call method `onActivityResult`. You can obtain the scanning results in that method.
+
+```java
+@Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ if (requestCode == MY_REQUEST_CODE) {
+ if (resultCode == VerificationFlowActivity.RESULT_OK && data != null) {
+ // perform processing of the data here
+
+ // for example, obtain parcelable recognition result
+ Bundle extras = data.getExtras();
+ // All combined recognizers produce results of type CombinedRecognitionResult.
+ // Instead of casting to CombinedRecognitionResult, you should cast the combined
+ // recognition result to the exact result type that is expected for used
+ // combined recognizer.
+ CombinedRecognitionResult combinedResult = (CombinedRecognitionResult) extras.getParcelable(
+ VerificationFlowActivity.EXTRAS_COMBINED_RECOGNITION_RESULT
+ );
+
+ // do something with the result
+ }
+ }
+}
+```
+
+### `VerificationFlowActivity` intent extras
+
+This section will discuss possible parameters that can be sent over `Intent` for `VerificationFlowActivity` activity that can customize default behaviour. There are several intent extras that can be sent to `VerificationFlowActivity` actitivy:
+
+* # **`VerificationFlowActivity.EXTRAS_COMBINED_RECOGNIZER_SETTINGS`** - Settings for the combined recognizer that will be used. Must be instance of the [CombinedRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/CombinedRecognizerSettings.html).
+
+* # **`VerificationFlowActivity.EXTRAS_COMBINED_RECOGNITION_RESULT`** - you can use this extra in `onActivityResult` method of calling activity to obtain combined recognition result.
+
+* # **`VerificationFlowActivity.EXTRAS_COMBINED_CAMERA_TYPE`** - with this extra you can define which camera on device will be used. By default back facing camera is used. To set the extra to intent, use the following code snippet:
+
+ ```java
+ intent.putExtra(VerificationFlowActivity.EXTRAS_COMBINED_CAMERA_TYPE, (Parcelable)CameraType.CAMERA_BACKFACE);
+ ```
+
+* # **`VerificationFlowActivity.EXTRAS_WARNING_DIALOG_NOT_MATCH_TITLE_RES`**, **`VerificationFlowActivity.EXTRAS_WARNING_DIALOG_NOT_MATCH_MESSAGE_RES`**, **`VerificationFlowActivity.EXTRAS_WARNING_DIALOG_NOT_MATCH_BUTTON_TEXT_RES`** - with these intent extras you can define String resource IDs for the title, message and button texts of the warning dialog that is shown when combined recognizer data does not pass validation (e.g. document sides don't match).
+
+* # **`VerificationFlowActivity.EXTRAS_SPLASH_MSG_RES_DOCUMENT_FIRST_SIDE`**, **`VerificationFlowActivity.EXTRAS_SPLASH_MSG_RES_DOCUMENT_SECOND_SIDE`** - with these intent extras you can define String resource IDs for the splash screen messages that will be shown above document scan viewfinder when scanning of the first/second side of the document is starting.
+
+* # **`VerificationFlowActivity.EXTRAS_SPLASH_ICON_RES_DOCUMENT_FIRST_SIDE`**, **`VerificationFlowActivity.EXTRAS_SPLASH_ICON_RES_DOCUMENT_SECOND_SIDE`** - with these intent extras you can define Drawable resource IDs of the splash screen images that will be shown above document scan viewfinder when scanning of the first/second side of the document is starting.
+
+* # **`VerificationFlowActivity.EXTRAS_INSTRUCTIONS_DOCUMENT_FIRST_SIDE`**, **`VerificationFlowActivity.EXTRAS_INSTRUCTIONS_DOCUMENT_SECOND_SIDE`** - with these intent extras you can define String resource IDs of the scan instructions that will be shown to the user as camera overlay during recognition of the first/second side of the document.
+
+* # **`VerificationFlowActivity.EXTRAS_BEEP_RESOURCE`** - with this extra you can set the resource ID of the sound to be played when scan completes. You can use following snippet to set this extra:
+
+ ```java
+ intent.putExtra(VerificationFlowActivity.EXTRAS_BEEP_RESOURCE, R.raw.beep);
+ ```
+
+* # **`VerificationFlowActivity.EXTRAS_SCAN_RESULT_LISTENER`** - with this extra you can set a [ParcelableScanResultListener](https://blinkid.github.io/blinkid-android/com/microblink/view/recognition/ParcelableScanResultListener.html) with callback that will be called when valid recognition result is available (for each result that is produced by activated recognizer). When scan result listener is passed to the activity, **recognition results will not be returned to the caller activity through result intent**. Scan result listener must be used in cases when size of the recognition results exceeds the allowed Android intent size limit.
+
+* # **`VerificationFlowActivity.EXTRAS_USE_LEGACY_CAMERA_API`** - with this boolean flag you can enforce using legacy Camera API even on Lollipop devices that support new Camera2 API. Use this only if you have problems with camera management on Lollipop devices.
+
+* # **`VerificationFlowActivity.EXTRAS_SET_FLAG_SECURE`** - with this extra you can request setting of `FLAG_SECURE` on activity window which indicates that the display has a secure video output and supports compositing secure surfaces. Use this to prevent taking screenshots of the activity window content and to prevent content from being viewed on non-secure displays. To set `FLAG_SECURE` on camera activity, use the following code snippet:
+
+ ```java
+ intent.putExtra(VerificationFlowActivity.EXTRAS_SET_FLAG_SECURE, true);
+ ```
+
+* # **`VerificationFlowActivity.EXTRAS_LICENSE_KEY`** - with this extra you can set the license key for _BlinkID_. You can obtain your licence key from [Microblink website](http://microblink.com/login) or you can contact us at [http://help.microblink.com](http://help.microblink.com). Once you obtain a license key, you can set it with following snippet:
+
+ ```java
+ // set the license key
+ intent.putExtra(VerificationFlowActivity.EXTRAS_LICENSE_KEY, "Enter_License_Key_Here");
+ ```
+
+ Licence key is bound to package name of your application. For example, if you have licence key that is bound to `com.microblink.blinkid` app package, you cannot use the same key in other applications. However, if you purchase Premium licence, you will get licence key that can be used in multiple applications. This licence key will then not be bound to package name of the app. Instead, it will be bound to the licencee string that needs to be provided to the library together with the licence key. To provide licencee string, use the `EXTRAS_LICENSEE` intent extra like this:
+
+ ```java
+ // set the license key
+ intent.putExtra(VerificationFlowActivity.EXTRAS_LICENSE_KEY, "Enter_License_Key_Here");
+ intent.putExtra(VerificationFlowActivity.EXTRAS_LICENSEE, "Enter_Licensee_Here");
+ ```
+
+* # **`VerificationFlowActivity.EXTRAS_IMAGE_LISTENER`** - with this extra you can set your implementation of [ImageListener interface](https://blinkid.github.io/blinkid-android/com/microblink/image/ImageListener.html) that will obtain images that are being processed. Make sure that your [ImageListener](https://blinkid.github.io/blinkid-android/com/microblink/image/ImageListener.html) implementation correctly implements [Parcelable](https://developer.android.com/reference/android/os/Parcelable.html) interface with static [CREATOR](https://developer.android.com/reference/android/os/Parcelable.Creator.html) field. Without this, you might encounter a runtime error. For more information and example, see [Using ImageListener to obtain images that are being processed](#imageListener). By default, _ImageListener_ will receive all possible images that become available during recognition process. This will introduce performance penalty because most of those images will probably not be used so sending them will just waste time. To control which images should become available to _ImageListener_, you can also set [ImageMetadata settings](https://blinkid.github.io/blinkid-android/com/microblink/metadata/MetadataSettings.ImageMetadataSettings.html) with `VerificationFlowActivity.EXTRAS_IMAGE_METADATA_SETTINGS`
+
+* # **`VerificationFlowActivity.EXTRAS_IMAGE_METADATA_SETTINGS`** - with this extra you can set [ImageMetadata settings](https://blinkid.github.io/blinkid-android/com/microblink/metadata/MetadataSettings.ImageMetadataSettings.html) which will define which images will be sent to [ImageListener interface](https://blinkid.github.io/blinkid-android/com/microblink/image/ImageListener.html) given via `VerificationFlowActivity.EXTRAS_IMAGE_LISTENER` extra. If _ImageListener_ is not given via Intent, then this extra has no effect. You can see example usage of _ImageMetadata Settings_ in chapter [Obtaining various metadata with _MetadataListener_](#metadataListener) and in provided demo apps.
+
## Embedding `RecognizerView` into custom scan activity
This section will discuss how to embed [RecognizerView](https://blinkid.github.io/blinkid-android/com/microblink/view/recognition/RecognizerView.html) into your scan activity and perform scan.
@@ -1536,7 +1651,7 @@ public void onScanningDone(RecognitionResults results) {
// you can use getters of MRTDCombinedRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
- if (!result.getDocumentBothSidesMatch()) {
+ if (!result.isDocumentDataMatch()) {
// face and MRZ are not from the same document
} else {
String issuer = result.getIssuer();
@@ -1707,7 +1822,7 @@ public void onScanningDone(RecognitionResults results) {
// you can use getters of AustrianIDCombinedRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
- if (!result.getDocumentBothSidesMatch()) {
+ if (!result.isDocumentDataMatch()) {
// front and back sides are not from the same ID card
} else {
String firstName = result.getFirstName();
@@ -1865,8 +1980,6 @@ public void onMetadataAvailable(Metadata metadata) {
Croatian ID combined recognizer produces [CroatianIDCombinedRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/croatia/combined/CroatianIDCombinedRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `CroatianIDCombinedRecognitionResult` class.
-**Note:** `CroatianIDCombinedRecognitionResult` extends [BlinkOCRRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkocr/BlinkOCRRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
-
See the following snippet for an example:
```java
@@ -1880,7 +1993,7 @@ public void onScanningDone(RecognitionResults results) {
// you can use getters of CroatianIDCombinedRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
- if (!result.getDocumentBothSidesMatch()) {
+ if (!result.isDocumentDataMatch()) {
// front and back sides are not from the same ID card
} else {
String firstName = result.getFirstName();
@@ -2038,8 +2151,6 @@ public void onMetadataAvailable(Metadata metadata) {
Czech ID combined recognizer produces [CzechIDCombinedRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/czechia/combined/CzechIDCombinedRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `CzechIDCombinedRecognitionResult` class.
-**Note:** `CzechIDCombinedRecognitionResult` extends [BlinkOCRRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkocr/BlinkOCRRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
-
See the following snippet for an example:
```java
@@ -2053,7 +2164,7 @@ public void onScanningDone(RecognitionResults results) {
// you can use getters of CzechIDCombinedRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
- if (!result.getDocumentBothSidesMatch()) {
+ if (!result.isDocumentDataMatch()) {
// front and back sides are not from the same ID card
} else {
String firstName = result.getFirstName();
@@ -2122,17 +2233,17 @@ public void onScanningDone(RecognitionResults results) {
**Available getters are documented in [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/front/GermanIDFrontSideRecognitionResult.html).**
-## Scanning MRZ side of German ID documents
+## Scanning back side of German ID documents
-This section will discuss the setting up of German ID MRZ Side recognizer and obtaining results from it.
+This section will discuss the setting up of German ID Back Side recognizer and obtaining results from it.
-### Setting up German ID card MRZ side recognizer
+### Setting up German ID card back side recognizer
-To activate German ID MRZ side recognizer, you need to create [GermanIDMRZSideRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/mrz/GermanIDMRZSideRecognizerSettings.html) and add it to `RecognizerSettings` array. You can use the following code snippet to perform that:
+To activate German ID back side recognizer, you need to create [GermanIDBackSideRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/back/GermanIDBackSideRecognizerSettings.html) and add it to `RecognizerSettings` array. You can use the following code snippet to perform that:
```java
private RecognizerSettings[] setupSettingsArray() {
- GermanIDMRZSideRecognizerSettings sett = new GermanIDMRZSideRecognizerSettings();
+ GermanIDBackSideRecognizerSettings sett = new GermanIDBackSideRecognizerSettings();
// now add sett to recognizer settings array that is used to configure
// recognition
@@ -2140,13 +2251,13 @@ private RecognizerSettings[] setupSettingsArray() {
}
```
-**You can also tweak recognition parameters with methods of [GermanIDMRZSideRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/mrz/GermanIDMRZSideRecognizerSettings.html). Check [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/mrz/GermanIDMRZSideRecognizerSettings.html) for more information.**
+**You can also tweak recognition parameters with methods of [GermanIDBackSideRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/back/GermanIDBackSideRecognizerSettings.html). Check [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/back/GermanIDBackSideRecognizerSettings.html) for more information.**
-### Obtaining results from German ID card MRZ side recognizer
+### Obtaining results from German ID card back side recognizer
-German ID MRZ side recognizer produces [GermanIDMRZSideRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/mrz/GermanIDMRZSideRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `GermanIDMRZSideRecognitionResult` class.
+German ID back side recognizer produces [GermanIDBackSideRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/back/GermanIDBackSideRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `GermanIDBackSideRecognitionResult` class.
-**Note:** `GermanIDMRZSideRecognitionResult` extends [MRTDRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/mrtd/MRTDRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
+**Note:** `GermanIDBackSideRecognitionResult` extends [MRTDRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/mrtd/MRTDRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
See the following snippet for an example:
@@ -2155,10 +2266,10 @@ See the following snippet for an example:
public void onScanningDone(RecognitionResults results) {
BaseRecognitionResult[] dataArray = results.getRecognitionResults();
for(BaseRecognitionResult baseResult : dataArray) {
- if(baseResult instanceof GermanIDMRZSideRecognitionResult) {
- GermanIDMRZSideRecognitionResult result = (GermanIDMRZSideRecognitionResult) baseResult;
+ if(baseResult instanceof GermanIDBackSideRecognitionResult) {
+ GermanIDBackSideRecognitionResult result = (GermanIDBackSideRecognitionResult) baseResult;
- // you can use getters of GermanIDMRZSideRecognitionResult class to
+ // you can use getters of GermanIDBackSideRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
String address = result.getAddress();
@@ -2171,7 +2282,110 @@ public void onScanningDone(RecognitionResults results) {
}
```
-**Available getters are documented in [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/mrz/GermanIDMRZSideRecognitionResult.html).**
+**Available getters are documented in [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/back/GermanIDBackSideRecognitionResult.html).**
+
+## Scanning front side of the older German ID documents
+
+This section will discuss the setting up of German ID recognizer for older cards (issued between 1 April 1987 and 31 October 2010) and obtaining results from it.
+
+### Setting up German ID card recognizer for the front side of the older card
+
+To activate German old ID card recognizer, you need to create [GermanOldIDRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/old/front/GermanOldIDRecognizerSettings.html) and add it to `RecognizerSettings` array. You can use the following code snippet to perform that:
+
+```java
+private RecognizerSettings[] setupSettingsArray() {
+ GermanOldIDRecognizerSettings sett = new GermanOldIDRecognizerSettings();
+
+ // now add sett to recognizer settings array that is used to configure
+ // recognition
+ return new RecognizerSettings[] { sett };
+}
+```
+
+**You can also tweak recognition parameters with methods of [GermanOldIDRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/old/front/GermanOldIDRecognizerSettings.html). Check [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/old/front/GermanOldIDRecognizerSettings.html) for more information.**
+
+### Obtaining results from German old ID card recognizer
+
+German old ID recognizer produces [GermanOldIDRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/old/front/GermanOldIDRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `GermanOldIDRecognitionResult` class.
+
+**Note:** `GermanOldIDRecognitionResult` extends [MRTDRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/mrtd/MRTDRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
+
+See the following snippet for an example:
+
+```java
+@Override
+public void onScanningDone(RecognitionResults results) {
+ BaseRecognitionResult[] dataArray = results.getRecognitionResults();
+ for(BaseRecognitionResult baseResult : dataArray) {
+ if(baseResult instanceof GermanOldIDRecognitionResult) {
+ GermanOldIDRecognitionResult result = (GermanOldIDRecognitionResult) baseResult;
+
+ // you can use getters of GermanOldIDRecognitionResult class to
+ // obtain scanned information
+ if(result.isValid() && !result.isEmpty()) {
+ String placeOfBirth = result.getPlaceOfBirth();
+ } else {
+ // not all relevant data was scanned, ask user
+ // to try again
+ }
+ }
+ }
+}
+```
+
+**Available getters are documented in [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/old/front/GermanOldIDRecognitionResult.html).**
+
+## Scanning German passports
+
+This section will discuss the setting up of German passport recognizer and obtaining results from it.
+
+### Setting up German passport recognizer
+
+To activate German passport recognizer, you need to create [GermanPassportRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/passport/GermanPassportRecognizerSettings.html) and add it to `RecognizerSettings` array. You can use the following code snippet to perform that:
+
+```java
+private RecognizerSettings[] setupSettingsArray() {
+ GermanPassportRecognizerSettings sett = new GermanPassportRecognizerSettings();
+
+ // now add sett to recognizer settings array that is used to configure
+ // recognition
+ return new RecognizerSettings[] { sett };
+}
+```
+
+**You can also tweak recognition parameters with methods of [GermanPassportRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/passport/GermanPassportRecognizerSettings.html). Check [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/passport/GermanPassportRecognizerSettings.html) for more information.**
+
+### Obtaining results from German passport recognizer
+
+German passport recognizer produces [GermanPassportRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/passport/GermanPassportRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `GermanPassportRecognitionResult` class.
+
+**Note:** `GermanPassportRecognitionResult` extends [MRTDRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/mrtd/MRTDRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
+
+See the following snippet for an example:
+
+```java
+@Override
+public void onScanningDone(RecognitionResults results) {
+ BaseRecognitionResult[] dataArray = results.getRecognitionResults();
+ for(BaseRecognitionResult baseResult : dataArray) {
+ if(baseResult instanceof GermanPassportRecognitionResult) {
+ GermanPassportRecognitionResult result = (GermanPassportRecognitionResult) baseResult;
+
+ // you can use getters of GermanPassportRecognitionResult class to
+ // obtain scanned information
+ if(result.isValid() && !result.isEmpty()) {
+ String name = result.getName();
+ String surname = result.getSurname();
+ } else {
+ // not all relevant data was scanned, ask user
+ // to try again
+ }
+ }
+ }
+}
+```
+
+**Available getters are documented in [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/germany/passport/GermanPassportRecognitionResult.html).**
## Scanning front side of Serbian ID documents
@@ -2276,6 +2490,74 @@ public void onScanningDone(RecognitionResults results) {
**Available getters are documented in [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/serbia/back/SerbianIDBackSideRecognitionResult.html).**
+## Scanning and combining results from front and back side of Serbian ID documents
+
+This section will discuss the setting up of Serbian ID Combined recognizer and obtaining results from it. This recognizer combines results from front and back side of the Serbian ID card to boost result accuracy. Also it checks whether front and back sides are from the same ID card.
+
+### Setting up Serbian ID card combined recognizer
+
+To activate Serbian ID combined recognizer, you need to create [SerbianIDCombinedRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/serbia/combined/SerbianIDCombinedRecognizerSettings.html) and add it to `RecognizerSettings` array. You can use the following code snippet:
+
+```java
+private RecognizerSettings[] setupSettingsArray() {
+ SerbianIDCombinedRecognizerSettings sett = new SerbianIDCombinedRecognizerSettings();
+
+ // now add sett to recognizer settings array that is used to configure
+ // recognition
+ return new RecognizerSettings[] { sett };
+}
+```
+
+**You can also tweak recognition parameters with methods of [SerbianIDCombinedRecognizerSettings](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/serbia/combined/SerbianIDCombinedRecognizerSettings.html). Check [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/serbia/combined/SerbianIDCombinedRecognizerSettings.html) for more information.**
+
+**Note:** In your [custom UI integration](#recognizerView), you have to enable [obtaining of partial result metadata](https://blinkid.github.io/blinkid-android/com/microblink/metadata/MetadataSettings.html#setPartialResultMetadataAllowed-boolean-) in [MetadataSettings](https://blinkid.github.io/blinkid-android/com/microblink/metadata/MetadataSettings.html) if you want to be informed when recognition of the front side is done and receive [RecognitionResultMetadata](https://blinkid.github.io/blinkid-android/com/microblink/metadata/RecognitionResultMetadata.html) in [onMetadataAvailable](https://blinkid.github.io/blinkid-android/com/microblink/metadata/MetadataListener.html) callback. When callback with [RecognitionResultMetadata](https://blinkid.github.io/blinkid-android/com/microblink/metadata/RecognitionResultMetadata.html) is called you can make appropriate changes in the UI to notify the user to flip document and scan back side. See the following snippet for an example:
+
+```java
+@Override
+public void onMetadataAvailable(Metadata metadata) {
+ if (metadata instanceof RecognitionResultMetadata) {
+ BaseRecognitionResult result = ((RecognitionResultMetadata) metadata).getScannedResult();
+ if (result != null && result instanceof SerbianIDFrontSideRecognitionResult) {
+ // notify user to scan the back side
+ }
+ }
+}
+```
+
+### Obtaining results from Serbian ID card combined recognizer
+
+Serbian ID combined recognizer produces [SerbianIDCombinedRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/serbia/combined/SerbianIDCombinedRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `SerbianIDCombinedRecognitionResult` class.
+
+See the following snippet for an example:
+
+```java
+@Override
+public void onScanningDone(RecognitionResults results) {
+ BaseRecognitionResult[] dataArray = results.getRecognitionResults();
+ for(BaseRecognitionResult baseResult : dataArray) {
+ if(baseResult instanceof SerbianIDCombinedRecognitionResult) {
+ SerbianIDCombinedRecognitionResult result = (SerbianIDCombinedRecognitionResult) baseResult;
+
+ // you can use getters of SerbianIDCombinedRecognitionResult class to
+ // obtain scanned information
+ if(result.isValid() && !result.isEmpty()) {
+ if (!result.isDocumentDataMatch()) {
+ // front and back sides are not from the same ID card
+ } else {
+ String firstName = result.getFirstName();
+ String lastName = result.getLastName();
+ }
+ } else {
+ // not all relevant data was scanned, ask user
+ // to try again
+ }
+ }
+ }
+}
+```
+
+**Available getters are documented in [Javadoc](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/serbia/combined/SerbianIDCombinedRecognitionResult.html).**
+
## Scanning front side of Slovak ID documents
This section will discuss the setting up of Slovak ID Front Side recognizer and obtaining results from it.
@@ -2417,8 +2699,6 @@ public void onMetadataAvailable(Metadata metadata) {
Slovak ID combined recognizer produces [SlovakIDCombinedRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/slovakia/combined/SlovakIDCombinedRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `SlovakIDCombinedRecognitionResult` class.
-**Note:** `SlovakIDCombinedRecognitionResult` extends [BlinkOCRRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkocr/BlinkOCRRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
-
See the following snippet for an example:
```java
@@ -2432,7 +2712,7 @@ public void onScanningDone(RecognitionResults results) {
// you can use getters of SlovakIDCombinedRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
- if (!result.getDocumentBothSidesMatch()) {
+ if (!result.isDocumentDataMatch()) {
// front and back sides are not from the same ID card
} else {
String firstName = result.getFirstName();
@@ -2590,8 +2870,6 @@ public void onMetadataAvailable(Metadata metadata) {
Slovenian ID combined recognizer produces [SlovenianIDCombinedRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/slovenia/combined/SlovenianIDCombinedRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `SlovenianIDCombinedRecognitionResult` class.
-**Note:** `SlovenianIDCombinedRecognitionResult` extends [BlinkOCRRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkocr/BlinkOCRRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
-
See the following snippet for an example:
```java
@@ -2605,7 +2883,7 @@ public void onScanningDone(RecognitionResults results) {
// you can use getters of SlovenianIDCombinedRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
- if (!result.getDocumentBothSidesMatch()) {
+ if (!result.isDocumentDataMatch()) {
// front and back sides are not from the same ID card
} else {
String firstName = result.getFirstName();
@@ -2933,7 +3211,19 @@ Returns owner's date of birth as raw string in format `YYMMDD`, or `null` if dat
Returns the full name of the card holder.
##### `String getOwnerAddress()`
-Returns the address of the card holder.
+Returns the full address of the card holder.
+
+##### `String getOwnerAddressZipCode()`
+Returns extracted ZIP code from the address of the card holder.
+
+##### `String getOwnerAddressStreet()`
+Returns extracted street name from the address of the card holder.
+
+##### `String getOwnerAddressCity()`
+Returns extracted city name from the address of the card holder.
+
+##### `String getOwnerAddressState()`
+Returns extracted state from the address of the card holder.
##### `String getOwnerReligion()`
Returns the religion of the card holder. Possible values are `ISLAM` and `null`.
@@ -3127,8 +3417,6 @@ public void onMetadataAvailable(Metadata metadata) {
Singapore ID combined recognizer produces [SingaporeIDCombinedRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkid/singapore/combined/SingaporeIDCombinedRecognitionResult.html). You can use `instanceof` operator to check if element in results array is instance of `SingaporeIDCombinedRecognitionResult` class.
-**Note:** `SingaporeIDCombinedRecognitionResult` extends [BlinkOCRRecognitionResult](https://blinkid.github.io/blinkid-android/com/microblink/recognizers/blinkocr/BlinkOCRRecognitionResult.html) so make sure you take that into account when using `instanceof` operator.
-
See the following snippet for an example:
```java
@@ -3142,7 +3430,7 @@ public void onScanningDone(RecognitionResults results) {
// you can use getters of SingaporeIDCombinedRecognitionResult class to
// obtain scanned information
if(result.isValid() && !result.isEmpty()) {
- if (!result.getDocumentBothSidesMatch()) {
+ if (!result.isDocumentDataMatch()) {
// front and back sides are not from the same ID card
} else {
String name = result.getName();
diff --git a/Release notes.md b/Release notes.md
index 83b08abb..a6532cae 100644
--- a/Release notes.md
+++ b/Release notes.md
@@ -1,5 +1,46 @@
# Release notes
+## 3.7.0
+
+- updated German ID recognizers:
+ - instead of `GermanIDMRZSideRecognizer`, which was used for scanning front side of the older ID cards and back side of the new ID cards, there are two specialised recognizers: `GermanIDBackSideRecognizer` and `GermanOldIDRecognizer`
+ - improved scanning accuracy of the `GermanIDFrontSideRecognizer` (name and surname)
+ - splitting address from back side of the new German ID (GermanIDBackSideRecognizer) to ZIP code, city, street and house number
+
+- better support for German passports: `GermanPassportRecognizer` reads passport data from MRZ and fields outside of the MRZ
+
+- splitting address in `MyKadRecognizer` to street, ZIP code, city and state
+
+- improved Croatian ID recognizers:
+ - multiple scans are used for better confidence
+
+- `TopUpParser` improvements
+
+- `DateParser` can parse dates with month names in English (either full or abbreviated), if this option is enabled
+
+- added support for polish IBAN without PL prefix to `IBANParser`
+
+- fixed returning of images inside TemplatingAPI for frames when document was not correctly detected
+
+- introduced combined recognizers:
+ - `AustrianIDCombinedRecognizer`: scans front and back side of the Austrian ID
+ - `CroatianIDCombinedRecognizer`: scans front and back side of the Croatian ID
+ - `CzechIDCombinedRecognizer`: scans front and back side of the Czech ID
+ - `MRTDCombinedRecognizer`: scans face image from any type of the document and Machine Readable Zone
+ - `SerbianIDCombinedRecognizer`: scans front and back side of the Serbian ID
+ - `SingaporeIDCombinedRecognizer`: scans front and back side of the Singapore ID
+ - `SlovakIDCombinedRecognizer`: scans front and back side of the Slovak ID
+ - `SlovenianIDCombinedRecognizer`: scans front and back side of the Slovenian ID
+
+ Combined recognizers can be used for scanning multiple parts/sides of the document in predefined order. They combine results from individual scans to boost accuracy and merge them into the final result.
+
+- added `VerificationFlowActivity` which is designed for scanning multiple parts/sides of the document by using provided combined recognizers
+
+- optimised native binary size
+ - 15% size reduction for `arm64-v8a` ABI
+ - 14% size reduction for `x86` ABI
+ - 13% size reduction for `armeabi-v7a` and `x86_64 ABIs
+
## 3.6.0
- added `AztecRecognizer` for scanning Aztec barcodes
diff --git a/builtFromCommit.txt b/builtFromCommit.txt
index 8a697b95..54daed9b 100644
--- a/builtFromCommit.txt
+++ b/builtFromCommit.txt
@@ -1 +1 @@
-Built from commit db863bd8cf0f23fb309a2386f664d2fc3cb7ecb5
+Built from commit d5de94703a49ad6797e8c5af8a2faea4e23af926
diff --git a/docs/allclasses-frame.html b/docs/allclasses-frame.html
index 71618d44..a3af6921 100644
--- a/docs/allclasses-frame.html
+++ b/docs/allclasses-frame.html
@@ -31,6 +31,10 @@
Returns the key(name) of the intent extra under which the recognition result of the
+ additional step should be stored and returned as activity result.
Returns the key(name) of the intent extra under which the recognition result of the
+ additional step should be stored and returned as activity result.
+
+
Returns:
+
key(name) of the intent extra under which the recognition result of the
+ additional step should be stored and returned as activity result.
Creates and returns camera overlay view of the additional verification step. This is
+ appropriate place where references to all camera overlay subviews, that must be
+ available later, should be obtained. This method is called after all intent extras
+ has been read (after the BaseVerificationFlowActivity.readAdditionalIntentExtras(Bundle)
+ hass been called).
Callback method that will be called when additional step is starting. This method is
+ called after the additional step camera overlay has been created. This is appropriate
+ place to make appropriate UI changes, e.g. show messages about started step, show splash screen, etc.
+
+
Parameters:
+
isCameraPreviewStarted - whether camera preview has been already started or not. If the
+ camera preview has not been started yet (value is false),
+ method BaseVerificationFlowActivity.onCameraPreviewStarted() will be called when/if
+ the camera is successfully started.
Base activity class for verification flow activities that use combined recognizers. Here is the implementation
+ of the scan flow logic and derived activities should define user interface and its updates during scan process.
+ Besides combined recognizer, one additional step with arbitrary recognizer can be included to the
+ recognition flow.
Key for passing a ParcelableScanResultListener with callback that will be called when
+ valid recognition result is available (for each result that is produced by activated recognizers).
Request setting of FLAG_SECURE on activity window which indicates that the display has
+ a secure video output and supports compositing secure surfaces.
Creates configuration for the additional verification step that can be performed in the verification
+ flow in addition to the combined recognizer step.
public static final java.lang.String EXTRAS_IMAGE_LISTENER
+
Define an ImageListener that will obtain images that are being processed.
+ Make sure that your ImageListener implementation correctly implements Parcelable
+ interface with static CREATOR field. Without this, you might encounter a runtime error.
public static final java.lang.String EXTRAS_SCAN_RESULT_LISTENER
+
Key for passing a ParcelableScanResultListener with callback that will be called when
+ valid recognition result is available (for each result that is produced by activated recognizers).
+ When scan result listener is passed to the activity, recognition results will not be returned
+ to the caller activity through result intent. Scan result listener must be used in cases when
+ size of the recognition results exceeds the allowed Android intent size limit.
public static final java.lang.String EXTRAS_USE_LEGACY_CAMERA_API
+
Force using legacy Camera API even on Lollipop devices that support new Camera2 API.
+ Use this only if you have problems with camera management on Lollipop devices.
public static final java.lang.String EXTRAS_SET_FLAG_SECURE
+
Request setting of FLAG_SECURE on activity window which indicates that the display has
+ a secure video output and supports compositing secure surfaces.
+ Use this to prevent taking screenshots of activity window content and to prevent content from
+ being viewed on non-secure displays.
public static final java.lang.String EXTRAS_WARNING_DIALOG_NOT_MATCH_TITLE_RES
+
String resource ID for the title of the warning dialog that is shown when combined recognizer
+ data does not pass validation (e.g. document sides don't match).
public static final java.lang.String EXTRAS_WARNING_DIALOG_NOT_MATCH_MESSAGE_RES
+
String resource ID for the message of the warning dialog that is shown when combined recognizer
+ data does not pass validation (e.g. document sides don't match).
public static final java.lang.String EXTRAS_WARNING_DIALOG_NOT_MATCH_BUTTON_TEXT_RES
+
String resource ID for the button text of the warning dialog that is shown when combined recognizer
+ data does not pass validation (e.g. document sides don't match).
Called just after camera preview has successfully
+ started and no exceptions occurred. When this method is called, it means
+ that from now on, frames will arrive and preview will be shown.
Called inside pause method of CameraView just haver camera preview has been stopped.
+ After this method is called, frames will no longer arrive nor will be shown.
Called when recognition results with exception. Known exceptions
+ that can occur are following:
+ * com.microblink.hardware.camera.CameraResolutionTooSmallException is thrown when largest possible camera preview
+ resolution is not enough for making a successful scan
+ * java.lang.UnsatisfiedLinkError is thrown when native library was not successfully loaded thus making scans impossible
+ * com.microblink.recognition.RecognizerError is thrown when initialization or reinitialization of native recognizer fails
+ * com.microblink.recognition.FeatureNotSupportedException is thrown when scanning cannot be performed. The reason why
+ scanning cannot be perfomed can be obtained by calling getReason() method of thrown exception.
+ * java.lang.Throwable is thrown in all other cases (for example when camera is not ready because it is used by other
+ apps or some unknown error has occurred)
Called on Android 6.0 and newer when runtime camera permission was not given to the app. You should implement this
+ callback by requesting camera permission from user.
This method will be called when camera focusing has failed.
+ Camera manager usually tries different focusing strategies
+ and this method is called when all those strategies fail to
+ indicate that either object on which camera is being focused
+ is too close or ambient light conditions are poor.
Called when activity is flipped. This can happen if your activity is in sensor or user orientation
+ mode and landscape to reverse landscape or portrait to reverse portrait or vice versa orientation
+ change has occurred. Normally, Android will not give you any notification when this orientation
+ change occurs, so SDK automatically detects that and with this listener informs you of such
+ event.
This method should be implemented to obtain activity's intent extras that are
+ relevant to the derived activity. Method is called in onCreate(Bundle).
+
+
Parameters:
+
extras - intent extras bundle obtained with getIntent().getExtras()
Creates and returns camera overlay view for the combined verification step. This is
+ appropriate place where references to all camera overlay subviews, that must be
+ available later, should be obtained. This method is called after all intent extras
+ has been read (after the readAdditionalIntentExtras(Bundle)
+ hass been called).
Callback method that is called when combined recognizer is set to scan first side and recognition
+ is started. This method is called after the combined step camera overlay has been created.
+ This is appropriate place to make appropriate UI changes, e.g. show messages about started step/side,
+ show splash screen, etc.
+
+
Parameters:
+
isCameraPreviewStarted - whether camera preview has been already started or not. If the
+ camera preview has not been started yet (value is false),
+ method onCameraPreviewStarted() will be called when/if
+ the camera is successfully started.
Callback method that is called when combined recognizer is set to scan second side
+ (only if second side exists) and recognition is started. This method is called after the combined
+ step camera overlay has been created. This is appropriate place to make appropriate UI changes,
+ e.g. show messages about started step/side, show splash screen, etc.
+
+
Parameters:
+
isCameraPreviewStarted - whether camera preview has been already started or not. If the
+ camera preview has not been started yet (value is false),
+ method onCameraPreviewStarted() will be called when/if
+ the camera is successfully started.
+
combinedFirstSideResult - recognition result for the first side of the combined document
+ that has been scanned
Callback that is called during recognition process when/if the glare is detected on the
+ scanned document. This is appropriate place to perform UI updates and inform user that glare is
+ detected (or that glare is not present any more).
Creates configuration for the additional verification step that can be performed in the verification
+ flow in addition to the combined recognizer step. This method is called from the
+ onCreate(Bundle) after the
+ readAdditionalIntentExtras(Bundle) has been called.
+
+
Returns:
+
configuration for the additional verification step that can be performed in the verification
+ flow in addition to the combined recognizer step, or null if the additional
+ verification step is not needed. In that case additional step will not be performed.
Scan activity designed for scanning documents by using combined recognizers
+ (CombinedRecognizerSettings). Scanning is performed
+ in multiple steps, in each step single side/part of the document is being scanned.
Creates configuration for the additional verification step that can be performed in the verification
+ flow in addition to the combined recognizer step.
Called just after camera preview has successfully
+ started and no exceptions occurred. When this method is called, it means
+ that from now on, frames will arrive and preview will be shown.
This method should be implemented to obtain activity's intent extras that are
+ relevant to the derived activity. Method is called in BaseVerificationFlowActivity.onCreate(Bundle).
Creates and returns camera overlay view for the combined verification step. This is
+ appropriate place where references to all camera overlay subviews, that must be
+ available later, should be obtained. This method is called after all intent extras
+ has been read (after the BaseVerificationFlowActivity.readAdditionalIntentExtras(Bundle)
+ hass been called).
Callback method that is called when combined recognizer is set to scan first side and recognition
+ is started. This method is called after the combined step camera overlay has been created.
+ This is appropriate place to make appropriate UI changes, e.g. show messages about started step/side,
+ show splash screen, etc.
isCameraPreviewStarted - whether camera preview has been already started or not. If the
+ camera preview has not been started yet (value is false),
+ method BaseVerificationFlowActivity.onCameraPreviewStarted() will be called when/if
+ the camera is successfully started.
Callback method that is called when combined recognizer is set to scan second side
+ (only if second side exists) and recognition is started. This method is called after the combined
+ step camera overlay has been created. This is appropriate place to make appropriate UI changes,
+ e.g. show messages about started step/side, show splash screen, etc.
isCameraPreviewStarted - whether camera preview has been already started or not. If the
+ camera preview has not been started yet (value is false),
+ method BaseVerificationFlowActivity.onCameraPreviewStarted() will be called when/if
+ the camera is successfully started.
+
combinedFirstSideResult - recognition result for the first side of the combined document
+ that has been scanned
Callback that is called during recognition process when/if the glare is detected on the
+ scanned document. This is appropriate place to perform UI updates and inform user that glare is
+ detected (or that glare is not present any more).
configuration for the additional verification step that can be performed in the verification
+ flow in addition to the combined recognizer step, or null if the additional
+ verification step is not needed. In that case additional step will not be performed.
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (LivenessAction c : LivenessAction.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
public static LivenessAction valueOf(java.lang.String name)
+
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
+
Returns:
+
the enum constant with the specified name
+
Throws:
+
java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
+
java.lang.NullPointerException - if the argument is null
Returns an array containing the constants of this enum type, in
+the order they are declared. This method may be used to iterate
+over the constants as follows:
+
+for (LivenessError c : LivenessError.values())
+ System.out.println(c);
+
+
+
Returns:
+
an array containing the constants of this enum type, in the order they are declared
public static LivenessError valueOf(java.lang.String name)
+
Returns the enum constant of this type with the specified name.
+The string must match exactly an identifier used to declare an
+enum constant in this type. (Extraneous whitespace characters are
+not permitted.)
+
+
Parameters:
+
name - the name of the enum constant to be returned.
+
Returns:
+
the enum constant with the specified name
+
Throws:
+
java.lang.IllegalArgumentException - if this enum type has no constant with the specified name
+
java.lang.NullPointerException - if the argument is null
Returns true if data from scanned parts/sides of the document match,
+ false otherwise. For example if date of expiry is scanned from the front and back side
+ of the document and values do not match, this method will return false. Result will
+ be only if scanned values for all fields that are compared are the same.
+
+
Returns:
+
true if data from scanned parts/sides of the document match,
+ false otherwise.
Returns true if both data on the front side of the document and on the back side of the document
- match, false otherwise. Date of birth, sex, document number and first and last name are being matched
+
isDocumentDataMatch
+
public boolean isDocumentDataMatch()
+
Returns true if both data on the front side of the document and on the back side of the document
+ match, false otherwise. Date of birth, sex, document number and first and last name are being matched
while all other data is being copied.
Returns true if both data on the front side of the document and on the back side of the document
- match, false otherwise. Only Address, issued by and date of issue is written only on back side,
+
isDocumentDataMatch
+
public boolean isDocumentDataMatch()
+
Returns true if both data on the front side of the document and on the back side of the document
+ match, false otherwise. Only Address, issued by and date of issue is written only on back side,
all other data elements are present on both sides and their values are matched.
Returns true if both data on the front side of the document and on the back side of the document
- match, false otherwise. Address, authority and personal number are written only on back side, while
+
isDocumentDataMatch
+
public boolean isDocumentDataMatch()
+
Returns true if both data on the front side of the document and on the back side of the document
+ match, false otherwise. Address, authority and personal number are written only on back side, while
date of issue, place of birth and nationality (full name of country) are written on front side,
all other data elements are present on both sides and their values are matched.