Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »


New and Improved!

Our Engineers have meticulously rewritten our Anyline Android SDK from the ground up with Version 43. Here you will experience a wide array of game changing features, performance enhancements and overall ease-of-use improvements.

This article covers a summary of what v43 offers compared to our previous versions, a video guide on how to upgrade from any previous version of our Anyline Android SDK to v43, links to the documentation, and a glossary of some of the terminology associated with our SDK.


Before and After

Previous versions of Anyline SDK

Version 43 of Anyline SDK


Changes in Version 43

Anyline Android SDK previous versions

 Initializing the plugin

Implementing a scan module requires the following classes to be initialized:

  1. a scan view

  2. a scan view plugin

  3. a scan plugin

the second and third class specify the scanning module you have selected.
For example:
OCR → OcrScanViewPlugin AnylineOcrConfig

In Android, the ScanPlugin is initialized internally (in the SDK) once the ScanViewPlugin is initialized.

Example:

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This must be called before doing anything Anyline-related!
        // Try/Catch this to check whether or not your license key is valid!
        try {
            AnylineSDK.init(getString(R.string.anyline_license_key), this);
        } catch (LicenseException e) {
            // handle exception
        }

        // Get the view from the layout
        setContentView(R.layout.activity_anyline_scan_view);

        // initialise the scanView
        scanView = (ScanView) findViewById(R.id.scan_view);

        //init the scanViewPlugin configuration which hold the scan view ui configuration (cutoutConfig and ScanFeedbackConfig)
        ScanViewPluginConfig licensePlateScanViewPluginConfig = new ScanViewPluginConfig(getApplicationContext(), "license_plate_view_config.json");

        //init the scanViewPlugin
        LicensePlateScanViewPlugin scanViewPlugin = new LicensePlateScanViewPlugin(getApplicationContext(), licensePlateScanViewPluginConfig, "LICENSE_PLATE");

        //init the base scanViewConfig which hold camera and flash configuration
        BaseScanViewConfig licensePlateBaseScanViewConfig = new BaseScanViewConfig(getApplicationContext(), "license_plate_view_config.json");

        //set the base scanViewConfig to the ScanView
        scanView.setScanViewConfig(licensePlateBaseScanViewConfig);

        //set the scanViewPlugin to the ScanView
        scanView.setScanViewPlugin(scanViewPlugin);

        //add result listener
        scanViewPlugin.addScanResultListener((ScanResultListener<LicensePlateScanResult>) result -> Log.d("Main Activity", "The scanned result is: " + result.getResult()));
    }
 Composite plugins
  • cancelOnResult is a required field and is either true or false. id should be a valid keyword string and is a required field. viewPlugins is an array where the viewPlugin JSON bodies of each child plugin is listed.

Example:

{
  "serialViewPluginComposite": {
      "id": "CATTLE_DL_VIN",
      "cancelOnResult": true,
      "viewPlugins": [
          {
              "viewPlugin": {
                  "plugin": {
                      "id": "CATTLE_TAG",
                      "ocrPlugin": {
                          "cattleTagConfig": {}
                      }
                  },
                  ...
              }
          },
          {
              "viewPlugin": {
                  "plugin": {
                      "id": "DRIVING_LICENSE",
                      "idPlugin": {
                              ...
                      }
                  },
                  ...
          }
      ]
  }
}

 JSON Config File Structure
  • Previous config files are parsed with the top-level keys identified as the objects they represent.

  • For example: The JSON configuration for the camera on a device is under the key identifier, camera ; the JSON configuration for the flash of the camera is under the key identifier, flash, and so on.

  • The cancelOnResult method is found inside the viewPlugin

Example:

{
  "viewPlugin": {
      "plugin": {
          "id": "LICENSEPLATE_PLUGIN",
          "licensePlatePlugin": {
              "scanMode": "AUTO"
        }
      },
      "cutoutConfig" : {
          "style": "rect",
          "maxWidthPercent": "70%",
          "maxHeightPercent": "70%",
          "alignment": "top_half",
          "ratioFromSize": {
              "width": 3,
              "height": 1
          },
          "outerColor": "000000",
          "outerAlpha": 0.3,
          "strokeWidth": 1,
          "strokeColor": "FFFFFF",
          "cornerRadius": 2,
          "feedbackStrokeColor": "0099FF"
      },
      "scanFeedback": {
          "animation": "none",
          "animationDuration" : 250,
          "style": "rect",
          "strokeWidth": 2,
          "strokeColor": "0099FF",
          "beepOnResult": true,
          "vibrateOnResult": true,
          "blinkAnimationOnResult": true
      },
      "cancelOnResult" : true
  }
}
 Listeners

The ScanPlugin, ScanViewPlugin, and ScanView Listeners all require the implementation different listeners for specific modules.

Some module specific delegate examples are OcrScanResult, LicensePlateScanResult, and so on.

//add result listener
scanViewPlugin.addScanResultListener((ScanResultListener<LicensePlateScanResult>) result -> Log.d("Main Activity", "The scanned result is: " + result.getResult()));
 Result Type

ScanResult does not support strongly-typed result types of modules and are not defined as part of the result object.

//add result listener
scanViewPlugin.addScanResultListener((ScanResultListener<LicensePlateScanResult>) result -> Log.d("Main Activity", "The scanned result is: " + result.getResult()));

Anyline Android SDK v43

 Initializing the plugin
  • Only the ScanView and ScanViewPlugin need to be initialized, with an appropriate ScanPlugin being generated by the ScanViewPlugin when the configuration for the target module is passed.

  • Furthermore, the scan view config is now initialized together with its scan view plugin.

Example:

private lateinit var scanView: ScanView
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // This must be called before doing anything Anyline-related!    
    // Try/Catch this to check whether or not your license key is valid!    
    try {
        AnylineSdk.init(getString(R.string.anyline_license_key), this)
    } catch (e: LicenseException) {
      // handle exception    
    } 

    // Get the view from the layout    
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(R.layout.scan_view)

    // initialise the scanView together with the scanViewPlugin    
    scanView = findViewById<View>(R.id.scan_view) as ScanView

    scanView.init("license_plate_config.json")

    // once the scan view is initialized, we can hook on the plugin events    
    // sets an event onto the scanViewPlugin and calls result from onResult onto the event    
    scanView.scanViewPlugin.resultReceived = Event { scanResult ->        
        Log.d(
            "Main Activity",            
            "The scanned result is: " + scanResult.pluginResult.licensePlateResult.plateText        
        )
    }
}
 Composite plugins
  • The root node’s JSON property is named viewPluginCompositeConfig.

  • An additional property named PROCESSING_MODE needs to be set to either sequential or parallel. id should be a valid keyword string and is a required field. viewPlugins is an array where the viewPluginConfig JSON bodies of each child plugin is listed.

  • The ViewPluginComposite class, which replaces the old plugin composite type AbstractScanViewPluginComposite, is now (along with ScanViewPlugin) a concrete implementation of the ViewPluginBase protocol. This class introduces a new way to subscribe to the multiple results, that a composite can return.

Example:

{
    "viewPluginCompositeConfig": {
        "id": "parallel_composite_scanning",
        "processingMode": <PROCESSING_MODE>,
        "viewPlugins": [
            {
                "viewPluginConfig": {
                    "pluginConfig": {
                        "id": "com.anyline.configs.plugin.lp",
                        "licensePlateConfig": {
                        "scanMode": "auto"
                        }
                    },
                    ...
                },
                "viewPluginConfig": {
                    ...
                },
                ...
            }
        ]
    }
}
 JSON Config File Structure
  • New config files are parsed with the top-level keys identified both as the objects they represent and with the key name “config”.

  • For example: The JSON configuration for the camera on a device is under the key identifier, cameraConfig ; the JSON configuration for the flash of the camera is under the key identifier, flashConfig, and so on.

  • The cancelOnResult method is found inside the pluginConfig.

Example:

{
  "cameraConfig": {
    "captureResolution": "1080p",
    "pictureResolution": "1080p"
  },
  "flashConfig": {
    "mode": "auto",
    "alignment": "top_left"
  },
  "viewPluginConfig": {
    "pluginConfig": {
      "id": "LPT",
      "licensePlateConfig": {
        "scanMode": "auto"
      },
      "cancelOnResult": true
    },
    "cutoutConfig": {
      "animation": "fade",
      "maxWidthPercent": "100%",
      "maxHeightPercent": "100%",
      "width": 750,
      "alignment": "top_half",
      "ratioFromSize": {
        "width": 3,
        "height": 1
      },
      "offset": {
        "x": 0,
        "y": 0
      },
      "cropOffset": {
        "x": 0,
        "y": 0
      },
      "cropPadding": {
        "x": 0,
        "y": 0
      },
      "cornerRadius": 4,
      "strokeColor": "0099ff",
      "strokeWidth": 2,
      "outerColor": "000000",
      "feedbackStrokeColor": "0099FF",
      "outerAlpha": 0.3
    },
    "scanFeedbackConfig": {
      "style": "rect",
      "visualFeedbackRedrawTimeout": 100,
      "strokeWidth": 2,
      "strokeColor": "0099FF",
      "fillColor": "220099FF",
      "beepOnResult": true,
      "vibrateOnResult": true,
      "blinkAnimationOnResult": true
    }
  }
}
 Listeners
  • The ScanPlugin, ScanViewPlugin, and ScanView listeners* have been altered, with the removal of implementing different module listeners. This has resulted in a more focused and efficient interface with more time-saving features.

  • module specific delegates such as OcrScanResult, LicensePlateScanResult, etc., are now removed and replaced by a single class: scanResult.

Example:

// once the scan view is initialized, we can hook on the plugin events    
// sets an event onto the scanViewPlugin and calls result from onResult onto the event    
scanView.scanViewPlugin.resultReceived = Event { scanResult ->        
      Log.d(
          "Main Activity",            
          "The scanned result is: " + scanResult.pluginResult.licensePlateResult.plateText        
      )
}
 Result Type

scanResult now supports strongly-typed result types of modules and are defined as part of the result object.

This means that for any module you are scanning (for example, OCR), then the module result (in this case, ocrResult) will be a non-null property where you will be able to find the result.

Example:

scanResult.pluginResult.licensePlateResult.plateText 


Upgrading to v43

To watch the video tutorial, please click here


Other Additions

  • Added PluginResult for describing result data

    • Added a type of plugin result for each scanning capability

  • [Tire] Added tire size specification fields to the result

  • [Barcode] Added AAMVA parsing for PDF417 codes on driving licenses

  • [ID] Restructured ID results in a way that every field can contain date- & multi-language information


Links to Documentation

f you require any further information or details on our v43 upgrade for the Anyline Android SDK,
please click here to see our documentation page: http://anyline.com/android-sdk-version43.0.0


Glossary

Please Note

*Listener - Refers to the class that adheres to an interface and implements methods contained within the interface

*Composite Plugin - Running a composite plugin either sequentially or simultaneously puts more than one discrete plugin to work. There are two modes which one can use:

  • sequential mode: for example, your workflow requires you to scan a license plate, and then a VIN. This is almost like running two separate scan plugins one after another, but with a composite you get the combined result of the two when you finish scanning both.

  • parallel mode: you are running two or more plugins simultaneously. (For example an ID card with a PDF417 barcode in it). You get the chance to scan both, and again the results are presented when you are done.

  • No labels