anyline-ocr-react-native-module 43.0.0 → 44.1.0

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.
Files changed (107) hide show
  1. package/.idea/modules.xml +8 -0
  2. package/.idea/plugin.iml +9 -0
  3. package/.idea/vcs.xml +6 -0
  4. package/android/.gradle/6.7/executionHistory/executionHistory.lock +0 -0
  5. package/android/.gradle/6.7/fileChanges/last-build.bin +0 -0
  6. package/android/.gradle/6.7/fileHashes/fileHashes.bin +0 -0
  7. package/android/.gradle/6.7/fileHashes/fileHashes.lock +0 -0
  8. package/android/.gradle/6.7/gc.properties +0 -0
  9. package/android/.gradle/7.0/dependencies-accessors/dependencies-accessors.lock +0 -0
  10. package/android/.gradle/7.0/dependencies-accessors/gc.properties +0 -0
  11. package/android/.gradle/7.0/executionHistory/executionHistory.lock +0 -0
  12. package/android/.gradle/7.0/fileChanges/last-build.bin +0 -0
  13. package/android/.gradle/7.0/fileHashes/fileHashes.bin +0 -0
  14. package/android/.gradle/7.0/fileHashes/fileHashes.lock +0 -0
  15. package/android/.gradle/7.0/gc.properties +0 -0
  16. package/android/.gradle/7.3/checksums/checksums.lock +0 -0
  17. package/android/.gradle/7.3/dependencies-accessors/dependencies-accessors.lock +0 -0
  18. package/android/.gradle/7.3/dependencies-accessors/gc.properties +0 -0
  19. package/android/.gradle/7.3/fileChanges/last-build.bin +0 -0
  20. package/android/.gradle/7.3/fileHashes/fileHashes.lock +0 -0
  21. package/android/.gradle/7.3/gc.properties +0 -0
  22. package/android/.gradle/7.4/checksums/checksums.lock +0 -0
  23. package/android/.gradle/7.4/checksums/md5-checksums.bin +0 -0
  24. package/android/.gradle/7.4/checksums/sha1-checksums.bin +0 -0
  25. package/android/.gradle/7.4/dependencies-accessors/dependencies-accessors.lock +0 -0
  26. package/android/.gradle/7.4/dependencies-accessors/gc.properties +0 -0
  27. package/android/.gradle/7.4/executionHistory/executionHistory.lock +0 -0
  28. package/android/.gradle/7.4/fileChanges/last-build.bin +0 -0
  29. package/android/.gradle/7.4/fileHashes/fileHashes.bin +0 -0
  30. package/android/.gradle/7.4/fileHashes/fileHashes.lock +0 -0
  31. package/android/.gradle/7.4/fileHashes/resourceHashesCache.bin +0 -0
  32. package/android/.gradle/7.4/gc.properties +0 -0
  33. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  34. package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
  35. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  36. package/android/.gradle/checksums/checksums.lock +0 -0
  37. package/android/.gradle/checksums/md5-checksums.bin +0 -0
  38. package/android/.gradle/checksums/sha1-checksums.bin +0 -0
  39. package/android/.gradle/configuration-cache/gc.properties +0 -0
  40. package/android/.gradle/vcs-1/gc.properties +0 -0
  41. package/android/.idea/compiler.xml +6 -0
  42. package/android/.idea/gradle.xml +19 -0
  43. package/android/.idea/jarRepositories.xml +40 -0
  44. package/android/.idea/misc.xml +10 -0
  45. package/android/.idea/vcs.xml +7 -0
  46. package/android/.settings/org.eclipse.buildship.core.prefs +13 -0
  47. package/android/build.gradle +9 -1
  48. package/android/gradle/wrapper/gradle-wrapper.properties +2 -2
  49. package/android/gradlew +192 -108
  50. package/android/gradlew.bat +10 -7
  51. package/android/local.properties +8 -0
  52. package/android/src/main/assets/info_sound_TIN.wav +0 -0
  53. package/android/src/main/java/com/anyline/reactnative/AnylineSDKPlugin.java +16 -22
  54. package/android/src/main/java/com/anyline/reactnative/FeedbackConfig.java +58 -0
  55. package/android/src/main/java/com/anyline/reactnative/ImageTextConfig.java +48 -0
  56. package/android/src/main/java/com/anyline/reactnative/InstructionConfig.java +19 -0
  57. package/android/src/main/java/com/anyline/reactnative/ScanActivity.java +180 -1
  58. package/android/src/main/res/drawable/dot_overlay.png +0 -0
  59. package/android/src/main/res/drawable-hdpi/ic_flash_auto.png +0 -0
  60. package/android/src/main/res/drawable-hdpi/ic_flash_off.png +0 -0
  61. package/android/src/main/res/drawable-hdpi/ic_flash_on.png +0 -0
  62. package/android/src/main/res/drawable-hdpi/ic_move_back.png +0 -0
  63. package/android/src/main/res/drawable-hdpi/ic_move_closer.png +0 -0
  64. package/android/src/main/res/drawable-hdpi/ic_too_bright.png +0 -0
  65. package/android/src/main/res/drawable-hdpi/ic_too_dark.png +0 -0
  66. package/android/src/main/res/drawable-hdpi/ic_wrong_format.png +0 -0
  67. package/android/src/main/res/drawable-mdpi/ic_flash_auto.png +0 -0
  68. package/android/src/main/res/drawable-mdpi/ic_flash_off.png +0 -0
  69. package/android/src/main/res/drawable-mdpi/ic_flash_on.png +0 -0
  70. package/android/src/main/res/drawable-mdpi/ic_move_back.png +0 -0
  71. package/android/src/main/res/drawable-mdpi/ic_move_closer.png +0 -0
  72. package/android/src/main/res/drawable-mdpi/ic_too_bright.png +0 -0
  73. package/android/src/main/res/drawable-mdpi/ic_too_dark.png +0 -0
  74. package/android/src/main/res/drawable-mdpi/ic_wrong_format.png +0 -0
  75. package/android/src/main/res/drawable-xhdpi/ic_flash_auto.png +0 -0
  76. package/android/src/main/res/drawable-xhdpi/ic_flash_off.png +0 -0
  77. package/android/src/main/res/drawable-xhdpi/ic_flash_on.png +0 -0
  78. package/android/src/main/res/drawable-xhdpi/ic_move_back.png +0 -0
  79. package/android/src/main/res/drawable-xhdpi/ic_move_closer.png +0 -0
  80. package/android/src/main/res/drawable-xhdpi/ic_too_bright.png +0 -0
  81. package/android/src/main/res/drawable-xhdpi/ic_too_dark.png +0 -0
  82. package/android/src/main/res/drawable-xhdpi/ic_wrong_format.png +0 -0
  83. package/android/src/main/res/drawable-xxhdpi/ic_flash_auto.png +0 -0
  84. package/android/src/main/res/drawable-xxhdpi/ic_flash_off.png +0 -0
  85. package/android/src/main/res/drawable-xxhdpi/ic_flash_on.png +0 -0
  86. package/android/src/main/res/drawable-xxhdpi/ic_move_back.png +0 -0
  87. package/android/src/main/res/drawable-xxhdpi/ic_move_closer.png +0 -0
  88. package/android/src/main/res/drawable-xxhdpi/ic_too_bright.png +0 -0
  89. package/android/src/main/res/drawable-xxhdpi/ic_too_dark.png +0 -0
  90. package/android/src/main/res/drawable-xxhdpi/ic_wrong_format.png +0 -0
  91. package/android/src/main/res/drawable-xxxhdpi/ic_flash_auto.png +0 -0
  92. package/android/src/main/res/drawable-xxxhdpi/ic_flash_off.png +0 -0
  93. package/android/src/main/res/drawable-xxxhdpi/ic_flash_on.png +0 -0
  94. package/android/src/main/res/drawable-xxxhdpi/ic_move_back.png +0 -0
  95. package/android/src/main/res/drawable-xxxhdpi/ic_move_closer.png +0 -0
  96. package/android/src/main/res/drawable-xxxhdpi/ic_too_bright.png +0 -0
  97. package/android/src/main/res/drawable-xxxhdpi/ic_too_dark.png +0 -0
  98. package/android/src/main/res/drawable-xxxhdpi/ic_wrong_format.png +0 -0
  99. package/android/src/main/res/layout/activity_scan.xml +53 -2
  100. package/ios/ALJsonUIConfiguration.m +3 -1
  101. package/ios/ALNFCScanViewController.m +0 -10
  102. package/ios/ALPluginHelper.m +9 -23
  103. package/ios/ALPluginScanViewController.h +0 -2
  104. package/ios/ALPluginScanViewController.m +0 -1
  105. package/ios/AnylineReact.podspec +2 -2
  106. package/ios/AnylineSDKPlugin.m +1 -2
  107. package/package.json +8 -8
@@ -14,7 +14,7 @@
14
14
  @rem limitations under the License.
15
15
  @rem
16
16
 
17
- @if "%DEBUG%" == "" @echo off
17
+ @if "%DEBUG%"=="" @echo off
18
18
  @rem ##########################################################################
19
19
  @rem
20
20
  @rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
25
25
  if "%OS%"=="Windows_NT" setlocal
26
26
 
27
27
  set DIRNAME=%~dp0
28
- if "%DIRNAME%" == "" set DIRNAME=.
28
+ if "%DIRNAME%"=="" set DIRNAME=.
29
+ @rem This is normally unused
29
30
  set APP_BASE_NAME=%~n0
30
31
  set APP_HOME=%DIRNAME%
31
32
 
@@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
40
41
 
41
42
  set JAVA_EXE=java.exe
42
43
  %JAVA_EXE% -version >NUL 2>&1
43
- if "%ERRORLEVEL%" == "0" goto execute
44
+ if %ERRORLEVEL% equ 0 goto execute
44
45
 
45
46
  echo.
46
47
  echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -75,15 +76,17 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
75
76
 
76
77
  :end
77
78
  @rem End local scope for the variables with windows NT shell
78
- if "%ERRORLEVEL%"=="0" goto mainEnd
79
+ if %ERRORLEVEL% equ 0 goto mainEnd
79
80
 
80
81
  :fail
81
82
  rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82
83
  rem the _cmd.exe /c_ return code!
83
- if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84
- exit /b 1
84
+ set EXIT_CODE=%ERRORLEVEL%
85
+ if %EXIT_CODE% equ 0 set EXIT_CODE=1
86
+ if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
87
+ exit /b %EXIT_CODE%
85
88
 
86
89
  :mainEnd
87
90
  if "%OS%"=="Windows_NT" endlocal
88
91
 
89
- :omega
92
+ :omega
@@ -0,0 +1,8 @@
1
+ ## This file must *NOT* be checked into Version Control Systems,
2
+ # as it contains information specific to your local configuration.
3
+ #
4
+ # Location of the SDK. This is only used by Gradle.
5
+ # For customization when using a Version Control System, please read the
6
+ # header note.
7
+ #Wed Nov 16 08:15:22 CET 2022
8
+ sdk.dir=/Users/patrickfekete/Library/Android/sdk
@@ -94,6 +94,7 @@ class AnylineSDKPlugin extends ReactContextBaseJavaModule implements ResultRepor
94
94
  }
95
95
  } catch (JSONException e) {
96
96
  e.printStackTrace();
97
+ returnError(e.getMessage());
97
98
  }
98
99
  }
99
100
 
@@ -103,6 +104,7 @@ class AnylineSDKPlugin extends ReactContextBaseJavaModule implements ResultRepor
103
104
  AnylineSdk.init(license, reactContext);
104
105
  } catch (LicenseException e) {
105
106
  e.printStackTrace();
107
+ returnError(e.getMessage());
106
108
  }
107
109
  }
108
110
 
@@ -160,36 +162,34 @@ class AnylineSDKPlugin extends ReactContextBaseJavaModule implements ResultRepor
160
162
  private void scanAnyline4() {
161
163
  try {
162
164
  configObject = new JSONObject(this.config);
163
- // JSONObject options = configObject;
164
165
  if (configObject != null) {
165
166
  scan();
166
167
  } else {
167
168
  returnError("No ViewPlugin in config. Please check your configuration.");
168
169
  }
170
+ } catch (LicenseException e) {
171
+ e.printStackTrace();
172
+ returnError("LICENSE ERROR: " + e.getMessage());
169
173
  } catch (JSONException e) {
170
174
  e.printStackTrace();
175
+ returnError("JSON ERROR: " + e.getMessage());
171
176
  }
172
177
  }
173
178
 
174
- private void scan() {
179
+ private void scan() throws LicenseException, JSONException {
175
180
 
176
181
  Intent intent = new Intent(getCurrentActivity(), ScanActivity.class);
177
182
 
178
- try {
179
- configObject = new JSONObject(this.config);
180
-
181
- license = configObject.get("license").toString();
182
- JSONObject optionsJSONObject = configObject.optJSONObject("options");
183
+ configObject = new JSONObject(this.config);
183
184
 
184
- if (optionsJSONObject != null) {
185
- intent.putExtra(
186
- EXTRA_ENABLE_BARCODE_SCANNING,
187
- optionsJSONObject.optBoolean("nativeBarcodeEnabled", false)
188
- );
189
- }
185
+ license = configObject.get("license").toString();
186
+ JSONObject optionsJSONObject = configObject.optJSONObject("options");
190
187
 
191
- } catch (JSONException e) {
192
- returnError("JSON ERROR: " + e.getMessage());
188
+ if (optionsJSONObject != null) {
189
+ intent.putExtra(
190
+ EXTRA_ENABLE_BARCODE_SCANNING,
191
+ optionsJSONObject.optBoolean("nativeBarcodeEnabled", false)
192
+ );
193
193
  }
194
194
 
195
195
  intent.putExtra(EXTRA_LICENSE_KEY, license);
@@ -198,13 +198,7 @@ class AnylineSDKPlugin extends ReactContextBaseJavaModule implements ResultRepor
198
198
  ResultReporter.setListener(this);
199
199
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
200
200
 
201
- try {
202
- AnylineSdk.init(configObject.getString("license"), reactContext);
203
- } catch (LicenseException e) {
204
- e.printStackTrace();
205
- } catch (JSONException e) {
206
- e.printStackTrace();
207
- }
201
+ AnylineSdk.init(configObject.getString("license"), reactContext);
208
202
  reactContext.startActivityForResult(intent, 1111, intent.getExtras());
209
203
  }
210
204
 
@@ -0,0 +1,58 @@
1
+ package com.anyline.reactnative;
2
+
3
+ import android.content.Context;
4
+
5
+ import org.json.JSONObject;
6
+
7
+ import java.io.IOException;
8
+
9
+ import io.anyline.util.SoundUtil;
10
+
11
+ public class FeedbackConfig {
12
+ private SoundUtil soundUtil;
13
+ public ImageTextConfig wrongFormat = null;
14
+ public ImageTextConfig brightnessTooHigh = null;
15
+ public ImageTextConfig brightnessTooLow = null;
16
+ public ImageTextConfig distance = null;
17
+ public String sound = null;
18
+
19
+ public FeedbackConfig(Context context, JSONObject jsonObject) {
20
+ if (jsonObject.has("format")) {
21
+ wrongFormat = new ImageTextConfig(context, jsonObject.optJSONObject("format"));
22
+ }
23
+
24
+ if (jsonObject.has("distance")) {
25
+ distance = new ImageTextConfig(context, jsonObject.optJSONObject("distance"));
26
+ }
27
+
28
+ if (jsonObject.has("brightness")) {
29
+ JSONObject jsonBrightness = jsonObject.optJSONObject("brightness");
30
+ if (jsonBrightness.has("too_high")) {
31
+ brightnessTooHigh = new ImageTextConfig(context, jsonBrightness.optJSONObject("too_high"));
32
+ }
33
+ if (jsonBrightness.has("too_low")) {
34
+ brightnessTooLow = new ImageTextConfig(context, jsonBrightness.optJSONObject("too_low"));
35
+ }
36
+ }
37
+
38
+ if (jsonObject.has("sound")) {
39
+ sound = jsonObject.optString("sound", "");
40
+ soundUtil = new SoundUtil(context);
41
+ try {
42
+ soundUtil.loadSoundFromAssets(sound);
43
+ } catch (IOException e) {
44
+ soundUtil = null;
45
+ }
46
+ }
47
+
48
+ }
49
+
50
+ public void playBeepSound() {
51
+ if (sound != null) {
52
+ if (soundUtil != null) {
53
+ soundUtil.playSound(sound);
54
+ }
55
+ }
56
+ }
57
+
58
+ }
@@ -0,0 +1,48 @@
1
+ package com.anyline.reactnative;
2
+
3
+ import android.content.Context;
4
+ import android.content.res.AssetManager;
5
+ import android.graphics.Bitmap;
6
+ import android.graphics.BitmapFactory;
7
+ import android.util.Log;
8
+
9
+ import org.json.JSONObject;
10
+
11
+ import java.io.IOException;
12
+ import java.io.InputStream;
13
+
14
+ public class ImageTextConfig {
15
+ public String text = null;
16
+ public boolean hasImage = false;
17
+ public int imageResId = 0;
18
+
19
+ public ImageTextConfig(Context context, JSONObject jsonObject) {
20
+ if (jsonObject.has("text")) {
21
+ text = jsonObject.optString("text", "");
22
+ }
23
+
24
+ if (jsonObject.has("image")) {
25
+ imageResId = context.getResources().getIdentifier(jsonObject.optString("image", ""),
26
+ "drawable",
27
+ context.getPackageName());
28
+ hasImage = true;
29
+ }
30
+ }
31
+
32
+ protected Bitmap getBitmapFromAsset(Context context, String filePath) {
33
+ AssetManager assetManager = context.getAssets();
34
+
35
+ InputStream inputStream;
36
+ Bitmap bitmap = null;
37
+ try {
38
+ inputStream = assetManager.open(filePath);
39
+ bitmap = BitmapFactory.decodeStream(inputStream);
40
+ inputStream.close();
41
+ } catch (IOException e) {
42
+ Log.e("ImageTextConfig", e.getMessage());
43
+ }
44
+
45
+ return bitmap;
46
+ }
47
+
48
+ }
@@ -0,0 +1,19 @@
1
+ package com.anyline.reactnative;
2
+
3
+ import org.json.JSONObject;
4
+
5
+ public class InstructionConfig {
6
+ public String text = null;
7
+ public String textColor = null;
8
+ public String backgroundColor = null;
9
+
10
+ public InstructionConfig(JSONObject jsonObject) {
11
+ text = jsonObject.optString("text", "");
12
+ if (jsonObject.has("textColor")) {
13
+ textColor = jsonObject.optString("textColor", "");
14
+ }
15
+ if (jsonObject.has("backgroundColor")) {
16
+ backgroundColor = jsonObject.optString("backgroundColor", "");
17
+ }
18
+ }
19
+ }
@@ -6,9 +6,16 @@ import static com.anyline.reactnative.AnylineSDKPlugin.RESULT_ERROR;
6
6
 
7
7
  import android.content.Intent;
8
8
  import android.content.pm.ActivityInfo;
9
+ import android.graphics.Bitmap;
10
+ import android.graphics.Color;
11
+ import android.graphics.Rect;
9
12
  import android.os.Bundle;
10
- import android.view.Gravity;
13
+ import android.os.Handler;
14
+ import android.os.Looper;
15
+ import android.util.Pair;
11
16
  import android.view.View;
17
+ import android.view.Gravity;
18
+ import android.util.Log;
12
19
 
13
20
  import androidx.annotation.NonNull;
14
21
  import androidx.annotation.Nullable;
@@ -21,14 +28,21 @@ import org.json.JSONArray;
21
28
  import org.json.JSONException;
22
29
  import org.json.JSONObject;
23
30
 
31
+ import java.io.IOException;
32
+ import java.util.Timer;
33
+ import java.util.TimerTask;
34
+
24
35
  import io.anyline2.ScanResult;
36
+ import io.anyline2.view.BrightnessHelper;
25
37
  import io.anyline2.view.ScanView;
38
+ import io.anyline2.viewplugin.ScanViewPlugin;
26
39
  import io.anyline2.viewplugin.ViewPluginBase;
27
40
 
28
41
  public class ScanActivity extends AppCompatActivity {
29
42
 
30
43
  private static final String KEY_DEFAULT_ORIENTATION_APPLIED = "default_orientation_applied";
31
44
 
45
+ private Handler handler = new Handler(Looper.getMainLooper());
32
46
  private ActivityScanBinding binding;
33
47
  private ScanView scanView;
34
48
 
@@ -36,6 +50,21 @@ public class ScanActivity extends AppCompatActivity {
36
50
  private boolean defaultOrientationApplied;
37
51
  private int orientation;
38
52
 
53
+ private InstructionConfig instructionConfig = null;
54
+ private ImageTextConfig imageCutoutConfig = null;
55
+ private FeedbackConfig feedbackConfig = null;
56
+
57
+ private long cleanUIFeedbackIntervalMills = 2000L;
58
+ private Timer cleanUIFeedbackTimer = null;
59
+
60
+ private static final String FEEDBACK_SCANINFO_LIGHTINGCONDITION = "$lightingCondition";
61
+ private static final String FEEDBACK_SCANINFO_LIGHTINGCONDITION_TOODARK = "TOODARK";
62
+ private static final String FEEDBACK_SCANINFO_LIGHTINGCONDITION_TOOBRIGHT = "TOOBRIGHT";
63
+ private static final int FEEDBACK_RUNSKIPPED_WRONGFORMAT = 5006;
64
+ private static final int FEEDBACK_RUNSKIPPED_WRONGDATE = 5027;
65
+ private static final int FEEDBACK_RUNSKIPPED_TOOCLOSE = 5023;
66
+ private static final int FEEDBACK_RUNSKIPPED_TOOFAR = 5024;
67
+
39
68
  @Override
40
69
  protected void onCreate(@Nullable Bundle savedInstanceState) {
41
70
  super.onCreate(savedInstanceState);
@@ -59,11 +88,47 @@ public class ScanActivity extends AppCompatActivity {
59
88
 
60
89
  applyDefaultOrientation(configJSON);
61
90
  setupChangeOrientationButton(configJSON);
91
+ setupCustomUIFeedback(configJSON);
62
92
 
63
93
  scanView.init(configJSON);
64
94
 
65
95
  ViewPluginBase viewPluginBase = scanView.getScanViewPlugin();
66
96
 
97
+ viewPluginBase.scanInfoReceived = jsonObject -> {
98
+ if (jsonObject.optString("name", "").equals(FEEDBACK_SCANINFO_LIGHTINGCONDITION)) {
99
+ String lightingConditionValue = jsonObject.optString("value", "");
100
+ if (feedbackConfig != null) {
101
+ if (lightingConditionValue.equalsIgnoreCase(FEEDBACK_SCANINFO_LIGHTINGCONDITION_TOODARK)) {
102
+ if (feedbackConfig.brightnessTooLow != null) {
103
+ updateUIFeedback(feedbackConfig.brightnessTooLow);
104
+ }
105
+ }
106
+ else if (lightingConditionValue.equalsIgnoreCase(FEEDBACK_SCANINFO_LIGHTINGCONDITION_TOOBRIGHT)) {
107
+ if (feedbackConfig.brightnessTooHigh != null) {
108
+ updateUIFeedback(feedbackConfig.brightnessTooHigh);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ };
114
+
115
+ viewPluginBase.runSkippedReceived = jsonObject -> {
116
+ if (feedbackConfig != null) {
117
+ if (jsonObject.optInt("code", 0) == FEEDBACK_RUNSKIPPED_WRONGFORMAT
118
+ || jsonObject.optInt("code", 0) == FEEDBACK_RUNSKIPPED_WRONGDATE) {
119
+ if (feedbackConfig.wrongFormat != null) {
120
+ updateUIFeedback(feedbackConfig.wrongFormat);
121
+ }
122
+ }
123
+ if (jsonObject.optInt("code", 0) == FEEDBACK_RUNSKIPPED_TOOCLOSE
124
+ || jsonObject.optInt("code", 0) == FEEDBACK_RUNSKIPPED_TOOFAR) {
125
+ if (feedbackConfig.distance != null) {
126
+ updateUIFeedback(feedbackConfig.distance);
127
+ }
128
+ }
129
+ }
130
+ };
131
+
67
132
  viewPluginBase.resultReceived = scanResult -> {
68
133
  setResult(AnylineSDKPlugin.RESULT_OK);
69
134
  JSONObject resultObject = getResultWithImagePath(scanResult);
@@ -157,6 +222,120 @@ public class ScanActivity extends AppCompatActivity {
157
222
  }
158
223
  }
159
224
 
225
+ private void setupCustomUIFeedback(JSONObject configJSON) {
226
+ JSONObject optionsJsonObject = configJSON.optJSONObject("options");
227
+ if (optionsJsonObject != null) {
228
+ try {
229
+ if (optionsJsonObject.has("instruction")) {
230
+ instructionConfig = new InstructionConfig(optionsJsonObject.getJSONObject("instruction"));
231
+ }
232
+ if (optionsJsonObject.has("imageCutout")) {
233
+ imageCutoutConfig = new ImageTextConfig(this, optionsJsonObject.getJSONObject("imageCutout"));
234
+ }
235
+ if (optionsJsonObject.has("feedback")) {
236
+ feedbackConfig = new FeedbackConfig(this, optionsJsonObject.getJSONObject("feedback"));
237
+ }
238
+ }
239
+ catch (JSONException e) {
240
+ finishWithError("Error setting up UI Feedback: " + e.getMessage());
241
+ return;
242
+ }
243
+
244
+ if (instructionConfig != null) {
245
+ if (instructionConfig.text != null) {
246
+ binding.textviewInstruction.setText(instructionConfig.text);
247
+ }
248
+ if (instructionConfig.textColor != null) {
249
+ binding.textviewInstruction.setTextColor(Color.parseColor("#" + instructionConfig.textColor));
250
+ }
251
+ if (instructionConfig.backgroundColor != null) {
252
+ binding.textviewInstruction.setBackgroundColor(Color.parseColor("#" + instructionConfig.backgroundColor));
253
+ }
254
+ }
255
+
256
+ if (imageCutoutConfig != null) {
257
+ if (imageCutoutConfig.hasImage) {
258
+ binding.imageviewCutoutOverlay.setImageResource(imageCutoutConfig.imageResId);
259
+ }
260
+ }
261
+
262
+ }
263
+
264
+ scanView.onCutoutChanged = cutouts -> {
265
+ Pair<ScanViewPlugin, android.graphics.Rect> firstCutout = cutouts.get(0);
266
+
267
+ ScanViewPlugin scanViewPlugin = firstCutout.first;
268
+ if (scanViewPlugin != null) {
269
+ Rect rect = firstCutout.second;
270
+ if (rect != null) {
271
+ if (instructionConfig != null) {
272
+ CoordinatorLayout.LayoutParams instructionLayoutParams =
273
+ new CoordinatorLayout.LayoutParams(rect.width(), rect.top);
274
+ instructionLayoutParams.setMargins(rect.left, 0, rect.right, rect.top);
275
+ binding.layoutInstruction.setVisibility(View.VISIBLE);
276
+ binding.layoutInstruction.setLayoutParams(instructionLayoutParams);
277
+ binding.layoutInstruction.requestLayout();
278
+ }
279
+
280
+ if (imageCutoutConfig != null) {
281
+ CoordinatorLayout.LayoutParams imageCutoutLayoutParams =
282
+ new CoordinatorLayout.LayoutParams(rect.width(), rect.height());
283
+ imageCutoutLayoutParams.setMargins(rect.left, rect.top, rect.right, rect.bottom);
284
+ binding.imageviewCutoutOverlay.setVisibility(View.VISIBLE);
285
+ binding.imageviewCutoutOverlay.setLayoutParams(imageCutoutLayoutParams);
286
+ binding.imageviewCutoutOverlay.requestLayout();
287
+ }
288
+
289
+ if (feedbackConfig != null) {
290
+ CoordinatorLayout.LayoutParams feedbackLayoutParams =
291
+ new CoordinatorLayout.LayoutParams(rect.width(), scanView.getHeight());
292
+ feedbackLayoutParams.setMargins(rect.left, rect.bottom, rect.right, scanView.getBottom());
293
+ binding.layoutBrightDistanceFeedback.setVisibility(View.VISIBLE);
294
+ binding.layoutBrightDistanceFeedback.setLayoutParams(feedbackLayoutParams);
295
+ binding.layoutBrightDistanceFeedback.requestLayout();
296
+ }
297
+ }
298
+ }
299
+ };
300
+ }
301
+
302
+ private void updateUIFeedback(ImageTextConfig imageTextFeedback) {
303
+ if (imageTextFeedback.text != null) {
304
+ if (binding.textviewBrightDistanceFeedback.getText().equals(imageTextFeedback.text)) {
305
+ return;
306
+ }
307
+ }
308
+
309
+ handler.post(() -> {
310
+ if (imageTextFeedback.text != null) {
311
+ binding.textviewBrightDistanceFeedback.setText(imageTextFeedback.text);
312
+ }
313
+ if (imageTextFeedback.hasImage) {
314
+ binding.imageviewBrightDistanceFeedback.setImageResource(imageTextFeedback.imageResId);
315
+ }
316
+
317
+ if (feedbackConfig != null) {
318
+ if (feedbackConfig.sound != null) {
319
+ feedbackConfig.playBeepSound();
320
+ }
321
+ }
322
+
323
+ if (cleanUIFeedbackTimer != null) {
324
+ cleanUIFeedbackTimer.cancel();
325
+ }
326
+ cleanUIFeedbackTimer = new Timer();
327
+ cleanUIFeedbackTimer.schedule(new TimerTask() {
328
+ @Override
329
+ public void run() {
330
+ handler.post(() -> {
331
+ binding.textviewBrightDistanceFeedback.setText("");
332
+ binding.imageviewBrightDistanceFeedback.setImageBitmap(null);
333
+ });
334
+ }
335
+ }, cleanUIFeedbackIntervalMills);
336
+ });
337
+ }
338
+
160
339
  @NonNull
161
340
  private JSONObject getResultWithImagePath(ScanResult scanResult) {
162
341
  JSONObject resultObject = scanResult.getResult();