License Plate Plugin


New in version 3.17.

Examples Source Code

The source code of all example use cases of the License Plate Plugin can be found in the Android SDK Bundle

Plugin Description

The Anyline License Plate Plugin provides the functionality to scan license plates of different formats and countries.

For each scan result, the license plate number and the country (if present on the plate) are returned.

The description of all parameters can be found at Plugin > License Plate

How to implement the License Plate Plugin

This is a step by step guide on how to implement the License Plate Plugin in Android.

Get the License Plate Plugin in Java

Starting with Anyline 4, the ScanView is a generic type which should not be cast to each scan view type.

First add the Scan View to your xml-layout.

Add the License Plate ScanView to the layout
<!--
  ~ Anyline
  ~ activity_scan_license_plate.xml
  ~
  ~ Copyright (c) 2017 Anyline GmbH
  ~
  -->

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/main_layout"
    android:animateLayoutChanges="true">


    <io.anyline.view.ScanView
        android:id="@+id/scan_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

</RelativeLayout>

In the next step, go to your Java Activity code and get the view from the layout in onCreate() or onActivityCreated()

Get the Scan View
        // Get the view from the layout
        scanView = (ScanView) findViewById(R.id.scan_view);

Initialise and Configure Anyline

ScanViewPlugin

The ScanViewPlugin configuration holds the UI properties for cutout and visual feedback.

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

Initialize ScanViewPlugin

Together with your Anyline License Key Generation, you can now initialise LicensePateScanViewPlugin. The LicensePateScanViewPlugin will internally initialize the LicensePlateScanPlugin. In java, this should be called in onCreate() or onActivityCreated().

Initialize the ScanViewPlugin
	//init the scan view
	LicensePlateScanViewPlugin scanViewPlugin = new LicensePlateScanViewPlugin(getApplicationContext(), getString(R.string.anyline_license_key), licensePlateScanviewPluginConfig, "LICENSE_PLATE");

ScanView

Set the Base Configuration

The base configurations are holding the camera and the flash properties. You can set it the following way, also in onCreate() or onActivityCreated()

Set the Base Configuration(Camera and Flash configuration) and the View Configuration (Cutout and ScanView configuration)
	//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

A ScanView is holding a ScanViewPlugin, therefore a ScanViewPlugin has to be set to the ScanView.

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

The License Plate Result Listener

In the License Plate Plugin of Anyline SDK, you will be provided the final results via a ResultListener.

Changes in 4

The result listener changed in version 4.

With Anyline 4, all listeners are called ScanResultListener. In case of the Ocr Plugin, the listener is of type LicensePlateScanResult. This section describes the ScanResultListener callback in detail.

onResult

This is the main callback method for the License Plate Module. It is called once a valid result has been found.

The result is an Instance of ScanResultListener of type LicensePlateScanResult, which holds the detected license plate number, the detected country (if present on the plate), the confidence of the result, as well as a cutout image and the full image.

See LicensePlateResult in the Javadocs

onResult
	//add result listener
	scanViewPlugin.addScanResultListener(new ScanResultListener<LicensePlateScanResult>() {
		@Override
		public void onResult(LicensePlateScanResult result) {
			resultText.setText(result.getResult());
		}
	});
  • result
Type Description
LicensePlateResult The scanned license plate data and supplementary scan information
Parameter Type Description
getResult() String The license plate number with all whitespaces removed
getCountry() String The country detected from an EU badge (or similar badge) on the plate
getCutoutImage() AnylineImage An image of the license plate, cropped to the cutout
getFullImage() AnylineImage The full image the result was found on
getConfidence() Integer The confidence of the SDK in the detected result

<https://documentation.anyline.io/api/android/io/anyline/plugin

Enabling or disabling the reporting

The reporting of the (intermediate) results (including an image) helps us to improve the accuracy of the SDK and detect potential shortcomings.

However, you can easily turn the reporting off (onCreate() or onActivityCreated())

setReportingEnabled
        // disable the reporting if set to off in preferences
        scanView.setReportingEnabled(PreferenceManager.getDefaultSharedPreferences(this).getBoolean(SettingsFragment
                .KEY_PREF_REPORTING_ON, true));
        addLicensePlateResultView();

Reporting & License

Depending, on your license, the reporting may not be turned on or off.

Start Scanning

After everything is initialised, you can start the scanning process, by calling startScanning() on the scanView. It is advised to place this call in the onResume() lifecycle method of Android.

startScanning
    @Override
    protected void onResume() {
        super.onResume();
        startScanning();
    }
    private void startScanning() {
        // this must be called in onResume, or after a result to start the scanning again
        if (!scanView.getScanViewPlugin().isRunning()) {
            scanView.start();
        }
    }

Stop Scanning

To stop the scanning process, call stop() on the scanView.

To make sure the SDK is properly stopped upon leaving the Activity, make sure to place cancelScanning() and releaseCamera()/releaseCameraInBackground() in the onPause() lifecycle method of Android.

stop
    @Override
    protected void onPause() {
        super.onPause();

        scanView.stop();
        scanView.releaseCameraInBackground();
    }

Full Example Activity

LicensePlate Module Example
/*
 * Anyline
 * ScanLicensePlateActivity.java
 *
 * Copyright (c) 2017 Anyline GmbH
 *
 * Created by martin at 2017-10-09
 */

package io.anyline.examples.licenseplate;

import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.RelativeLayout;

import at.nineyards.anyline.camera.AnylineViewConfig;
import at.nineyards.anyline.modules.licenseplate.LicensePlateResult;
import at.nineyards.anyline.modules.licenseplate.LicensePlateResultListener;
import at.nineyards.anyline.modules.licenseplate.LicensePlateScanView;
import io.anyline.examples.R;
import io.anyline.examples.SettingsFragment;
import io.anyline.examples.licenseplate.result.LicensePlateResultView;

public class ScanLicensePlateActivity extends AppCompatActivity {

    private static final String TAG = ScanLicensePlateActivity.class.getSimpleName();
    protected ScanView scanView;
    private LicensePlateResultView licensePlateResultView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Set the flag to keep the screen on (otherwise the screen may go dark during scanning)
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_scan_license_plate);

        String license = getString(R.string.anyline_license_key);

        // Get the view from the layout
        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 scan view
	LicensePlateScanViewPlugin scanViewPlugin = new LicensePlateScanViewPlugin(getApplicationContext(), getString(R.string.anyline_license_key), 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(new ScanResultListener<LicensePlateScanResult>() {
		@Override
		public void onResult(LicensePlateScanResult result) {
			resultText.setText(result.getResult());
		}
	});

        // disable the reporting if set to off in preferences
        scanView.setReportingEnabled(PreferenceManager.getDefaultSharedPreferences(this).getBoolean(SettingsFragment
                .KEY_PREF_REPORTING_ON, true));
        addLicensePlateResultView();
    }

    private void addLicensePlateResultView() {
        RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.license_plate_main_layout);

        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
        params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);

        licensePlateResultView = new LicensePlateResultView(this);
        licensePlateResultView.setVisibility(View.INVISIBLE);

        mainLayout.addView(licensePlateResultView, params);
        licensePlateResultView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                clearAndHideLicensePlateResultView();
                startScanning();
            }
        });
    }

    private void clearAndHideLicensePlateResultView() {
        licensePlateResultView.setCountry("");
        licensePlateResultView.setLicensePlate("");
        licensePlateResultView.setVisibility(View.INVISIBLE);
    }

    private void startScanning() {
        // this must be called in onResume, or after a result to start the scanning again
        if (!scanView.getScanViewPlugin().isRunning()) {
            scanView.start();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        startScanning();
    }

    @Override
    protected void onPause() {
        super.onPause();

        scanView.stop();
        scanView.releaseCameraInBackground();
    }

    @Override
    public void onBackPressed() {
        if (licensePlateResultView.getVisibility() == View.VISIBLE) {
            clearAndHideLicensePlateResultView();
            startScanning();
        } else {
            super.onBackPressed();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}