Skip to content

Commit da0e04e

Browse files
authored
Merge pull request #11 from blinkcard/release/2.10.0
Release/2.10.0
2 parents 88af5e3 + 84c0256 commit da0e04e

15 files changed

Lines changed: 402 additions & 229 deletions

File tree

BlinkCard/blinkcard-react-native.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ Pod::Spec.new do |s|
1313
s.source = { :git => "https://github.com/BlinkCard/blinkcard-react-native.git", :tag => "v#{s.version}" }
1414
s.source_files = "src/ios", "src/ios/**/*.{h,m}"
1515
s.dependency 'React'
16-
s.dependency 'MBBlinkCard', '~> 2.9.1'
16+
s.dependency 'MBBlinkCard', '~> 2.10.0'
1717
s.frameworks = 'UIKit'
1818
end

BlinkCard/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export class RecognizerCollection {
160160
*/
161161
this.allowMultipleResults = false;
162162
/** Number of miliseconds after first non-empty result becomes available to end scanning with a timeout */
163-
this.milisecondsBeforeTimeout = 10000;
163+
this.milisecondsBeforeTimeout = 0;
164164

165165
if (!(this.recognizerArray instanceof Array)) {
166166
throw new Error("recognizerArray must be array of Recognizer objects!");

BlinkCard/overlays/blinkCardOverlays.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { OverlaySettings } from '../overlaySettings'
2-
2+
import { AndroidCameraResolutionPreset,
3+
iOSCameraResolutionPreset
4+
} from '../types'
35
/**
46
* Class for setting up BlinkCard overlay.
57
* BlinkCard overlay is best suited for scanning payment cards.
@@ -73,5 +75,26 @@ export class BlinkCardOverlaySettings extends OverlaySettings {
7375
* example: "US" to use "en_US" on Android and en-US on iOS
7476
*/
7577
this.country = null;
78+
79+
/**
80+
* Defines possible iOS device camera video resolution preset.
81+
*
82+
* Default: PresetOptimal
83+
*/
84+
this.iOSCameraResolutionPreset = iOSCameraResolutionPreset.PresetOptimal;
85+
86+
/**
87+
* Defines possible Android device camera video resolution preset.
88+
*
89+
* Default: PresetDefault
90+
*/
91+
this.androidCameraResolutionPreset = AndroidCameraResolutionPreset.PresetDefault;
92+
93+
/**
94+
* Option to set whether legacy camera API should be used even on Lollipop devices that support newer Camera2 API.
95+
*
96+
* Default: false
97+
*/
98+
this.enableAndroidLegacyCameraApi = false;
7699
}
77100
}

BlinkCard/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

BlinkCard/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@microblink/blinkcard-react-native",
3-
"version": "2.9.1",
3+
"version": "2.10.0",
44
"description": "AI-driven credit card scanning for cross-platform apps built with ReactNative.",
55
"main": "index.js",
66
"repository": {

BlinkCard/src/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ android {
2525

2626
dependencies {
2727
implementation 'com.facebook.react:react-native:+'
28-
implementation('com.microblink:blinkcard:2.9.3@aar') {
28+
implementation('com.microblink:blinkcard:2.10.0@aar') {
2929
transitive = true
3030
}
3131
}

BlinkCard/src/android/src/main/java/com/microblink/blinkcard/reactnative/MicroblinkModule.java

Lines changed: 80 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.microblink.blinkcard.metadata.recognition.FirstSideRecognitionCallback;
3232
import com.microblink.blinkcard.recognition.RecognitionSuccessType;
3333
import com.microblink.blinkcard.view.recognition.ScanResultListener;
34+
import com.microblink.blinkcard.licence.exception.LicenceKeyException;
3435

3536
import com.microblink.blinkcard.uisettings.UISettings;
3637
import com.microblink.blinkcard.reactnative.recognizers.RecognizerSerializers;
@@ -75,93 +76,94 @@ public String getName() {
7576

7677
@ReactMethod
7778
public void scanWithCamera(ReadableMap jsonOverlaySettings, ReadableMap jsonRecognizerCollection, ReadableMap license, Promise promise) {
78-
prepareScanning(license, promise);
79-
try {
80-
LanguageUtils.setLanguageAndCountry(jsonOverlaySettings.getString("language"),
81-
jsonOverlaySettings.getString("country"),
82-
getCurrentActivity());
83-
} catch (Exception e) {}
84-
mRecognizerBundle = RecognizerSerializers.INSTANCE.deserializeRecognizerCollection(jsonRecognizerCollection);
85-
UISettings overlaySettings = OverlaySettingsSerializers.INSTANCE.getOverlaySettings(getReactApplicationContext(), jsonOverlaySettings, mRecognizerBundle);
86-
ActivityRunner.startActivityForResult(getCurrentActivity(), REQUEST_CODE, overlaySettings);
79+
if(prepareScanning(license, promise)) {
80+
try {
81+
LanguageUtils.setLanguageAndCountry(jsonOverlaySettings.getString("language"),
82+
jsonOverlaySettings.getString("country"),
83+
getCurrentActivity());
84+
} catch (Exception e) {}
85+
mRecognizerBundle = RecognizerSerializers.INSTANCE.deserializeRecognizerCollection(jsonRecognizerCollection);
86+
UISettings overlaySettings = OverlaySettingsSerializers.INSTANCE.getOverlaySettings(getReactApplicationContext(), jsonOverlaySettings, mRecognizerBundle);
87+
ActivityRunner.startActivityForResult(getCurrentActivity(), REQUEST_CODE, overlaySettings);
88+
}
8789
}
8890

8991
@ReactMethod
9092
private void scanWithDirectApi(ReadableMap jsonRecognizerCollection, ReadableMap frontImage, ReadableMap backImage, ReadableMap license, Promise promise) {
9193
//DirectAPI processing
9294
mScanPromise = promise;
93-
prepareScanning(license, promise);
94-
95-
ScanResultListener mScanResultListenerBackSide = new ScanResultListener() {
96-
@Override
97-
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
98-
mFirstSideScanned = false;
99-
handleDirectApiResult(recognitionSuccessType);
100-
}
101-
@Override
102-
public void onUnrecoverableError(@NonNull Throwable throwable) {
103-
promise.reject(throwable);
104-
}
105-
};
95+
if(prepareScanning(license, promise)) {
96+
ScanResultListener mScanResultListenerBackSide = new ScanResultListener() {
97+
@Override
98+
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
99+
mFirstSideScanned = false;
100+
handleDirectApiResult(recognitionSuccessType);
101+
}
102+
@Override
103+
public void onUnrecoverableError(@NonNull Throwable throwable) {
104+
promise.reject(throwable);
105+
}
106+
};
106107

107-
FirstSideRecognitionCallback mFirstSideRecognitionCallback = new FirstSideRecognitionCallback() {
108-
@Override
109-
public void onFirstSideRecognitionFinished() {
110-
mFirstSideScanned = true;
111-
}
112-
};
108+
FirstSideRecognitionCallback mFirstSideRecognitionCallback = new FirstSideRecognitionCallback() {
109+
@Override
110+
public void onFirstSideRecognitionFinished() {
111+
mFirstSideScanned = true;
112+
}
113+
};
113114

114-
ScanResultListener mScanResultListenerFrontSide = new ScanResultListener() {
115-
@Override
116-
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
117-
if (mFirstSideScanned == true) {
118-
//multiside recognizer used
119-
try {
120-
if (backImage != null) {
121-
processImage(backImage.getString(PARAM_BACK_IMAGE), mScanResultListenerBackSide);
122-
} else if (recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL) {
123-
handleDirectApiResult(recognitionSuccessType);
124-
} else {
125-
handleDirectApiError("Could not extract the information from the front side and back side is empty!", promise);
115+
ScanResultListener mScanResultListenerFrontSide = new ScanResultListener() {
116+
@Override
117+
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
118+
if (mFirstSideScanned == true) {
119+
//multiside recognizer used
120+
try {
121+
if (backImage != null) {
122+
processImage(backImage.getString(PARAM_BACK_IMAGE), mScanResultListenerBackSide);
123+
} else if (recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL) {
124+
handleDirectApiResult(recognitionSuccessType);
125+
} else {
126+
handleDirectApiError("Could not extract the information from the front side and back side is empty!", promise);
127+
}
128+
} catch (Exception e) {
129+
throw new RuntimeException(e);
126130
}
127-
} catch (Exception e) {
128-
throw new RuntimeException(e);
131+
} else if (mFirstSideScanned == false && recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL){
132+
//singleside recognizer used
133+
handleDirectApiResult(recognitionSuccessType);
134+
} else {
135+
mFirstSideScanned = false;
136+
handleDirectApiError("Could not extract the information with DirectAPI!", promise);
129137
}
130-
} else if (mFirstSideScanned == false && recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL){
131-
//singleside recognizer used
132-
handleDirectApiResult(recognitionSuccessType);
133-
} else {
134-
mFirstSideScanned = false;
135-
handleDirectApiError("Could not extract the information with DirectAPI!", promise);
136138
}
137-
}
138-
@Override
139-
public void onUnrecoverableError(@NonNull Throwable throwable) {
140-
promise.reject(throwable);
141-
}
142-
};
139+
@Override
140+
public void onUnrecoverableError(@NonNull Throwable throwable) {
141+
promise.reject(throwable);
142+
}
143+
};
143144

144-
setupRecognizerRunner(jsonRecognizerCollection, mFirstSideRecognitionCallback, promise);
145+
setupRecognizerRunner(jsonRecognizerCollection, mFirstSideRecognitionCallback, promise);
145146

146-
if (frontImage != null) {
147-
processImage(frontImage.getString(PARAM_FRONT_IMAGE), mScanResultListenerFrontSide);
148-
} else {
149-
handleDirectApiError("The provided image for the 'frontImage' parameter is empty!", promise);
147+
if (frontImage != null) {
148+
processImage(frontImage.getString(PARAM_FRONT_IMAGE), mScanResultListenerFrontSide);
149+
} else {
150+
handleDirectApiError("The provided image for the 'frontImage' parameter is empty!", promise);
151+
}
150152
}
151153
}
152154

153-
private void prepareScanning(ReadableMap license, Promise promise) {
155+
private boolean prepareScanning(ReadableMap license, Promise promise) {
154156
Activity currentActivity = getCurrentActivity();
155157
if (currentActivity == null) {
156158
promise.reject(ERROR_ACTIVITY_DOES_NOT_EXIST, "Activity does not exist");
157-
return;
159+
return false;
158160
}
159161

160162
// Store the promise to resolve/reject when scanning is done
161163
mScanPromise = promise;
162164
if (!license.hasKey(PARAM_LICENSE_KEY)) {
163165
promise.reject(ERROR_LICENSE_KEY_NOT_SET, "License key is not set");
164-
return;
166+
return false;
165167
}
166168
String licenseKey = license.getString(PARAM_LICENSE_KEY);
167169
String licensee = null;
@@ -172,7 +174,8 @@ private void prepareScanning(ReadableMap license, Promise promise) {
172174
if (license.hasKey(PARAM_SHOW_TRIAL_LICENSE_WARNING)) {
173175
showTrialLicenseKeyWarning = license.getBoolean(PARAM_SHOW_TRIAL_LICENSE_WARNING);
174176
}
175-
setLicense(licenseKey, licensee, showTrialLicenseKeyWarning);
177+
178+
return setLicense(licenseKey, licensee, showTrialLicenseKeyWarning);
176179
}
177180

178181
private void setupRecognizerRunner(ReadableMap jsonRecognizerCollection, FirstSideRecognitionCallback mFirstSideRecognitionCallback, Promise promise) {
@@ -233,16 +236,27 @@ private Bitmap base64ToBitmap(String base64String) {
233236
return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
234237
}
235238

236-
private void setLicense( String licenseKey, String licensee, Boolean showTrialLicenseKeyWarning ) {
239+
private boolean setLicense( String licenseKey, String licensee, Boolean showTrialLicenseKeyWarning ) {
237240
if (showTrialLicenseKeyWarning != null) {
238241
MicroblinkSDK.setShowTrialLicenseWarning(showTrialLicenseKeyWarning);
239242
}
240243
if (licensee != null) {
241-
MicroblinkSDK.setLicenseKey(licenseKey, licensee, this.getCurrentActivity());
244+
try {
245+
MicroblinkSDK.setLicenseKey(licenseKey, licensee, this.getCurrentActivity());
246+
} catch (LicenceKeyException licenceKeyException) {
247+
mScanPromise.reject("Android license key error: " + licenceKeyException.toString());
248+
return false;
249+
}
242250
} else {
243-
MicroblinkSDK.setLicenseKey(licenseKey, this.getCurrentActivity());
251+
try {
252+
MicroblinkSDK.setLicenseKey(licenseKey, this.getCurrentActivity());
253+
} catch (LicenceKeyException licenceKeyException) {
254+
mScanPromise.reject("Android license key error: " + licenceKeyException.toString());
255+
return false;
256+
}
244257
}
245258
MicroblinkSDK.setIntentDataTransferMode(IntentDataTransferMode.PERSISTED_OPTIMISED);
259+
return true;
246260
}
247261

248262
private void rejectPromise(String code, String message) {

BlinkCard/src/android/src/main/java/com/microblink/blinkcard/reactnative/overlays/serialization/BlinkCardOverlaySettingsSerialization.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import com.microblink.blinkcard.reactnative.overlays.OverlaySettingsSerialization;
99
import com.microblink.blinkcard.uisettings.BlinkCardUISettings;
1010
import com.microblink.blinkcard.uisettings.UISettings;
11+
import com.microblink.blinkcard.hardware.camera.VideoResolutionPreset;
12+
import com.microblink.blinkcard.uisettings.CameraSettings;
1113

1214
public final class BlinkCardOverlaySettingsSerialization implements OverlaySettingsSerialization {
1315
@Override
@@ -57,6 +59,21 @@ public UISettings createUISettings(Context context, ReadableMap jsonUISettings,
5759
if (errorCardTooCloseToEdge != null) {
5860
overlayStringsBuilder.setErrorCardTooCloseToEdge(errorCardTooCloseToEdge);
5961
}
62+
63+
VideoResolutionPreset videoResolutionPreset = VideoResolutionPreset.values()[0];
64+
if (jsonUISettings.hasKey("androidCameraResolutionPreset")) {
65+
videoResolutionPreset = VideoResolutionPreset.values()[jsonUISettings.getInt("androidCameraResolutionPreset")];
66+
}
67+
68+
Boolean androidLegacyCameraApi = false;
69+
if (jsonUISettings.hasKey("enableAndroidLegacyCameraApi")) {
70+
androidLegacyCameraApi = jsonUISettings.getBoolean("enableAndroidLegacyCameraApi");
71+
}
72+
73+
settings.setCameraSettings(new CameraSettings.Builder()
74+
.setVideoResolutionPreset(videoResolutionPreset)
75+
.setForceLegacyApi(androidLegacyCameraApi)
76+
.build());
6077

6178
settings.setStrings(overlayStringsBuilder.build());
6279
return settings;

0 commit comments

Comments
 (0)