UNPKG

cordova-plugin-pdf417

Version:

A small and powerful PDF417 barcode scanning library

662 lines (510 loc) 120 kB
# _PDF417.mobi_ SDK for Android [![Build Status](https://travis-ci.org/PDF417/pdf417-android.svg?branch=master)](https://travis-ci.org/PDF417/pdf417-android) _PDF417.mobi_ SDK for Android is SDK that enables you to perform scans of various barcodes in your app. You can simply integrate the SDK into your app by following the instructions below and your app will be able to benefit the scanning feature for following barcode standards: * [PDF417 barcode](https://en.wikipedia.org/wiki/PDF417) * [QR code](https://en.wikipedia.org/wiki/QR_code) * [Code 128](https://en.wikipedia.org/wiki/Code_128) * [Code 38](https://en.wikipedia.org/wiki/Code_39) * [EAN 13](https://en.wikipedia.org/wiki/International_Article_Number_(EAN)) * [EAN 8](https://en.wikipedia.org/wiki/EAN-8) * [UPC A](https://en.wikipedia.org/wiki/Universal_Product_Code) * [UPC E](https://en.wikipedia.org/wiki/Universal_Product_Code) * [ITF](https://en.wikipedia.org/wiki/Interleaved_2_of_5) * [Data Matrix](https://en.wikipedia.org/wiki/Data_Matrix) * [Aztec](https://en.wikipedia.org/wiki/Aztec_Code) Using _PDF417.mobi_ in your app requires a valid license key. You can obtain a trial license key by registering to [Microblink dashboard](https://microblink.com/login). After registering, you will be able to generate a license key for your app. License key is bound to [package name](http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename) of your app, so please make sure you enter the correct package name when asked. See below for more information about how to integrate _PDF417.mobi_ SDK into your app and also check latest [Release notes](Release notes.md). # Table of contents * [Android _PDF417.mobi_ integration instructions](#intro) * [Quick Start](#quickStart) * [Quick start with demo app](#quickDemo) * [Integrating _PDF417.mobi_ into your project using Maven](#mavenIntegration) * [Android studio integration instructions](#quickIntegration) * [Eclipse integration instructions](#eclipseIntegration) * [Performing your first scan](#quickScan) * [Advanced _PDF417.mobi_ integration instructions](#advancedIntegration) * [Checking if _PDF417.mobi_ is supported](#supportCheck) * [Customization of `Pdf417ScanActivity` activity](#scanActivityCustomization) * [Embedding `RecognizerView` into custom scan activity](#recognizerView) * [`RecognizerView` reference](#recognizerViewReference) * [Using direct API for recognition of Android Bitmaps](#directAPI) * [Understanding DirectAPI's state machine](#directAPIStateMachine) * [Using DirectAPI while RecognizerView is active](#directAPIWithRecognizer) * [Obtaining various metadata with _MetadataListener_](#metadataListener) * [Using ImageListener to obtain images that are being processed](#imageListener) * [Recognition settings and results](#recognitionSettingsAndResults) * [[Recognition settings](https://pdf417.github.io/pdf417-android/com/microblink/recognizers/settings/RecognitionSettings.html)](#recognitionSettings) * [Scanning PDF417 barcodes](#pdf417Recognizer) * [Scanning one dimensional barcodes with _PDF417.mobi_'s implementation](#custom1DBarDecoder) * [Scanning barcodes with ZXing implementation](#zxing) * [Translation and localization](#translation) * [Embedding _PDF417.mobi_ inside another SDK](#embedAAR) * [_PDF417.mobi_ licensing model](#licensingModel) * [Ensuring the final app gets all resources required by _PDF417.mobi_](#sdkIntegrationIntoApp) * [Processor architecture considerations](#archConsider) * [Reducing the final size of your app](#reduceSize) * [Combining _PDF417.mobi_ with other native libraries](#combineNativeLibraries) * [Troubleshooting](#troubleshoot) * [Integration problems](#integrationTroubleshoot) * [SDK problems](#sdkTroubleshoot) * [Frequently asked questions and known problems](#faq) * [Additional info](#info) # <a name="intro"></a> Android _PDF417.mobi_ integration instructions The package contains Android Archive (AAR) that contains everything you need to use _PDF417.mobi_ library. Besides AAR, package also contains a demo project that contains following modules: - _Pdf417MobiDemo_ shows how to use simple Intent-based API to scan single barcode. - _Pdf417MobiDemoCustomUI_ demonstrates advanced integration within custom scan activity. - _Pdf417MobiDirectAPIDemo_ demonstrates how to perform scanning of [Android Bitmaps](https://developer.android.com/reference/android/graphics/Bitmap.html) Source code of all demo apps is given to you to show you how to perform integration of _PDF417.mobi_ SDK into your app. You can use this source code and all resources as you wish. You can use demo apps as basis for creating your own app, or you can copy/paste code and/or resources from demo apps into your app and use them as you wish without even asking us for permission. _PDF417.mobi_ is supported on Android SDK version 10 (Android 2.3.3) or later. The library contains one activity: `Pdf417ScanActivity`. It is responsible for camera control and recognition. 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). # <a name="quickStart"></a> Quick Start ## <a name="quickDemo"></a> Quick start with demo app 1. Open Android Studio. 2. In Quick Start dialog choose _Import project (Eclipse ADT, Gradle, etc.)_. 3. In File dialog select _Pdf417MobiDemo_ folder. 4. Wait for project to load. If Android studio asks you to reload project on startup, select `Yes`. ## <a name="mavenIntegration"></a> Integrating _PDF417.mobi_ into your project using Maven Maven repository for _PDF417.mobi_ SDK is: [http://maven.microblink.com](http://maven.microblink.com). If you do not want to perform integration via Maven, simply skip to [Android Studio integration instructions](#quickIntegration) or [Eclipse integration instructions](#eclipseIntegration). ### Using gradle or Android Studio In your `build.gradle` you first need to add _PDF417.mobi_ maven repository to repositories list: ``` repositories { maven { url 'http://maven.microblink.com' } } ``` After that, you just need to add _PDF417.mobi_ as a dependency to your application (make sure, `transitive` is set to true): ``` dependencies { compile('com.microblink:pdf417.mobi:6.1.0@aar') { transitive = true } } ``` If you plan to use ProGuard, add following lines to your `proguard-rules.pro`: ``` -keep class com.microblink.** { *; } -keepclassmembers class com.microblink.** { *; } -dontwarn android.hardware.** -dontwarn android.support.v4.** ``` #### Import Javadoc to Android Studio Current version of Android Studio will not automatically import javadoc from maven dependency, so you have you do that manually. To do that, follow these steps: 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 `pdf417.mobi-6.1.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 7. Enter following address: `https://pdf417.github.io/pdf417-android/` 8. Click `OK` ### Using android-maven-plugin [Android Maven Plugin](https://simpligility.github.io/android-maven-plugin/) v4.0.0 or newer is required. Open your `pom.xml` file and add these directives as appropriate: ```xml <repositories> <repository> <id>MicroblinkRepo</id> <url>http://maven.microblink.com</url> </repository> </repositories> <dependencies> <dependency> <groupId>com.microblink</groupId> <artifactId>pdf417.mobi</artifactId> <version>6.1.0</version> <type>aar</type> </dependency> </dependencies> ``` ## <a name="quickIntegration"></a> Android studio integration instructions 1. In Android Studio menu, click _File_, select _New_ and then select _Module_. 2. In new window, select _Import .JAR or .AAR Package_, and click _Next_. 3. In _File name_ field, enter the path to _LibPdf417Mobi.aar_ and click _Finish_. 4. In your app's `build.gradle`, add dependency to `LibPdf417Mobi` and appcompat-v7: ``` dependencies { compile project(':LibPdf417Mobi') compile "com.android.support:appcompat-v7:25.1.0" } ``` 5. If you plan to use ProGuard, add following lines to your `proguard-rules.pro`: ``` -keep class com.microblink.** { *; } -keepclassmembers class com.microblink.** { *; } -dontwarn android.hardware.** -dontwarn android.support.v4.** ``` ### <a name="androidStudio_importAAR_javadoc"></a> Import Javadoc to Android Studio 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 `LibPdf417Mobi-unspecified` entry, right click on it and select `Library Properties...` 4. A `Library Properties` pop-up window will appear 5. Click the `+` button in bottom left corner of the window 6. Window for choosing JAR file will appear 7. Find and select `LibPdf417Mobi-javadoc.jar` file which is located in root folder of the SDK distribution 8. Click `OK` ## <a name="eclipseIntegration"></a> Eclipse integration instructions We do not provide Eclipse integration demo apps. We encourage you to use Android Studio. We also do not test integrating _PDF417.mobi_ with Eclipse. If you are having problems with _PDF417.mobi_, make sure you have tried integrating it with Android Studio prior contacting us. However, if you still want to use Eclipse, you will need to convert AAR archive to Eclipse library project format. You can do this by doing the following: 1. In Eclipse, create a new _Android library project_ in your workspace. 2. Clear the `src` and `res` folders. 3. Unzip the `LibPdf417Mobi.aar` file. You can rename it to zip and then unzip it using any tool. 4. Copy the `classes.jar` to `libs` folder of your Eclipse library project. If `libs` folder does not exist, create it. 5. Copy the contents of `jni` folder to `libs` folder of your Eclipse library project. 6. Replace the `res` folder on library project with the `res` folder of the `LibPdf417Mobi.aar` file. You’ve already created the project that contains almost everything you need. Now let’s see how to configure your project to reference this library project. 1. In the project you want to use the library (henceforth, "target project") add the library project as a dependency 2. Open the `AndroidManifest.xml` file inside `LibPdf417Mobi.aar` file and make sure to copy all permissions, features and activities to the `AndroidManifest.xml` file of the target project. 3. Copy the contents of `assets` folder from `LibPdf417Mobi.aar` into `assets` folder of target project. If `assets` folder in target project does not exist, create it. 4. Clean and Rebuild your target project 5. If you plan to use ProGuard, add same statements as in [Android studio guide](#quickIntegration) to your ProGuard configuration file. 6. Add appcompat-v7 library to your workspace and reference it by target project (modern ADT plugin for Eclipse does this automatically for all new android projects). ## <a name="quickScan"></a> Performing your first scan 1. You can start recognition process by starting `Pdf417ScanActivity` activity with Intent initialized in the following way: ```java // Intent for Pdf417ScanActivity Activity Intent intent = new Intent(this, Pdf417ScanActivity.class); // set your licence key // obtain your licence key at http://microblink.com/login or // contact us at http://help.microblink.com intent.putExtra(Pdf417ScanActivity.EXTRAS_LICENSE_KEY, "Add your licence key here"); RecognitionSettings settings = new RecognitionSettings(); // setup array of recognition settings (described in chapter "Recognition // settings and results") settings.setRecognizerSettingsArray(setupSettingsArray()); intent.putExtra(Pdf417ScanActivity.EXTRAS_RECOGNITION_SETTINGS, settings); // Starting Activity startActivityForResult(intent, MY_REQUEST_CODE); ``` 2. After `Pdf417ScanActivity` 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 == Pdf417ScanActivity.RESULT_OK && data != null) { // perform processing of the data here // for example, obtain parcelable recognition result Bundle extras = data.getExtras(); RecognitionResults result = data.getParcelableExtra(Pdf417ScanActivity.EXTRAS_RECOGNITION_RESULTS); // get array of recognition results BaseRecognitionResult[] resultArray = result.getRecognitionResults(); // Each element in resultArray inherits BaseRecognitionResult class and // represents the scan result of one of activated recognizers that have // been set up. More information about this can be found in // "Recognition settings and results" chapter // Or, you can pass the intent to another activity data.setComponent(new ComponentName(this, ResultActivity.class)); startActivity(data); } } } ``` For more information about defining recognition settings and obtaining scan results see [Recognition settings and results](#recognitionSettingsAndResults). # <a name="advancedIntegration"></a> Advanced _PDF417.mobi_ integration instructions This section will cover more advanced details in _PDF417.mobi_ integration. First part will discuss the methods for checking whether _PDF417.mobi_ is supported on current device. Second part will cover the possible customization of builtin `Pdf417ScanActivity` activity, third part will describe how to embed `RecognizerView` into your activity and fourth part will describe how to use direct API to recognize directly android bitmaps without the need of camera. ## <a name="supportCheck"></a> Checking if _PDF417.mobi_ is supported ### _PDF417.mobi_ requirements Even before starting the scan activity, you should check if _PDF417.mobi_ is supported on current device. In order to be supported, device needs to have camera. Android 2.3 is the minimum android version on which _PDF417.mobi_ is supported. For best performance and compatibility, we recommend Android 5.0 or newer. Camera video preview resolution also matters. In order to perform successful scans, camera preview resolution cannot be too low. _PDF417.mobi_ requires minimum 320p camera preview resolution in order to perform scan. It must be noted that camera preview resolution is not the same as the video record resolution, although on most devices those are the same. However, there are some devices that allow recording of HD video (720p resolution), but do not allow high enough camera preview resolution (for example, [Sony Xperia Go](http://www.gsmarena.com/sony_xperia_go-4782.php) supports video record resolution at 720p, but camera preview resolution is only 320p - _PDF417.mobi_ does not work on that device). _PDF417.mobi_ is native application, written in C++ and available for multiple platforms. Because of this, _PDF417.mobi_ cannot work on devices that have obscure hardware architectures. We have compiled _PDF417.mobi_ native code only for most popular Android [ABIs](https://en.wikipedia.org/wiki/Application_binary_interface). See [Processor architecture considerations](#archConsider) for more information about native libraries in _PDF417.mobi_ and instructions how to disable certain architectures in order to reduce the size of final app. ### Checking for _PDF417.mobi_ support in your app To check whether the _PDF417.mobi_ is supported on the device, you can do it in the following way: ```java // check if PDF417.mobi is supported on the device RecognizerCompatibilityStatus status = RecognizerCompatibility.getRecognizerCompatibilityStatus(this); if(status == RecognizerCompatibilityStatus.RECOGNIZER_SUPPORTED) { Toast.makeText(this, "PDF417.mobi is supported!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(this, "PDF417.mobi is not supported! Reason: " + status.name(), Toast.LENGTH_LONG).show(); } ``` However, some recognizers require camera with autofocus. If you try to start recognition with those recognizers on a device that does not have camera with autofocus, you will get an error. To prevent that, when you prepare the array with recognition settings (see [Recognition settings and results](#recognitionSettingsAndResults) for settings reference), you can easily filter out all settings that require autofocus from array using the following code snippet: ```java // setup array of recognition settings (described in chapter "Recognition // settings and results") RecognizerSettings[] settArray = setupSettingsArray(); if(!RecognizerCompatibility.cameraHasAutofocus(CameraType.CAMERA_BACKFACE, this)) { setarr = RecognizerSettingsUtils.filterOutRecognizersThatRequireAutofocus(setarr); } ``` ## <a name="scanActivityCustomization"></a> Customization of `Pdf417ScanActivity` activity ### `Pdf417ScanActivity` intent extras This section will discuss possible parameters that can be sent over `Intent` for `Pdf417ScanActivity` activity that can customize default behaviour. There are several intent extras that can be sent to `Pdf417ScanActivity` actitivy: * <a name="intent_EXTRAS_CAMERA_TYPE" href="#intent_EXTRAS_CAMERA_TYPE">#</a> **`Pdf417ScanActivity.EXTRAS_CAMERA_TYPE`** - with this extra you can define which camera on device will be used. To set the extra to intent, use the following code snippet: ```java intent.putExtra(Pdf417ScanActivity.EXTRAS_CAMERA_TYPE, (Parcelable)CameraType.CAMERA_FRONTFACE); ``` * <a name="intent_EXTRAS_CAMERA_ASPECT_MODE" href="#intent_EXTRAS_CAMERA_ASPECT_MODE">#</a> **`Pdf417ScanActivity.EXTRAS_CAMERA_ASPECT_MODE`** - with this extra you can define which [camera aspect mode](https://pdf417.github.io/pdf417-android/com/microblink/view/CameraAspectMode.html) will be used. If set to `ASPECT_FIT` (default), then camera preview will be letterboxed inside available view space. If set to `ASPECT_FILL`, camera preview will be zoomed and cropped to use the entire view space. To set the extra to intent, use the following code snippet: ```java intent.putExtra(Pdf417ScanActivity.EXTRAS_CAMERA_ASPECT_MODE, (Parcelable)CameraAspectMode.ASPECT_FIT); ``` * <a name="intent_EXTRAS_RECOGNITION_SETTINGS" href="#intent_EXTRAS_RECOGNITION_SETTINGS">#</a> **`Pdf417ScanActivity.EXTRAS_RECOGNITION_SETTINGS`** - with this extra you can define settings that affect whole recognition process. This includes both array of recognizer settings and global recognition settings. More information about recognition settings can be found in chapter [Recognition settings and results](#recognitionSettingsAndResults). To set the extra to intent, use the following code snippet: ```java RecognitionSettings recognitionSettings = new RecognitionSettings(); // define additional settings; e.g set timeout to 10 seconds recognitionSettings.setNumMsBeforeTimeout(10000); // setup recognizer settings array recognitionSettings.setRecognizerSettingsArray(setupSettingsArray()); intent.putExtra(Pdf417ScanActivity.EXTRAS_RECOGNITION_SETTINGS, recognitionSettings); ``` * <a name="intent_EXTRAS_RECOGNITION_RESULTS" href="#intent_EXTRAS_RECOGNITION_RESULTS">#</a> **`Pdf417ScanActivity.EXTRAS_RECOGNITION_RESULTS`** - you can use this extra in `onActivityResult` method of calling activity to obtain recognition results. For more information about recognition settings and result, see [Recognition settings and results](#recognitionSettingsAndResults). You can use the following snippet to obtain scan results: ```java RecognitionResults results = data.getParcelableExtra(Pdf417ScanActivity.EXTRAS_RECOGNITION_RESULTS); ``` * <a name="intent_EXTRAS_OPTIMIZE_CAMERA_FOR_NEAR_SCANNING" href="#intent_EXTRAS_OPTIMIZE_CAMERA_FOR_NEAR_SCANNING">#</a> **`Pdf417ScanActivity.EXTRAS_OPTIMIZE_CAMERA_FOR_NEAR_SCANNING`** - with this extra you can give a hint to _PDF417.mobi_ to optimize camera parameters for near object scanning. When camera parameters are optimized for near object scanning, macro focus mode will be preferred over autofocus mode. Thus, camera will have easier time focusing on to near objects, but might have harder time focusing on far objects. If you expect that most of your scans will be performed by holding the device very near the object, turn on that parameter. By default, this parameter is set to false. * <a name="intent_EXTRAS_BEEP_RESOURCE" href="#intent_EXTRAS_BEEP_RESOURCE">#</a> **`Pdf417ScanActivity.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(Pdf417ScanActivity.EXTRAS_BEEP_RESOURCE, R.raw.beep); ``` * <a name="intent_EXTRAS_SPLASH_SCREEN_LAYOUT_RESOURCE" href="#intent_EXTRAS_SPLASH_SCREEN_LAYOUT_RESOURCE">#</a> **`Pdf417ScanActivity.EXTRAS_SPLASH_SCREEN_LAYOUT_RESOURCE`** - with this extra you can set the resource ID of the layout that will be used as camera splash screen while camera is being initialized. You can use following snippet to set this extra: ```java intent.putExtra(Pdf417ScanActivity. EXTRAS_SPLASH_SCREEN_LAYOUT_RESOURCE, R.layout.camera_splash); ``` * <a name="intent_EXTRAS_SHOW_FOCUS_RECTANGLE" href="#intent_EXTRAS_SHOW_FOCUS_RECTANGLE">#</a> **`Pdf417ScanActivity.EXTRAS_SHOW_FOCUS_RECTANGLE`** - with this extra you can enable showing of rectangle that displays area camera uses to measure focus and brightness when automatically adjusting its parameters. You can enable showing of this rectangle with following code snippet: ```java intent.putExtra(Pdf417ScanActivity.EXTRAS_SHOW_FOCUS_RECTANGLE, true); ``` * <a name="intent_EXTRAS_ALLOW_PINCH_TO_ZOOM" href="#intent_EXTRAS_ALLOW_PINCH_TO_ZOOM">#</a> **`Pdf417ScanActivity.EXTRAS_ALLOW_PINCH_TO_ZOOM`** - with this extra you can set whether pinch to zoom will be allowed on camera activity. Default is `false`. To enable pinch to zoom gesture on camera activity, use the following code snippet: ```java intent.putExtra(Pdf417ScanActivity.EXTRAS_ALLOW_PINCH_TO_ZOOM, true); ``` * <a name="intent_EXTRAS_CAMERA_VIDEO_PRESET" href="#intent_EXTRAS_CAMERA_VIDEO_PRESET">#</a> **`Pdf417ScanActivity.EXTRAS_CAMERA_VIDEO_PRESET`** - with this extra you can set the video resolution preset that will be used when choosing camera resolution for scanning. For more information, see [javadoc](https://pdf417.github.io/pdf417-android/com/microblink/hardware/camera/VideoResolutionPreset.html). For example, to use 720p video resolution preset, use the following code snippet: ```java intent.putExtra(Pdf417ScanActivity.EXTRAS_CAMERA_VIDEO_PRESET, (Parcelable)VideoResolutionPreset.VIDEO_RESOLUTION_720p); ``` * <a name="intent_EXTRAS_SET_FLAG_SECURE" href="#intent_EXTRAS_SET_FLAG_SECURE">#</a> **`Pdf417ScanActivity.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(Pdf417ScanActivity.EXTRAS_SET_FLAG_SECURE, true); ``` * <a name="intent_EXTRAS_LICENSE_KEY" href="#intent_EXTRAS_LICENSE_KEY">#</a> **`Pdf417ScanActivity.EXTRAS_LICENSE_KEY`** - with this extra you can set the license key for _PDF417.mobi_. 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(Pdf417ScanActivity.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 `mobi.pdf417.demo` 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(Pdf417ScanActivity.EXTRAS_LICENSE_KEY, "Enter_License_Key_Here"); intent.putExtra(Pdf417ScanActivity.EXTRAS_LICENSEE, "Enter_Licensee_Here"); ``` * <a name="intent_EXTRAS_IMAGE_LISTENER" href="#intent_EXTRAS_IMAGE_LISTENER">#</a> **`Pdf417ScanActivity.EXTRAS_IMAGE_LISTENER`** - with this extra you can set your implementation of [ImageListener interface](https://pdf417.github.io/pdf417-android/com/microblink/image/ImageListener.html) that will obtain images that are being processed. Make sure that your [ImageListener](https://pdf417.github.io/pdf417-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://pdf417.github.io/pdf417-android/com/microblink/metadata/MetadataSettings.ImageMetadataSettings.html) with `Pdf417ScanActivity.EXTRAS_IMAGE_METADATA_SETTINGS` * <a name="intent_EXTRAS_IMAGE_METADATA_SETTINGS" href="#intent_EXTRAS_IMAGE_METADATA_SETTINGS">#</a> **`Pdf417ScanActivity.EXTRAS_IMAGE_METADATA_SETTINGS`** - with this extra you can set [ImageMetadata settings](https://pdf417.github.io/pdf417-android/com/microblink/metadata/MetadataSettings.ImageMetadataSettings.html) which will define which images will be sent to [ImageListener interface](https://pdf417.github.io/pdf417-android/com/microblink/image/ImageListener.html) given via `Pdf417ScanActivity.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. * <a name="intent_EXTRAS_SHOW_DIALOG_AFTER_SCAN" href="#intent_EXTRAS_SHOW_DIALOG_AFTER_SCAN">#</a> **`Pdf417ScanActivity.EXTRAS_SHOW_DIALOG_AFTER_SCAN`** - with this extra you can prevent showing of dialog after each barcode scan. By default, each time scanner finds and decodes a barcode, a dialog with barcode's contents will be shown. To prevent this, use the following snippet: ```java // disable showing of dialog after scan intent.putExtra(Pdf417ScanActivity.EXTRAS_SHOW_DIALOG_AFTER_SCAN, false); ``` ### Customizing `Pdf417ScanActivity` appearance Besides possibility to put various intent extras for customizing `Pdf417ScanActivity` behaviour, you can also change strings it displays. The procedure for changing strings in `Pdf417ScanActivity` activity are explained in [Translation and localization](#stringChanging) section. #### Modifying other resources. Generally, you can also change other resources that `Pdf417ScanActivity` uses, but you are encouraged to create your own custom scan activity instead (see [Embedding `RecognizerView` into custom scan activity](#recognizerView)). #### Changing viewfinder appearance To change the colour of viewfinder in `Pdf417ScanActivity`, change or override the colours defined in `res/values/colors.xml` (colours `default_frame` and `recognized_frame`). ## <a name="recognizerView"></a> Embedding `RecognizerView` into custom scan activity This section will discuss how to embed [RecognizerView](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html) into your scan activity and perform scan. 1. First make sure that `RecognizerView` is a member field in your activity. This is required because you will need to pass all activity's lifecycle events to `RecognizerView`. 2. It is recommended to keep your scan activity in one orientation, such as `portrait` or `landscape`. Setting `sensor` as scan activity's orientation will trigger full restart of activity whenever device orientation changes. This will provide very poor user experience because both camera and _PDF417.mobi_ native library will have to be restarted every time. There are measures for this behaviour and will be discussed [later](#scanOrientation). 3. In your activity's `onCreate` method, create a new `RecognizerView`, define its [settings and listeners](#recognizerViewReference) and then call its `create` method. After that, add your views that should be layouted on top of camera view. 4. Override your activity's `onStart`, `onResume`, `onPause`, `onStop` and `onDestroy` methods and call `RecognizerView's` lifecycle methods `start`, `resume`, `pause`, `stop` and `destroy`. This will ensure correct camera and native resource management. If you plan to manage `RecognizerView's` lifecycle independently of host activity's lifecycle, make sure the order of calls to lifecycle methods is the same as is with activities (i.e. you should not call `resume` method if `create` and `start` were not called first). Here is the minimum example of integration of `RecognizerView` as the only view in your activity: ```java public class MyScanActivity extends Activity implements ScanResultListener, CameraEventsListener { private static final int PERMISSION_CAMERA_REQUEST_CODE = 69; private RecognizerView mRecognizerView; @Override protected void onCreate(Bundle savedInstanceState) { // create RecognizerView mRecognizerView = new RecognizerView(this); RecognitionSettings settings = new RecognitionSettings(); // setup array of recognition settings (described in chapter "Recognition // settings and results") RecognizerSettings[] settArray = setupSettingsArray(); if(!RecognizerCompatibility.cameraHasAutofocus(CameraType.CAMERA_BACKFACE, this)) { settArray = RecognizerSettingsUtils.filterOutRecognizersThatRequireAutofocus(settArray); } settings.setRecognizerSettingsArray(settArray); mRecognizerView.setRecognitionSettings(settings); try { // set license key mRecognizerView.setLicenseKey(this, "your license key"); } catch (InvalidLicenceKeyException exc) { finish(); return; } // scan result listener will be notified when scan result gets available mRecognizerView.setScanResultListener(this); // camera events listener will be notified about camera lifecycle and errors mRecognizerView.setCameraEventsListener(this); // set camera aspect mode // ASPECT_FIT will fit the camera preview inside the view // ASPECT_FILL will zoom and crop the camera preview, but will use the // entire view surface mRecognizerView.setAspectMode(CameraAspectMode.ASPECT_FILL); mRecognizerView.create(); setContentView(mRecognizerView); } @Override protected void onStart() { super.onStart(); // you need to pass all activity's lifecycle methods to RecognizerView mRecognizerView.start(); } @Override protected void onResume() { super.onResume(); // you need to pass all activity's lifecycle methods to RecognizerView mRecognizerView.resume(); } @Override protected void onPause() { super.onPause(); // you need to pass all activity's lifecycle methods to RecognizerView mRecognizerView.pause(); } @Override protected void onStop() { super.onStop(); // you need to pass all activity's lifecycle methods to RecognizerView mRecognizerView.stop(); } @Override protected void onDestroy() { super.onDestroy(); // you need to pass all activity's lifecycle methods to RecognizerView mRecognizerView.destroy(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // you need to pass all activity's lifecycle methods to RecognizerView mRecognizerView.changeConfiguration(newConfig); } @Override public void onScanningDone(RecognitionResults results) { // this method is from ScanResultListener and will be called when scanning completes // RecognitionResults may contain multiple results in array returned // by method getRecognitionResults(). // This depends on settings in RecognitionSettings object that was // given to RecognizerView. // For more information, see chapter "Recognition settings and results") // After this method ends, scanning will be resumed and recognition // state will be retained. If you want to prevent that, then // you should call: // mRecognizerView.resetRecognitionState(); // If you want to pause scanning to prevent receiving recognition // results, you should call: // mRecognizerView.pauseScanning(); // After scanning is paused, you will have to resume it with: // mRecognizerView.resumeScanning(true); // boolean in resumeScanning method indicates whether recognition // state should be automatically reset when resuming scanning } @Override public void onCameraPreviewStarted() { // this method is from CameraEventsListener and will be called when camera preview starts } @Override public void onCameraPreviewStopped() { // this method is from CameraEventsListener and will be called when camera preview stops } @Override public void onError(Throwable exc) { /** * This method is from CameraEventsListener and will be called when * opening of camera resulted in exception or recognition process * encountered an error. The error details will be given in exc * parameter. */ } @Override @TargetApi(23) public void onCameraPermissionDenied() { /** * Called on Android 6.0 and newer if camera permission is not given * by user. You should request permission from user to access camera. */ requestPermissions(new String[]{Manifest.permission.CAMERA}, PERMISSION_CAMERA_REQUEST_CODE); /** * Please note that user might have not given permission to use * camera. In that case, you have to explain to user that without * camera permissions scanning will not work. * For more information about requesting permissions at runtime, check * this article: * https://developer.android.com/training/permissions/requesting.html */ } @Override public void onAutofocusFailed() { /** * This method is from CameraEventsListener 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. */ } @Override public void onAutofocusStarted(Rect[] areas) { /** * This method is from CameraEventsListener and will be called when camera focusing has started. * You can utilize this method to draw focusing animation on UI. * Areas parameter is array of rectangles where focus is being measured. * It can be null on devices that do not support fine-grained camera control. */ } @Override public void onAutofocusStopped(Rect[] areas) { /** * This method is from CameraEventsListener and will be called when camera focusing has stopped. * You can utilize this method to remove focusing animation on UI. * Areas parameter is array of rectangles where focus is being measured. * It can be null on devices that do not support fine-grained camera control. */ } } ``` ### <a name="scanOrientation"></a> Scan activity's orientation If activity's `screenOrientation` property in `AndroidManifest.xml` is set to `sensor`, `fullSensor` or similar, activity will be restarted every time device changes orientation from portrait to landscape and vice versa. While restarting activity, its `onPause`, `onStop` and `onDestroy` methods will be called and then new activity will be created anew. This is a potential problem for scan activity because in its lifecycle it controls both camera and native library - restarting the activity will trigger both restart of the camera and native library. This is a problem because changing orientation from landscape to portrait and vice versa will be very slow, thus degrading a user experience. **We do not recommend such setting.** For that matter, we recommend setting your scan activity to either `portrait` or `landscape` mode and handle device orientation changes manually. To help you with this, `RecognizerView` supports adding child views to it that will be rotated regardless of activity's `screenOrientation`. You add a view you wish to be rotated (such as view that contains buttons, status messages, etc.) to `RecognizerView` with `addChildView` method. The second parameter of the method is a boolean that defines whether the view you are adding will be rotated with device. To define allowed orientations, implement [OrientationAllowedListener](https://pdf417.github.io/pdf417-android/com/microblink/view/OrientationAllowedListener.html) interface and add it to `RecognizerView` with method `setOrientationAllowedListener`. **This is the recommended way of rotating camera overlay.** However, if you really want to set `screenOrientation` property to `sensor` or similar and want Android to handle orientation changes of your scan activity, then we recommend to set `configChanges` property of your activity to `orientation|screenSize`. This will tell Android not to restart your activity when device orientation changes. Instead, activity's `onConfigurationChanged` method will be called so that activity can be notified of the configuration change. In your implementation of this method, you should call `changeConfiguration` method of `RecognizerView` so it can adapt its camera surface and child views to new configuration. Note that on Android versions older than 4.0 changing of configuration will require restart of camera, which can be slow. ## <a name="recognizerViewReference"></a> `RecognizerView` reference The complete reference of `RecognizerView` is available in [Javadoc](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html). The usage example is provided in `pdf417MobiDemoCustomUI` demo app provided with SDK. This section just gives a quick overview of `RecognizerView's` most important methods. ##### <a name="recognizerView_create"></a> [`create()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#create--) This method should be called in activity's `onCreate` method. It will initialize `RecognizerView's` internal fields and will initialize camera control thread. This method must be called after all other settings are already defined, such as listeners and recognition settings. After calling this method, you can add child views to `RecognizerView` with method `addChildView(View, boolean)`. ##### <a name="recognizerView_start"></a> [`start()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#start--) This method should be called in activity's `onStart` method. It will initialize background processing thread and start native library initialization on that thread. ##### <a name="recognizerView_resume"></a> [`resume()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#resume--) This method should be called in activity's `onResume` method. It will trigger background initialization of camera. After camera is loaded, it will start camera frame recognition, except if scanning loop is paused. ##### <a name="recognizerView_pause"></a> [`pause()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#pause--) This method should be called in activity's `onPause` method. It will stop the camera, but will keep native library loaded. ##### <a name="recognizerView_stop"></a> [`stop()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#stop--) This method should be called in activity's `onStop` method. It will deinitialize native library, terminate background processing thread and free all resources that are no longer necessary. ##### <a name="recognizerView_destroy"></a> [`destroy()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#destroy--) This method should be called in activity's `onDestroy` method. It will free all resources allocated in `create()` and will terminate camera control thread. ##### <a name="recognizerView_changeConfiguration"></a> [`changeConfiguration(Configuration)`](https://pdf417.github.io/pdf417-android/com/microblink/view/BaseCameraView.html#changeConfiguration-android.content.res.Configuration-) This method should be called in activity's `onConfigurationChanged` method. It will adapt camera surface to new configuration without the restart of the activity. See [Scan activity's orientation](#scanOrientation) for more information. ##### <a name="recognizerView_setCameraType"></a> [`setCameraType(CameraType)`](https://pdf417.github.io/pdf417-android/com/microblink/view/BaseCameraView.html#setCameraType-com.microblink.hardware.camera.CameraType-) With this method you can define which camera on device will be used. Default camera used is back facing camera. ##### <a name="recognizerView_setAspectMode"></a> [`setAspectMode(CameraAspectMode)`](https://pdf417.github.io/pdf417-android/com/microblink/view/BaseCameraView.html#setAspectMode-com.microblink.view.CameraAspectMode-) Define the [aspect mode of camera](https://pdf417.github.io/pdf417-android/com/microblink/view/CameraAspectMode.html). If set to `ASPECT_FIT` (default), then camera preview will be letterboxed inside available view space. If set to `ASPECT_FILL`, camera preview will be zoomed and cropped to use the entire view space. ##### <a name="recognizerView_setVideoResolutionPreset"></a> [`setVideoResolutionPreset(VideoResolutionPreset)`](https://pdf417.github.io/pdf417-android/com/microblink/view/BaseCameraView.html#setVideoResolutionPreset-com.microblink.hardware.camera.VideoResolutionPreset-) Define the [video resolution preset](https://pdf417.github.io/pdf417-android/com/microblink/hardware/camera/VideoResolutionPreset.html) that will be used when choosing camera resolution for scanning. ##### <a name="recognizerView_setRecognitionSettings"></a> [`setRecognitionSettings(RecognitionSettings)`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#setRecognitionSettings-com.microblink.recognizers.settings.RecognitionSettings-) With this method you can set recognition settings that contains information what will be scanned and how will scan be performed. For more information about recognition settings and results see [Recognition settings and results](#recognitionSettingsAndResults). This method must be called before `create()`. ##### <a name="recognizerView_reconfigureRecognizers1"></a> [`reconfigureRecognizers(RecognitionSettings)`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#reconfigureRecognizers-com.microblink.recognizers.settings.RecognitionSettings-) With this method you can reconfigure the recognition process while recognizer is active. Unlike `setRecognitionSettings`, this method must be called while recognizer is active (i.e. after `resume` was called). For more information about recognition settings see [Recognition settings and results](#recognitionSettingsAndResults). ##### <a name="recognizerView_setOrientationAllowedListener"></a> [`setOrientationAllowedListener(OrientationAllowedListener)`](https://pdf417.github.io/pdf417-android/com/microblink/view/BaseCameraView.html#setOrientationAllowedListener-com.microblink.view.OrientationAllowedListener-) With this method you can set a [OrientationAllowedListener](https://pdf417.github.io/pdf417-android/com/microblink/view/OrientationAllowedListener.html) which will be asked if current orientation is allowed. If orientation is allowed, it will be used to rotate rotatable views to it and it will be passed to native library so that recognizers can be aware of the new orientation. If you do not set this listener, recognition will be performed only in orientation defined by current activity's orientation. ##### <a name="recognizerView_setScanResultListener"></a> [`setScanResultListener(ScanResultListener)`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#setScanResultListener-com.microblink.view.recognition.ScanResultListener-) With this method you can set a [ScanResultListener](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/ScanResultListener.html) which will be notified when recognition completes. After recognition completes, `RecognizerView` will pause its scanning loop and to continue the scanning you will have to call `resumeScanning` method. In this method you can obtain data from scanning results. For more information see [Recognition settings and results](#recognitionSettingsAndResults). ##### <a name="recognizerView_setCameraEventsListener"></a> [`setCameraEventsListener(CameraEventsListener)`](https://pdf417.github.io/pdf417-android/com/microblink/view/BaseCameraView.html#setCameraEventsListener-com.microblink.view.CameraEventsListener-) With this method you can set a [CameraEventsListener](https://pdf417.github.io/pdf417-android/com/microblink/view/CameraEventsListener.html) which will be notified when various camera events occur, such as when camera preview has started, autofocus has failed or there has been an error while using the camera or performing the recognition. ##### <a name="recognizerView_pauseScanning"></a> [`pauseScanning()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#pauseScanning--) This method pauses the scanning loop, but keeps both camera and native library initialized. Pause and resume scanning methods count the number of calls, so if you called `pauseScanning()` twice, you will have to call `resumeScanning` twice to actually resume scanning. ##### <a name="recognizerView_resumeScanning"></a> [`resumeScanning(boolean)`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#resumeScanning-boolean-) With this method you can resume the paused scanning loop. If called with `true` parameter, implicitly calls `resetRecognitionState()`. If called with `false`, old recognition state will not be reset, so it could be reused for boosting recognition result. This may not be always a desired behaviour. Pause and resume scanning methods count the number of calls, so if you called `pauseScanning()` twice, you will have to call `resumeScanning` twice to actually resume scanning loop. ##### <a name="recognizerView_resetRecognitionState"></a> [`resetRecognitionState()`](https://pdf417.github.io/pdf417-android/com/microblink/view/recognition/RecognizerView.html#resetRecognitionState--) With this method you can reset internal recognition state. State is usually kept to improve recognition quality over time, but without resetting recognition state sometimes you might get poorer results (for example if you scan one object and then another without resetting state you might end up with result that contains properties from both scanned objects). ##### <a name="recognizerView_addChildView"></a> [`addChildView(View, boolean)`](https://pdf417.github.io/pdf417-android/com/microblink/view/BaseCameraView.html#addChildView-android.view.View-boolean-) With this method you can add your own view on top of `RecognizerView`. `RecognizerView` will ensure that your view will be layouted exactly above camera preview surface (which can be letterboxed if aspect ratio of camera preview size does not match the aspect ratio of `RecognizerView` and camera aspect mode is set to `ASPECT_FIT`). Boolean parameter defines whether your view should be rotated with device orientation changes. The rotation is independent of host activity's orientation changes and allowed orientations will be determined from [OrientationAllowedListener](https://pdf417.github.io/pdf417-android/com/microblink/view/OrientationAllowedListener.html). See also [Scan activity's orientation](#scanOrientation) for more information why