react-native-scanbot-barcode-scanner-sdk 3.2.1-beta6 → 3.2.1-beta9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/.project +6 -0
- package/android/build.gradle +2 -2
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/android/gradlew +185 -0
- package/android/gradlew.bat +89 -0
- package/android/src/main/java/com/reactlibrary/ScanbotBarcodeSdkPackage.java +17 -4
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/ObjectMapper.java +6 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/ScanbotBarcodeSdkPackage.java +15 -5
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/RNScanbotBarcodeCameraComponent.java +292 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/{ScanbotBarcodeCameraViewConfiguration.java → RNScanbotBarcodeCameraConfiguration.java} +54 -4
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/RNScanbotBarcodeCameraUi.java +81 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponent.java +90 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponentManager.java +133 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponentManagerFactory.java +40 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/RNScanbotNativeComponentUi.java +131 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/{EventEmitter.java → base/communication/RNScanbotEventEmitter.java} +27 -6
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/base/communication/RNScanbotEventReceiver.java +108 -0
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/{common/ScanbotComponentFrameLayout.java → base/views/RNScanbotNativeComponentFrameLayout.java} +4 -4
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/{common/ScanbotComponentRootView.java → base/views/RNScanbotNativeComponentRootView.java} +43 -48
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/utils/JSONUtils.java +25 -14
- package/android/src/main/res/layout/component_barcode_camera_view.xml +22 -5
- package/index.d.ts +7 -3
- package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraView.h +7 -1
- package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraView.m +18 -2
- package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraViewManager.h +6 -0
- package/ios/Components/BarcodeCameraView/RNScanbotBarcodeCameraViewManager.m +41 -0
- package/ios/Utils/BarcodeMapping.h +3 -1
- package/package.json +1 -1
- package/src/components/barcode-camera-view/scanbot-barcode-camera-view-types.tsx +6 -0
- package/src/components/barcode-camera-view/scanbot-barcode-camera-view.tsx +42 -5
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/BitmapHelper.java +0 -28
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/JSONUtils.java +0 -272
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/LogUtils.java +0 -40
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/ResponseUtils.java +0 -41
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/ScanbotBarcodeCameraViewFragment.java +0 -255
- package/android/src/main/java/io/scanbot/barcodesdk/plugin/reactnative/components/barcodecameraview/ScanbotBarcodeCameraViewManager.java +0 -160
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview;;
|
|
2
|
+
|
|
3
|
+
import android.Manifest;
|
|
4
|
+
import android.app.Activity;
|
|
5
|
+
import android.content.pm.PackageManager;
|
|
6
|
+
import android.graphics.Color;
|
|
7
|
+
import android.view.View;
|
|
8
|
+
|
|
9
|
+
import androidx.annotation.ColorInt;
|
|
10
|
+
import androidx.annotation.NonNull;
|
|
11
|
+
import androidx.annotation.Nullable;
|
|
12
|
+
import androidx.core.app.ActivityCompat;
|
|
13
|
+
import androidx.core.content.ContextCompat;
|
|
14
|
+
|
|
15
|
+
import com.facebook.react.bridge.ReactContext;
|
|
16
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
17
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
18
|
+
import com.facebook.react.bridge.WritableArray;
|
|
19
|
+
import com.facebook.react.bridge.WritableMap;
|
|
20
|
+
import com.facebook.react.bridge.WritableNativeArray;
|
|
21
|
+
|
|
22
|
+
import org.jetbrains.annotations.NotNull;
|
|
23
|
+
|
|
24
|
+
import java.util.Collections;
|
|
25
|
+
import java.util.List;
|
|
26
|
+
|
|
27
|
+
import io.scanbot.sdk.SdkLicenseError;
|
|
28
|
+
import io.scanbot.sdk.barcode.BarcodeDetectorFrameHandler;
|
|
29
|
+
import io.scanbot.sdk.barcode.DefaultScanbotBarcodeDetector;
|
|
30
|
+
import io.scanbot.sdk.barcode.ScanbotBarcodeDetector;
|
|
31
|
+
import io.scanbot.sdk.barcode.entity.BarcodeItem;
|
|
32
|
+
import io.scanbot.sdk.barcode.entity.BarcodeScannerAdditionalConfig;
|
|
33
|
+
import io.scanbot.sdk.barcode.entity.BarcodeScanningResult;
|
|
34
|
+
import io.scanbot.sdk.camera.FrameHandlerResult;
|
|
35
|
+
import io.scanbot.barcodesdk.plugin.reactnative.utils.JSONUtils;
|
|
36
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventEmitter;
|
|
37
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventReceiver;
|
|
38
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.RNScanbotNativeComponent;
|
|
39
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.RNScanbotNativeComponentUi;
|
|
40
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentRootView;
|
|
41
|
+
import io.scanbot.sdk.ui.camera.FinderOverlayView;
|
|
42
|
+
import io.scanbot.sdk.ui.camera.ScanbotCameraXView;
|
|
43
|
+
import kotlin.Unit;
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* The core logic of the ScanbotBarcodeCameraView Component
|
|
47
|
+
*/
|
|
48
|
+
public class RNScanbotBarcodeCameraComponent extends RNScanbotNativeComponent implements BarcodeDetectorFrameHandler.ResultHandler {
|
|
49
|
+
|
|
50
|
+
private static final int REQUEST_PERMISSION_CODE = 200;
|
|
51
|
+
|
|
52
|
+
// From Java to JavaScript
|
|
53
|
+
public enum NativeEvents implements RNScanbotEventEmitter.NativeEvent {
|
|
54
|
+
BARCODE_SCANNER_RESULT("onBarcodeScannerResult");
|
|
55
|
+
|
|
56
|
+
private final String name;
|
|
57
|
+
NativeEvents(final String name) {
|
|
58
|
+
this.name = name;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public String getName() {
|
|
62
|
+
return name;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// UI
|
|
67
|
+
private RNScanbotBarcodeCameraUi barcodeCameraUi;
|
|
68
|
+
private ScanbotBarcodeDetector barcodeDetector;
|
|
69
|
+
private BarcodeDetectorFrameHandler frameHandler;
|
|
70
|
+
|
|
71
|
+
// Communication
|
|
72
|
+
private RNScanbotEventEmitter eventEmitter;
|
|
73
|
+
|
|
74
|
+
// Configuration
|
|
75
|
+
private RNScanbotBarcodeCameraConfiguration configuration = new RNScanbotBarcodeCameraConfiguration();
|
|
76
|
+
private float userDefinedCameraZoomFactor = -1;
|
|
77
|
+
|
|
78
|
+
// Dependencies
|
|
79
|
+
private final ReactContext reactContext;
|
|
80
|
+
|
|
81
|
+
// State handling
|
|
82
|
+
private boolean isInitialized = false;
|
|
83
|
+
|
|
84
|
+
public RNScanbotBarcodeCameraComponent(@NonNull final ReactContext reactContext) {
|
|
85
|
+
super(reactContext);
|
|
86
|
+
this.reactContext = reactContext;
|
|
87
|
+
this.barcodeCameraUi = new RNScanbotBarcodeCameraUi(reactContext);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ---------------------
|
|
91
|
+
// Component Lifecycle
|
|
92
|
+
// ---------------------
|
|
93
|
+
@Override
|
|
94
|
+
public void onComponentWillUnmount() {
|
|
95
|
+
super.onComponentWillUnmount();
|
|
96
|
+
final ScanbotCameraXView cameraView = this.barcodeCameraUi.getCameraView();
|
|
97
|
+
cameraView.stopPreview();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@Override
|
|
101
|
+
public void onOrientationChanged() {
|
|
102
|
+
super.onOrientationChanged();
|
|
103
|
+
}
|
|
104
|
+
// ---------------------
|
|
105
|
+
|
|
106
|
+
@Override
|
|
107
|
+
public void initializeComponent() {
|
|
108
|
+
final ScanbotCameraXView cameraView = this.barcodeCameraUi.getCameraView();
|
|
109
|
+
cameraView.startPreview();
|
|
110
|
+
|
|
111
|
+
this.barcodeDetector = new DefaultScanbotBarcodeDetector();
|
|
112
|
+
|
|
113
|
+
this.frameHandler = BarcodeDetectorFrameHandler.attach(cameraView, barcodeDetector);
|
|
114
|
+
this.frameHandler.setDetectionInterval(0);
|
|
115
|
+
this.frameHandler.addResultHandler(this);
|
|
116
|
+
|
|
117
|
+
cameraView.addFrameHandler(frameHandler);
|
|
118
|
+
cameraView.setCameraOpenCallback(cameraView::continuousFocus);
|
|
119
|
+
|
|
120
|
+
cameraView.post(this::checkPermissions);
|
|
121
|
+
|
|
122
|
+
this.eventEmitter = new RNScanbotEventEmitter(this.reactContext, this.barcodeCameraUi.getRootView());
|
|
123
|
+
|
|
124
|
+
applyConfiguration();
|
|
125
|
+
|
|
126
|
+
reactContext.runOnUiQueueThread(() -> isInitialized = true);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private void applyConfiguration() {
|
|
130
|
+
reactContext.runOnUiQueueThread(() -> {
|
|
131
|
+
final FinderOverlayView finderOverlayView = barcodeCameraUi.getFinderOverlayView();
|
|
132
|
+
final ScanbotCameraXView cameraView = barcodeCameraUi.getCameraView();
|
|
133
|
+
|
|
134
|
+
finderOverlayView.setVisibility(configuration.shouldUseFinderView() ? View.VISIBLE : View.INVISIBLE);
|
|
135
|
+
finderOverlayView.setStrokeWidth(configuration.getFinderLineWidth());
|
|
136
|
+
finderOverlayView.setStrokeColor(configuration.getFinderLineColor());
|
|
137
|
+
finderOverlayView.setOverlayColor(colorWithAlpha(
|
|
138
|
+
configuration.getFinderBackgroundColor(),
|
|
139
|
+
configuration.getFinderBackgroundOpacity()));
|
|
140
|
+
finderOverlayView.setMinFinderPadding(configuration.getFinderMinimumPadding());
|
|
141
|
+
finderOverlayView.setVerticalOffset(configuration.getFinderVerticalOffset());
|
|
142
|
+
finderOverlayView.setRequiredAspectRatios(Collections.singletonList(configuration.getFinderAspectRatio()));
|
|
143
|
+
finderOverlayView.requestLayout();
|
|
144
|
+
|
|
145
|
+
cameraView.useFlash(configuration.isFlashEnabled());
|
|
146
|
+
|
|
147
|
+
if (configuration.getCameraZoomFactor() != -1) {
|
|
148
|
+
if (configuration.getCameraZoomFactor() != userDefinedCameraZoomFactor || userDefinedCameraZoomFactor == -1) {
|
|
149
|
+
cameraView.setOpticalZoomLevel(configuration.getCameraZoomFactor());
|
|
150
|
+
userDefinedCameraZoomFactor = configuration.getCameraZoomFactor();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
barcodeDetector.modifyConfig(b -> {
|
|
154
|
+
if(!configuration.barcodeFormats.isEmpty()) {
|
|
155
|
+
b.setBarcodeFormats(configuration.barcodeFormats);
|
|
156
|
+
}
|
|
157
|
+
if(!configuration.acceptedDocumentFormats.isEmpty()) {
|
|
158
|
+
b.setAcceptedDocumentFormats(configuration.acceptedDocumentFormats);
|
|
159
|
+
}
|
|
160
|
+
b.setEngineMode(configuration.engineMode);
|
|
161
|
+
|
|
162
|
+
if(configuration.additionalConfiguration != null) {
|
|
163
|
+
b.modifyAdditionalConfig(ab -> {
|
|
164
|
+
final BarcodeScannerAdditionalConfig config = configuration.additionalConfiguration;
|
|
165
|
+
ab.setMinimumTextLength(config.getMinimumTextLength());
|
|
166
|
+
ab.setMaximumTextLength(config.getMaximumTextLength());
|
|
167
|
+
ab.setMsiPlesseyChecksumAlgorithms(config.getMsiPlesseyChecksumAlgorithms());
|
|
168
|
+
ab.setStripCheckDigits(config.getStripCheckDigits());
|
|
169
|
+
ab.setGs1DecodingEnabled(config.getGs1DecodingEnabled());
|
|
170
|
+
ab.setMinimum1DQuietZoneSize(config.getMinimum1DQuietZoneSize());
|
|
171
|
+
return Unit.INSTANCE;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return Unit.INSTANCE;
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Barcode Detector Frame Handler - Result Handler
|
|
181
|
+
@Override
|
|
182
|
+
@SuppressWarnings("unchecked")
|
|
183
|
+
public boolean handle(@NotNull FrameHandlerResult<? extends BarcodeScanningResult, ? extends SdkLicenseError> frameHandlerResult) {
|
|
184
|
+
if (frameHandlerResult instanceof FrameHandlerResult.Success) {
|
|
185
|
+
handleSuccess((FrameHandlerResult.Success<BarcodeScanningResult>) frameHandlerResult);
|
|
186
|
+
}
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private void handleSuccess(final FrameHandlerResult.Success<BarcodeScanningResult> result) {
|
|
191
|
+
if (result == null || result.getValue() == null) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
List<BarcodeItem> barcodeItems;
|
|
196
|
+
if (configuration.barcodeFilter != null) {
|
|
197
|
+
barcodeItems = JSONUtils.getBarcodeItemsFromItemListWithFilter(result.getValue().getBarcodeItems(), configuration.barcodeFilter);
|
|
198
|
+
} else {
|
|
199
|
+
barcodeItems = result.getValue().getBarcodeItems();
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
sendResult(barcodeItems);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private void sendResult(final List<BarcodeItem> barcodeItems) {
|
|
206
|
+
if (barcodeItems == null || barcodeItems.size() == 0) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
final WritableArray barcodes = new WritableNativeArray();
|
|
211
|
+
|
|
212
|
+
for (BarcodeItem item: barcodeItems) {
|
|
213
|
+
final WritableMap barcode = new JSONUtils.WritableMapBuilder()
|
|
214
|
+
.putString("text", item.getText())
|
|
215
|
+
.putString("type", item.getBarcodeFormat().name())
|
|
216
|
+
.putString("textWithExtension", item.getTextWithExtension())
|
|
217
|
+
.build();
|
|
218
|
+
barcodes.pushMap(barcode);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
final WritableMap result = new JSONUtils.WritableMapBuilder()
|
|
222
|
+
.putString("status", "OK")
|
|
223
|
+
.putArray("barcodes", barcodes)
|
|
224
|
+
.build();
|
|
225
|
+
|
|
226
|
+
final WritableMap data = new JSONUtils.WritableMapBuilder()
|
|
227
|
+
.putMap("result", result)
|
|
228
|
+
.build();
|
|
229
|
+
|
|
230
|
+
eventEmitter.emitEvent(NativeEvents.BARCODE_SCANNER_RESULT, data);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
@Override
|
|
234
|
+
public RNScanbotNativeComponentUi createNativeComponentUi(@NonNull ReactContext reactContext) {
|
|
235
|
+
this.barcodeCameraUi = new RNScanbotBarcodeCameraUi(reactContext);
|
|
236
|
+
return this.barcodeCameraUi;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/*
|
|
240
|
+
* Creates the root view for the component
|
|
241
|
+
*/
|
|
242
|
+
@Override
|
|
243
|
+
public RNScanbotNativeComponentRootView getRootView() { return this.barcodeCameraUi.getRootView(); }
|
|
244
|
+
|
|
245
|
+
/*
|
|
246
|
+
* Returns the list of native events
|
|
247
|
+
*/
|
|
248
|
+
@Override
|
|
249
|
+
public RNScanbotEventEmitter.NativeEvent[] getNativeEvents() { return NativeEvents.values(); }
|
|
250
|
+
|
|
251
|
+
@Override
|
|
252
|
+
public RNScanbotEventReceiver.JavaScriptEvent[] getJavascriptEvents() {
|
|
253
|
+
return new RNScanbotEventReceiver.JavaScriptEvent[] {};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/*
|
|
257
|
+
* Applies the given configuration to the component (JSON Configuration)
|
|
258
|
+
*/
|
|
259
|
+
@Override
|
|
260
|
+
public void applyConfiguration(@NonNull final ReadableMap configuration) {
|
|
261
|
+
applyConfiguration(RNScanbotBarcodeCameraConfiguration.fromJsonMap(configuration));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/*
|
|
265
|
+
* Applies the given configuration to the component (Native Configuration)
|
|
266
|
+
*/
|
|
267
|
+
public void applyConfiguration(@NonNull final RNScanbotBarcodeCameraConfiguration configuration) {
|
|
268
|
+
this.configuration = configuration;
|
|
269
|
+
if (isInitialized) {
|
|
270
|
+
applyConfiguration();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private void checkPermissions() {
|
|
275
|
+
if (this.reactContext == null) { return; }
|
|
276
|
+
Activity activity = reactContext.getCurrentActivity();
|
|
277
|
+
|
|
278
|
+
if (activity != null && ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
|
279
|
+
ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.CAMERA }, REQUEST_PERMISSION_CODE);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
@ColorInt
|
|
284
|
+
public static int colorWithAlpha(@ColorInt int color, float factor) {
|
|
285
|
+
int alpha = Math.round(Color.alpha(color) * factor);
|
|
286
|
+
int red = Color.red(color);
|
|
287
|
+
int green = Color.green(color);
|
|
288
|
+
int blue = Color.blue(color);
|
|
289
|
+
return Color.argb(alpha, red, green, blue);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview
|
|
1
|
+
package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview;;
|
|
2
2
|
|
|
3
3
|
import android.graphics.Color;
|
|
4
4
|
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
|
|
7
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
8
|
+
|
|
5
9
|
import java.util.ArrayList;
|
|
6
10
|
import java.util.List;
|
|
7
11
|
|
|
@@ -9,17 +13,21 @@ import io.scanbot.sdk.barcode.entity.BarcodeDocumentFormat;
|
|
|
9
13
|
import io.scanbot.sdk.barcode.entity.BarcodeFormat;
|
|
10
14
|
import io.scanbot.sdk.barcode.entity.BarcodeScannerAdditionalConfig;
|
|
11
15
|
import io.scanbot.sdk.barcode.entity.EngineMode;
|
|
16
|
+
import io.scanbot.barcodesdk.plugin.reactnative.utils.JSONUtils;
|
|
17
|
+
import io.scanbot.barcodesdk.plugin.reactnative.ObjectMapper;
|
|
12
18
|
import io.scanbot.sdk.ui.camera.FinderAspectRatio;
|
|
19
|
+
import io.scanbot.sdk.ui.view.barcode.configuration.BarcodeFilter;
|
|
13
20
|
|
|
14
21
|
@SuppressWarnings("unused")
|
|
15
|
-
public class
|
|
16
|
-
|
|
22
|
+
public class RNScanbotBarcodeCameraConfiguration {
|
|
23
|
+
// Manually mapped properties (must NOT have a getter and setter)
|
|
17
24
|
public List<BarcodeFormat> barcodeFormats = new ArrayList<>();
|
|
18
25
|
public List<BarcodeDocumentFormat> acceptedDocumentFormats = new ArrayList<>();
|
|
19
26
|
public EngineMode engineMode;
|
|
20
27
|
public BarcodeScannerAdditionalConfig additionalConfiguration;
|
|
28
|
+
public BarcodeFilter barcodeFilter;
|
|
21
29
|
|
|
22
|
-
// Automatically mapped properties
|
|
30
|
+
// Automatically mapped properties (must have a getter and a setter with the same name)
|
|
23
31
|
private boolean shouldUseFinderView = false;
|
|
24
32
|
private int finderLineWidth = 1;
|
|
25
33
|
private int finderLineColor = Color.WHITE;
|
|
@@ -110,4 +118,46 @@ public class ScanbotBarcodeCameraViewConfiguration {
|
|
|
110
118
|
public FinderAspectRatio getFinderAspectRatio() {
|
|
111
119
|
return finderAspectRatio;
|
|
112
120
|
}
|
|
121
|
+
|
|
122
|
+
@NonNull
|
|
123
|
+
public static RNScanbotBarcodeCameraConfiguration fromJsonMap(ReadableMap jsonConfig) {
|
|
124
|
+
final RNScanbotBarcodeCameraConfiguration nativeConfig = new RNScanbotBarcodeCameraConfiguration();
|
|
125
|
+
|
|
126
|
+
// Automatic Mapping
|
|
127
|
+
try {
|
|
128
|
+
ObjectMapper.map(jsonConfig, nativeConfig);
|
|
129
|
+
} catch (Exception e) {
|
|
130
|
+
final String msg = "Unexpected ERROR while parsing the given JSON configuration: " + e.getMessage();
|
|
131
|
+
throw new ObjectMapper.InvalidJSONException(msg);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Custom Mapping
|
|
135
|
+
if (jsonConfig.hasKey("barcodeFormats")) {
|
|
136
|
+
nativeConfig.barcodeFormats = JSONUtils.extractBarcodeFormats(jsonConfig);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (jsonConfig.hasKey("acceptedDocumentFormats")) {
|
|
140
|
+
nativeConfig.acceptedDocumentFormats = JSONUtils.extractBarcodeDocumentFormats(jsonConfig);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (jsonConfig.hasKey("cameraZoomFactor")) {
|
|
144
|
+
float value = (float) jsonConfig.getDouble("cameraZoomFactor");
|
|
145
|
+
if (value != -1) {
|
|
146
|
+
nativeConfig.setCameraZoomFactor(value);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (jsonConfig.hasKey("flashEnabled")) {
|
|
151
|
+
nativeConfig.setFlashEnabled(jsonConfig.getBoolean("flashEnabled"));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (jsonConfig.hasKey("barcodeFilter")) {
|
|
155
|
+
nativeConfig.barcodeFilter = JSONUtils.extractBarcodeFilter(jsonConfig);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
nativeConfig.additionalConfiguration = JSONUtils.extractBarcodeScannerAdditionalConfig(jsonConfig);
|
|
159
|
+
nativeConfig.engineMode = JSONUtils.extractEngineMode(jsonConfig);
|
|
160
|
+
|
|
161
|
+
return nativeConfig;
|
|
162
|
+
}
|
|
113
163
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
package io.scanbot.barcodesdk.plugin.reactnative.components.barcodecameraview;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.util.Size;
|
|
5
|
+
import android.view.LayoutInflater;
|
|
6
|
+
import android.widget.FrameLayout;
|
|
7
|
+
|
|
8
|
+
import androidx.annotation.NonNull;
|
|
9
|
+
|
|
10
|
+
import com.facebook.react.bridge.ReactContext;
|
|
11
|
+
|
|
12
|
+
import io.scanbot.barcodesdk.plugin.reactnative.R;
|
|
13
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.RNScanbotNativeComponentUi;
|
|
14
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentFrameLayout;
|
|
15
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentRootView;
|
|
16
|
+
import io.scanbot.sdk.ui.camera.FinderOverlayView;
|
|
17
|
+
import io.scanbot.sdk.ui.camera.ScanbotCameraXView;
|
|
18
|
+
|
|
19
|
+
public class RNScanbotBarcodeCameraUi extends RNScanbotNativeComponentUi {
|
|
20
|
+
|
|
21
|
+
private FinderOverlayView finderOverlayView;
|
|
22
|
+
private ScanbotCameraXView cameraView;
|
|
23
|
+
private RNScanbotNativeComponentFrameLayout cameraLayout;
|
|
24
|
+
|
|
25
|
+
public RNScanbotBarcodeCameraUi(@NonNull final ReactContext reactContext) {
|
|
26
|
+
super(reactContext);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
protected RNScanbotNativeComponentRootView createRootView(@NonNull final ReactContext reactContext) {
|
|
31
|
+
final Activity activity = reactContext.getCurrentActivity();
|
|
32
|
+
if (activity == null) {
|
|
33
|
+
throw new IllegalStateException("ERROR: Cannot retrieve current activity");
|
|
34
|
+
}
|
|
35
|
+
return setupUIAndGetRootView(activity);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public FinderOverlayView getFinderOverlayView() {
|
|
39
|
+
return this.finderOverlayView;
|
|
40
|
+
}
|
|
41
|
+
public ScanbotCameraXView getCameraView() {
|
|
42
|
+
return this.cameraView;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* Takes care of inflating the XML layout, retrieving the views and configuring them (UI)
|
|
47
|
+
*/
|
|
48
|
+
private RNScanbotNativeComponentRootView setupUIAndGetRootView(@NonNull final Activity activity) {
|
|
49
|
+
// Retrieves Root View from XML layout
|
|
50
|
+
final RNScanbotNativeComponentRootView rootView = (RNScanbotNativeComponentRootView) LayoutInflater
|
|
51
|
+
.from(activity)
|
|
52
|
+
.inflate(R.layout.component_barcode_camera_view, null, false);
|
|
53
|
+
|
|
54
|
+
// Retrieves the inner Camera Layout and configures it
|
|
55
|
+
cameraLayout = rootView.findViewById(R.id.barcode_camera_layout);
|
|
56
|
+
cameraLayout.setZ(-1.0f);
|
|
57
|
+
cameraLayout.setLayoutParams(new FrameLayout.LayoutParams(
|
|
58
|
+
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
59
|
+
FrameLayout.LayoutParams.MATCH_PARENT));
|
|
60
|
+
|
|
61
|
+
finderOverlayView = rootView.findViewById(R.id.barcode_finder_overlay);
|
|
62
|
+
cameraView = rootView.findViewById(R.id.barcode_camera);
|
|
63
|
+
|
|
64
|
+
return rootView;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@Override
|
|
68
|
+
protected void onViewsRemeasured() {
|
|
69
|
+
cameraView.stopPreview();
|
|
70
|
+
|
|
71
|
+
final Size cameraViewSize = new Size(
|
|
72
|
+
cameraLayout.getWidth(),
|
|
73
|
+
cameraLayout.getHeight()
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
cameraView.setPreviewFrameSize(cameraViewSize);
|
|
77
|
+
cameraView.setAnalyzerFrameSize(cameraViewSize);
|
|
78
|
+
|
|
79
|
+
cameraView.startPreview();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
package io.scanbot.barcodesdk.plugin.reactnative.components.base;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
import androidx.annotation.Nullable;
|
|
5
|
+
|
|
6
|
+
import com.facebook.react.bridge.ReactContext;
|
|
7
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
8
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
9
|
+
|
|
10
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventEmitter;
|
|
11
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventReceiver;
|
|
12
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.views.RNScanbotNativeComponentRootView;
|
|
13
|
+
import kotlin.NotImplementedError;
|
|
14
|
+
|
|
15
|
+
public abstract class RNScanbotNativeComponent {
|
|
16
|
+
// The UI layer of the native component
|
|
17
|
+
private RNScanbotNativeComponentUi nativeComponentUi;
|
|
18
|
+
// Internally set to true when the UI root view is recreated
|
|
19
|
+
private boolean isDirty;
|
|
20
|
+
|
|
21
|
+
public RNScanbotNativeComponent(@NonNull final ReactContext reactContext) {
|
|
22
|
+
this.nativeComponentUi = createNativeComponentUi(reactContext);
|
|
23
|
+
}
|
|
24
|
+
/*
|
|
25
|
+
* Every native component must have a UI component of type RNScanbotNativeComponentUi.
|
|
26
|
+
* You must override this method to provide your own custom implementation for it.
|
|
27
|
+
*/
|
|
28
|
+
public RNScanbotNativeComponentUi createNativeComponentUi(@NonNull final ReactContext reactContext) {
|
|
29
|
+
throw new NotImplementedError("You must override createNativeComponentUi() in your Native Component implementation");
|
|
30
|
+
}
|
|
31
|
+
/*
|
|
32
|
+
* Initialize the component
|
|
33
|
+
*/
|
|
34
|
+
public abstract void initializeComponent();
|
|
35
|
+
/*
|
|
36
|
+
* You must override this method to write your implementation mapping the JSON configuration
|
|
37
|
+
* that is passed to the component from the React Native JavaScript layer
|
|
38
|
+
*/
|
|
39
|
+
public abstract void applyConfiguration(@NonNull final ReadableMap configuration);
|
|
40
|
+
/*
|
|
41
|
+
* This is called when a new view instance is requested to the ViewManager.
|
|
42
|
+
* It mostly disposes listeners and callbacks, and the .dispose() function of
|
|
43
|
+
* the UI Component can be overridden to add custom disposal methods.
|
|
44
|
+
*/
|
|
45
|
+
public void recreateWithContext(final ReactContext reactContext) {
|
|
46
|
+
this.nativeComponentUi.dispose();
|
|
47
|
+
this.nativeComponentUi = createNativeComponentUi(reactContext);
|
|
48
|
+
this.nativeComponentUi._setOnViewRecreatedListener(() -> this.isDirty = true);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
* Called on componentDidMount
|
|
53
|
+
*/
|
|
54
|
+
public void onComponentDidMount() {
|
|
55
|
+
this.initializeComponent();
|
|
56
|
+
}
|
|
57
|
+
/*
|
|
58
|
+
* Called on componentWillUnmount
|
|
59
|
+
*/
|
|
60
|
+
public void onComponentWillUnmount() {}
|
|
61
|
+
/*
|
|
62
|
+
* Called on componentDidUpdate
|
|
63
|
+
*/
|
|
64
|
+
public void onComponentDidUpdate() {
|
|
65
|
+
if (this.isDirty) {
|
|
66
|
+
initializeComponent();
|
|
67
|
+
this.isDirty = false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/*
|
|
71
|
+
* Called on orientationChanged
|
|
72
|
+
*/
|
|
73
|
+
public void onOrientationChanged() {}
|
|
74
|
+
/*
|
|
75
|
+
* Creates the root view for the component
|
|
76
|
+
*/
|
|
77
|
+
public RNScanbotNativeComponentRootView getRootView() { return this.nativeComponentUi.getRootView(); }
|
|
78
|
+
/*
|
|
79
|
+
* Returns the list of Native events (from Native to JavaScript); default: empty
|
|
80
|
+
*/
|
|
81
|
+
public RNScanbotEventEmitter.NativeEvent[] getNativeEvents() { return new RNScanbotEventEmitter.NativeEvent[] {}; }
|
|
82
|
+
/*
|
|
83
|
+
* Returns the list of JavaScript events (from JavaScript to Native); default: empty
|
|
84
|
+
*/
|
|
85
|
+
public RNScanbotEventReceiver.JavaScriptEvent[] getJavascriptEvents() { return new RNScanbotEventReceiver.JavaScriptEvent[] {}; }
|
|
86
|
+
/*
|
|
87
|
+
* Override this to handle events defined in the getJavascriptEvents method; default: empty
|
|
88
|
+
*/
|
|
89
|
+
public void handleJavascriptEvent(RNScanbotEventReceiver.JavaScriptEvent event, @Nullable ReadableArray args) {}
|
|
90
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
package io.scanbot.barcodesdk.plugin.reactnative.components.base;
|
|
2
|
+
|
|
3
|
+
import android.widget.FrameLayout;
|
|
4
|
+
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
import androidx.annotation.Nullable;
|
|
7
|
+
|
|
8
|
+
import com.facebook.react.ReactRootView;
|
|
9
|
+
import com.facebook.react.bridge.ReactContext;
|
|
10
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
11
|
+
import com.facebook.react.bridge.ReadableMap;
|
|
12
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
13
|
+
import com.facebook.react.uimanager.ViewGroupManager;
|
|
14
|
+
import com.facebook.react.uimanager.annotations.ReactProp;
|
|
15
|
+
|
|
16
|
+
import java.util.ArrayList;
|
|
17
|
+
import java.util.List;
|
|
18
|
+
import java.util.Map;
|
|
19
|
+
|
|
20
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventEmitter;
|
|
21
|
+
import io.scanbot.barcodesdk.plugin.reactnative.components.base.communication.RNScanbotEventReceiver;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* This class takes care of setting up a ViewManager that:
|
|
25
|
+
* - Returns the correct name for registering the view in React Native
|
|
26
|
+
* - Accepts a JSON configuration under the prop name 'configuration' and passes it to the native component
|
|
27
|
+
* - Sets up events (both JS -> Java and Java -> JS) and it handles common core events
|
|
28
|
+
* automatically (like componentDidMount, orientationChanged etc.)
|
|
29
|
+
* - Takes care of creating (and recreating) the root view and passing it to the React Native View Manager
|
|
30
|
+
* @param <T> Your custom type that extends RNScanbotNativeComponent
|
|
31
|
+
*/
|
|
32
|
+
public abstract class RNScanbotNativeComponentManager<T extends RNScanbotNativeComponent> extends ViewGroupManager<ReactRootView> implements RNScanbotEventReceiver.IEventHandler {
|
|
33
|
+
protected final ReactContext reactContext;
|
|
34
|
+
protected final T nativeComponent;
|
|
35
|
+
protected RNScanbotEventReceiver eventReceiver;
|
|
36
|
+
private boolean isInitialized = false;
|
|
37
|
+
|
|
38
|
+
public RNScanbotNativeComponentManager(
|
|
39
|
+
@NonNull final ReactContext reactContext,
|
|
40
|
+
@NonNull final T nativeComponent
|
|
41
|
+
) {
|
|
42
|
+
super();
|
|
43
|
+
this.reactContext = reactContext;
|
|
44
|
+
this.nativeComponent = nativeComponent;
|
|
45
|
+
this.eventReceiver = new RNScanbotEventReceiver(this, nativeComponent.getJavascriptEvents());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@ReactProp(name = "configuration")
|
|
49
|
+
public void setConfiguration(FrameLayout frameLayout, ReadableMap configuration) {
|
|
50
|
+
final RNScanbotNativeComponent component = nativeComponent;
|
|
51
|
+
if (component == null) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
component.applyConfiguration(configuration);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected void componentDidMount() { this.nativeComponent.onComponentDidMount(); }
|
|
58
|
+
protected void componentWillUnmount() { this.nativeComponent.onComponentWillUnmount(); }
|
|
59
|
+
protected void componentDidUpdate() { this.nativeComponent.onComponentDidUpdate(); }
|
|
60
|
+
protected void orientationChanged() { this.nativeComponent.onOrientationChanged(); }
|
|
61
|
+
|
|
62
|
+
/* --------------------------------------------------*/
|
|
63
|
+
/* Internal stuff you probably shouldn't worry about */
|
|
64
|
+
/* --------------------------------------------------*/
|
|
65
|
+
|
|
66
|
+
// Maps native events (from Native to JS)
|
|
67
|
+
@Nullable
|
|
68
|
+
@Override
|
|
69
|
+
public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
|
|
70
|
+
final RNScanbotEventEmitter.NativeEvent[] commonEvents = RNScanbotEventEmitter.CommonEvents.values();
|
|
71
|
+
final RNScanbotEventEmitter.NativeEvent[] customEvents = nativeComponent.getNativeEvents();
|
|
72
|
+
final RNScanbotEventEmitter.NativeEvent[] allEvents = RNScanbotEventEmitter.concatEvents(commonEvents, customEvents);
|
|
73
|
+
return RNScanbotEventEmitter.getMapForNativeEvents(allEvents);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Creates the view instance when requested from the RN layer
|
|
77
|
+
@NonNull
|
|
78
|
+
@Override
|
|
79
|
+
protected ReactRootView createViewInstance(@NonNull final ThemedReactContext reactContext) {
|
|
80
|
+
if (isInitialized) {
|
|
81
|
+
this.nativeComponent.recreateWithContext(reactContext);
|
|
82
|
+
}
|
|
83
|
+
isInitialized = true;
|
|
84
|
+
return this.nativeComponent.getRootView();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Parses notifications from the EventReceiver:
|
|
88
|
+
// - It handles common events and stops them from getting to the inheriting class
|
|
89
|
+
// - It sends non-common events to the handleJavascriptEvent delegate method in the inheriting class
|
|
90
|
+
@Override
|
|
91
|
+
public void eventHandler_eventReceived(RNScanbotEventReceiver.JavaScriptEvent event, @Nullable ReadableArray args) {
|
|
92
|
+
List<RNScanbotEventReceiver.JavaScriptEvent> handledEvents = new ArrayList<>();
|
|
93
|
+
RNScanbotEventReceiver.CommonEvents commonEvent = eventReceiver.getCommonEventFromName(event.getName());
|
|
94
|
+
if (commonEvent == null) {
|
|
95
|
+
this.nativeComponent.handleJavascriptEvent(event, args);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.handleCommonEvent(commonEvent, args);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Calls the common events handlers
|
|
103
|
+
private void handleCommonEvent(RNScanbotEventReceiver.CommonEvents commonEvent, @Nullable ReadableArray args) {
|
|
104
|
+
switch (commonEvent) {
|
|
105
|
+
case COMPONENT_DID_UPDATE:
|
|
106
|
+
componentDidUpdate();
|
|
107
|
+
break;
|
|
108
|
+
case COMPONENT_DID_MOUNT:
|
|
109
|
+
componentDidMount();
|
|
110
|
+
break;
|
|
111
|
+
case COMPONENT_WILL_UNMOUNT:
|
|
112
|
+
componentWillUnmount();
|
|
113
|
+
break;
|
|
114
|
+
case ORIENTATION_CHANGED:
|
|
115
|
+
orientationChanged();
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Maps JavaScript events (from JavaScript to Native)
|
|
121
|
+
@Nullable
|
|
122
|
+
@Override
|
|
123
|
+
public Map<String, Integer> getCommandsMap() {
|
|
124
|
+
return eventReceiver.getCommandsMap();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Hands over JavaScript events to our beatufiul event receiver
|
|
128
|
+
@Override
|
|
129
|
+
public void receiveCommand(@NonNull ReactRootView root, String commandId, @Nullable ReadableArray args) {
|
|
130
|
+
super.receiveCommand(root, commandId, args);
|
|
131
|
+
eventReceiver.receiveCommand(commandId, args);
|
|
132
|
+
}
|
|
133
|
+
}
|