com.os.mobile.blinkid.BlinkIdPlugin.java Source code

Java tutorial

Introduction

Here is the source code for com.os.mobile.blinkid.BlinkIdPlugin.java

Source

package com.os.mobile.blinkid;

import android.content.Intent;
import android.os.Parcelable;
import android.widget.Toast;

import com.microblink.activity.ScanActivity;
import com.microblink.activity.ScanCard;
import com.microblink.activity.ShowOcrResultMode;
import com.microblink.recognizers.BaseRecognitionResult;
import com.microblink.recognizers.ocr.mrtd.MRTDRecognitionResult;
import com.microblink.recognizers.ocr.mrtd.MRTDRecognizerSettings;
import com.microblink.recognizers.settings.GenericRecognizerSettings;
import com.microblink.recognizers.settings.RecognizerSettings;
import com.microblink.util.Log;
import com.microblink.util.RecognizerCompatibility;
import com.microblink.util.RecognizerCompatibilityStatus;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Created by vitoroliveira on 06/11/15.
 */
public class BlinkIdPlugin extends CordovaPlugin {

    /* Request Code received on Activity Result  */
    public static final int MY_PHOTOPAY_REQUEST_CODE = 0x101;

    /* Cordova Plugin - Action to Read Cards */
    public static final String ACTION_READ_CARD_ID = "readCardId";

    private CallbackContext callbackContext;

    @Override
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        this.callbackContext = callbackContext;
        if (ACTION_READ_CARD_ID.equals(action)) {
            readCardId(callbackContext, args);
        }
        return true;
    }

    /**
     * Method to launch Card ID Reader
     *
     * @param callbackContext
     * @param args
     * @throws JSONException
     */
    private void readCardId(CallbackContext callbackContext, JSONArray args) throws JSONException {

        // check if BlinkID is supported on the device
        RecognizerCompatibilityStatus supportStatus = RecognizerCompatibility
                .getRecognizerCompatibilityStatus(cordova.getActivity());
        if (supportStatus != RecognizerCompatibilityStatus.RECOGNIZER_SUPPORTED) {
            callbackContext.error("BlinkID is not supported! Reason: " + supportStatus.name());
            return;
        }

        if (args != null) {
            /* Get the license key from cordova */
            String licenseKey = args.getString(0);

            if (licenseKey == null) {
                callbackContext.error("Is mandatory a license key to use the this plugin");
                return;
            }

            /* Launch the Activity to read the card id */
            this.cordova.startActivityForResult((CordovaPlugin) this, buildMrtdIntent(licenseKey),
                    MY_PHOTOPAY_REQUEST_CODE);

        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        if (requestCode == MY_PHOTOPAY_REQUEST_CODE) {

            // make sure PhotoPay activity returned result
            if (resultCode == ScanActivity.RESULT_OK && intent != null) {

                // depending on settings, we may have multiple scan results.
                // we first need to obtain list of recognition results
                Parcelable[] multiData = intent
                        .getParcelableArrayExtra(ScanActivity.EXTRAS_RECOGNITION_RESULT_LIST);

                if (multiData != null) {

                    Log.i(this, "Data count: " + multiData.length);
                    int i = 1;

                    for (Parcelable parc : multiData) {
                        Log.i(this, "Data #" + Integer.valueOf(i++).toString());

                        // each element in multiData is actually class derived from BaseRecognitionResult
                        // so it is always safe to cast
                        // Moreover, as is specified in README file, you can use instanceof operator
                        // to determine the actual type of result. Here we will simply pass
                        // the result list to ResultActivity and there we will explain
                        // how to retrieve data from result.

                        BaseRecognitionResult rd = (BaseRecognitionResult) parc;

                        /* Create JSON to send as a result to the call of the Plugin  */
                        if (rd != null) {
                            JSONObject jsonObject = new JSONObject();
                            try {
                                jsonObject.put("isParsed", ((MRTDRecognitionResult) rd).isMRZParsed());
                                jsonObject.put("issuer", ((MRTDRecognitionResult) rd).getIssuer());
                                jsonObject.put("documentNumber", ((MRTDRecognitionResult) rd).getDocumentNumber());
                                jsonObject.put("documentCode", ((MRTDRecognitionResult) rd).getDocumentCode());
                                jsonObject.put("dateOfExpiry", ((MRTDRecognitionResult) rd).getDateOfExpiry());
                                jsonObject.put("primaryId", ((MRTDRecognitionResult) rd).getPrimaryId());
                                jsonObject.put("secondaryId", ((MRTDRecognitionResult) rd).getSecondaryId());
                                jsonObject.put("dateOfBirth", ((MRTDRecognitionResult) rd).getDateOfBirth());
                                jsonObject.put("nationality", ((MRTDRecognitionResult) rd).getNationality());
                                jsonObject.put("sex", ((MRTDRecognitionResult) rd).getSex());
                                jsonObject.put("opt1", ((MRTDRecognitionResult) rd).getOpt1());
                                jsonObject.put("opt2", ((MRTDRecognitionResult) rd).getOpt2());
                                jsonObject.put("mrzText", ((MRTDRecognitionResult) rd).getMRZText());

                                this.callbackContext.success(jsonObject.toString());
                                // break;
                            } catch (JSONException e) {
                                Log.e("MicroBlink", e.toString());
                            }
                        }

                    }
                } else {
                    Log.e(this, "Unable to retrieve list of recognition data!");
                }

                // set intent's component to ResultActivity and pass its contents
                // to ResultActivity. ResultActivity will show how to extract
                // data from result.

                //   intent.setComponent(new ComponentName(this, ResultActivity.class));
                //   startActivity(intent);
            } else {
                // if PhotoPay activity did not return result, user has probably
                // pressed Back button and cancelled scanning
                Toast.makeText(cordova.getActivity(), "Scan cancelled!", Toast.LENGTH_SHORT).show();
            }
        }
    }

    private Intent buildMrtdIntent(String licenseKey) {
        // prepare settings for Machine Readable Travel Document (MRTD) recognizer
        MRTDRecognizerSettings mrtd = new MRTDRecognizerSettings();

        // build a scan intent by adding intent extras common to all other recognizers
        // when scanning ID documents, we will use ScanCard activity which has more suitable UI for scanning ID documents
        //   return new ListElement("ID document", buildIntent(new RecognizerSettings[]{mrtd}, ScanCard.class, null));

        return buildIntent(new RecognizerSettings[] { mrtd }, ScanCard.class, null, licenseKey);
    }

    /**
     * This method will build scan intent for PhotoPay. Method needs array of recognizer settings
     * to know which recognizers to enable, activity to which intent will be sent and optionally
     * an intent for HelpActivity that will be used if user taps the Help button on scan activity.
     */
    private Intent buildIntent(RecognizerSettings[] settArray, Class<?> target, Intent helpIntent,
            String licenseKey) {
        // first create intent for given activity
        final Intent intent = new Intent(cordova.getActivity(), target);

        // optionally, if you want the beep sound to be played after a scan
        // add a sound resource id as EXTRAS_BEEP_RESOURCE extra
        //TODO
        //  intent.putExtra(ScanActivity.EXTRAS_BEEP_RESOURCE, R.raw.beep);

        // if we have help intent, we can pass it to scan activity so it can invoke
        // it if user taps the help button. If we do not set the help intent,
        // scan activity will hide the help button.
        if (helpIntent != null) {
            intent.putExtra(ScanActivity.EXTRAS_HELP_INTENT, helpIntent);
        }

        // now add array with recognizer settings so that scan activity will know
        // what do you want to scan. Setting recognizer settings array is mandatory.
        intent.putExtra(ScanActivity.EXTRAS_RECOGNIZER_SETTINGS_ARRAY, settArray);

        // generic recognizer settings are optional and give you the ability to
        // define settings that are valid for all recognizers.
        GenericRecognizerSettings genSett = new GenericRecognizerSettings();

        // with setNumMsBeforeTimeout you can define number of miliseconds that must pass
        // after first partial scan result has arrived before scan activity triggers a timeout.
        // Timeout is good for preventing infinitely long scanning experience when user attempts
        // to scan damaged or unsupported slip. After timeout, scan activity will return only
        // data that was read successfully. This might be incomplete data.
        genSett.setNumMsBeforeTimeout(10000);

        // If you add more recognizers to recognizer settings array, you can choose whether you
        // want to have the ability to obtain multiple scan results from same video frame. For example,
        // if both payment slip and payment barcode are visible on a single frame, by setting
        // setAllowMultipleScanResultsOnSingleImage to true you can obtain both scan results
        // from barcode and slip. If this is false (default), you will get the first valid result
        // (i.e. first result that contains all required data). Having this option turned off
        // creates better and faster user experience.
        //        genSett.setAllowMultipleScanResultsOnSingleImage(true);

        // once generic settings are prepared, you can set them with EXTRAS_GENERIC_SETTINGS extra
        // Setting generic settings is optional.
        intent.putExtra(ScanActivity.EXTRAS_GENERIC_SETTINGS, genSett);

        // In order for scanning to work, you must enter a valid licence key. Without licence key,
        // scanning will not work. Licence key is bound the the package name of your app, so when
        // obtaining your licence key from Microblink make sure you give us the correct package name
        // of your app.
        // Licence key also defines which recognizers are enabled and which are not. Since the licence
        // key validation is performed on image processing thread in native code, all enabled recognizers
        // that are disallowed by licence key will be turned off without any error and information
        // about turning them off will be logged to ADB logcat.
        intent.putExtra(ScanActivity.EXTRAS_LICENSE_KEY, licenseKey);

        // If you want, you can disable drawing of OCR results on scan activity. Drawing OCR results can be visually
        // appealing and might entertain the user while waiting for scan to complete, but might introduce a small
        // performance penalty.
        // intent.putExtra(ScanActivity.EXTRAS_SHOW_OCR_RESULT, false);

        // If you want you can have scan activity display the focus rectangle whenever camera
        // attempts to focus, similarly to various camera app's touch to focus effect.
        // By default this is off, and you can turn this on by setting EXTRAS_SHOW_FOCUS_RECTANGLE
        // extra to true.
        intent.putExtra(ScanActivity.EXTRAS_SHOW_FOCUS_RECTANGLE, true);

        // If you want, you can enable the pinch to zoom feature of scan activity.
        // By enabling this you allow the user to use the pinch gesture to zoom the camera.
        // By default this is off and can be enabled by setting EXTRAS_ALLOW_PINCH_TO_ZOOM extra to true.
        intent.putExtra(ScanActivity.EXTRAS_ALLOW_PINCH_TO_ZOOM, true);

        // Enable showing of OCR results as animated dots. This does not have effect if non-OCR recognizer like
        // barcode recognizer is active.
        intent.putExtra(ScanActivity.EXTRAS_SHOW_OCR_RESULT_MODE, (Parcelable) ShowOcrResultMode.ANIMATED_DOTS);

        return intent;
    }
}