Integration Documentation for Flutter Compatible with Liveness Detection V4.x Version.
Minimum Android version:4.4 (API Level:19)
Compilation Android SDK version:API Level:35
Target Android SDK version:API Level:35
Supported CPU architectures:armeabi-v7a,arm64-v8a
SDK incremental package size:4.5MB+
If you have requirements for package size, you can refer to this to reduce the package size by approximately 1.4MB.
Capture image size:default capture image resolution 600px*600px, size is about 300KB, support custom image size range: 300px~1000px
Supported languages:
Use-permissions:
<uses-feature android:name="android.hardware.camera" /><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.CAMERA" />SDK requirements and limitations as below:
Nonearm64, x86_646.4MB(arm64, disable bitcode)NOen, zh-Hans, id, vi, th, es, ms, hi,filNSCameraUsageDescriptionClick to view the compliance explanation
Install IDV-Demo.apk to your phone and log in with the test account.
If you are upgrading from an older version of the Liveness SDK, please refer to this document to understand the changes.
Add the dependency in your Flutter project’s pubspec.yaml file.
xxxxxxxxxxdependencies flutter sdkflutter liveness_plugin:4.1.11For iOS, you need to do:
Podfile.xxxxxxxxxxsource 'https://cdn.cocoapods.org/'source 'https://github.com/advance-ai-mobile/aai-specs'
pod install --repo-update to install the dependencies in your project.xxxxxxxxxx<key>NSCameraUsageDescription</key><string>Use the camera to detect the face movements</string>Initialization SDK.
xxxxxxxxxxLivenessPlugin.initSDKOfLicense(Market.xxx);Check license
The license is obtained by your server calling our openAPI, you need to check license before starting the liveness detection activity.
xString license = "xxx";String? result = await LivenessPlugin.setLicenseAndCheck(license);
print("result = " + result.toString());if ("SUCCESS" == result) { startLivenessDetection();}
The returned values of checkResult:
APPLICATION_ID_NOT_MATCH: The package name is not within the authorized scope, please check your package name.
LICENSE_EXPIRE: The license has expired, please confirm that the user has calibrated the phone time.
ERROR_LICENSE(1): The license parsing succeeded, but necessary authentication information is missing, this case generally will not occur.
ERROR_LICENSE(2): The license parsing succeeded, but the internal format is incorrect, this case also generally will not occur.
ERROR_LICENSE(3): It is highly likely that an incompatible SDK license is being used, such as using an IQA license for liveness detection.
ERROR_LICENSE(4, 5): Parsing failed, please check if the license has issues like mismatched quotes, line breaks, etc.You can create SDK launch parameters using the method below
xxxxxxxxxxclass _MyHomePageState extends State<MyHomePage> implements LivenessDetectionCallback {
@override void initState() { super.initState(); LivenessPlugin.getSDKVersion.then((sdkVersion) { print("Liveness SDK Version = " + sdkVersion); });
}
void _incrementCounter() { _checkLicense(); }
void _checkLicense() async { LivenessPlugin.initSDKOfLicense(Market.Indonesia); String license = "xxx"; String? result = await LivenessPlugin.setLicenseAndCheck(license);
print("result = " + result.toString()); if ("SUCCESS" == result) { startLivenessDetection(); } }
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); }
void startLivenessDetection() { // Note: All configuration options listed below are optional. Please set them as needed. Map<String, dynamic> config = { // Optional // Note for iOS side only support CameraType.FRONT "cameraType": CameraType.FRONT,
// Optional "detectOcclusion": false, /* // Optional "auditImageConfig": { "enableCollectSwitch": true, "imageWidth": 400, "imageQuality": 30, "relativeSecondsCaptureAfterCameraLaunched": 3.0, }, */ /* // Optional "livenessType": "test_more", "signatureId": "your_signature_id", */
/* // Optional "distantNearTimeout": 50000, "silentTimeout": 50000, "actionTimeout": 10000, "prepareMillSeconds": 0, */
/* // Optional // The size(width) of the resulting image "resultPictureSize": 600, */
/* // Optional // Maximum duration of video recording, in seconds. // 0 means do not record video. "maxRecordVideoSeconds": 60, */ // Optional (strongly recommended) // You can use this property to pass your user unique identifier to us, // we will establish a mapping relationship based on the identifier. // It is helpful for us to check the log when you encountering problems. "userId": "your_unique_user_id", /* // Optional // Note this configuration item only works on android side "maskColor": "#000000", */
/* // Optional // The hightlight state color of the avatar preview area's border "ovalColor": "#000000", */
/* // Optional // The normal state color of the avatar preview area's border "ovalNormalColor": "#000000" */
/* // Optional (iOS only) // Specify the language for the SDK UI. // Supported values: "en", "zh-Hans", "id", "vi", "th", "es", "ms", "hi", "fil" // If not set, the SDK follows the system language. "language": "en", */
/* // Optional (iOS only) // Override specific SDK prompt texts. // Key format: "<language>.<key>", e.g. "en.no_face". // The SDK will use the matching language entries based on the effective language // (set via "language" above, or system language if not set). // Common keys (e.g.): "no_face", "move_closer", "stay_still", "pls_blink", "pls_open_mouth" // For the full list of available keys, see: // Pods/AAILivenessUI/AAILivenessSDK/AAILivenessUI/Resource/AAILanguageString.bundle/en.lproj/Localizable.strings "localizedStrings": { "en.no_face": "No face detected", "en.pls_blink": "Please blink", "en.stay_still": "Hold steady", }, */
/* // Optional (iOS only) // Customize the font of the state-hint label. // "fontName" must be a valid PostScript font name registered in the app. // If the font cannot be found, the SDK default font is used. "font": { "fontName": "YourCustomFont-Regular", "fontSize": 16.0, }, */ }; LivenessPlugin.startLivenessDetection(config, this); }
@override void onGetDetectionResult(bool isSuccess, Map<dynamic, dynamic>? resultMap) { print("onGetDetectionResult called:" + isSuccess.toString()); print("onGetDetectionResult print result:" + resultMap.toString()); }}The following customization options are currently supported on iOS only.
Set the SDK display language via the language parameter. Supported values: "en", "zh-Hans", "id", "vi", "th", "es", "ms", "hi", "fil". If not set, the SDK follows the device system language.
xxxxxxxxxxMap<String, dynamic> config = { "language": "en",};Use localizedStrings to override specific SDK prompt texts. Keys follow the format "<language>.<key>". Only entries matching the effective language (from language or system language) are applied.
xxxxxxxxxxMap<String, dynamic> config = { "language": "en", "localizedStrings": { "en.no_face": "No face detected", "en.pls_blink": "Please blink slowly", "en.stay_still": "Hold steady", },};Some commonly used keys (examples):
| Key | Default (en) |
|---|---|
no_face | Please put your face in the frame |
move_closer | Get closer |
move_further | Step back |
stay_still | Hold steady |
pls_blink | Please blink |
pls_open_mouth | Please open your mouth and then close |
low_light | Go to a brighter area |
warn_muti_face | Multiple faces detected from the image, please only keep one face in the image |
For the complete list of available keys, refer to the Localizable.strings file bundled with the SDK after running pod install:
xxxxxxxxxxPods/AAILivenessUI/AAILivenessSDK/AAILivenessUI/Resource/AAILanguageString.bundle/en.lproj/Localizable.strings
Use font to customize the font of the state-hint label. fontName must be a valid PostScript name of a font registered in your app. If the font cannot be found, the SDK default font is used.
xxxxxxxxxxMap<String, dynamic> config = { "font": { "fontName": "YourCustomFont-Regular", "fontSize": 16.0, },};See FAQ for Android UI customization.
See Error Code