diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4723e9d..a0c8579 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
The changes documented here do not include those from the original repository.
+## [2.0.0]
+
+### 2025-08-22
+
+**BREAKING CHANGE:** The signature of `handleActivityResult` has changed - the onSuccess now returns `OSBARCScanResult` instead of just a string with the scanned code.
+
+- Add **hint** parameter to scan for specific barcode formats
+- Return the format of the scanned code inside the scan result.
+
## [1.2.1]
### 20205-08-18
diff --git a/docs/README.md b/docs/README.md
index cb115bb..8eb894c 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -46,7 +46,7 @@ In your app-level gradle file, import the OSBarcodeLib library like so:
```gradle
dependencies {
- implementation("com.github.outsystems:osbarcode-android:1.0.0@aar")
+ implementation("com.github.outsystems:osbarcode-android:2.0.0@aar")
}
```
@@ -72,7 +72,7 @@ A method that triggers the barcode reader/scanner, opening a new activity with t
- **scanOrientation**: An integer indicating which scan orientation to use - portrait, landscape, or adaptive.
- **scanButton**: A boolean that will display a scan button on the barcode reader. If true, scanning will only be triggered when pressing the button instead of automatically when framing the barcode. A second click on the button disables scannning.
- **scanText**: A string that contains the text to be displayed on the scan button. It will only be shown if **scanButton** is set to true.
- - **hint**: An integer that holds a hint to what type of barcode to look for. **This parameter isn't being used yet**.
+ - **hint**: An integer that holds a hint to what type of barcode to look for.
- **androidScanningLibrary**: A string which determines what barcode library to use - ML Kit or ZXing.
#### Usage
@@ -89,7 +89,7 @@ fun handleActivityResult(
requestCode: Int,
resultCode: Int,
intent: Intent?,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: (OSBARCError) -> Unit
)
```
diff --git a/pom.xml b/pom.xml
index 4d0a0cd..0de09bf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,5 +7,5 @@
4.0.0
io.ionic.libs
ionbarcode-android
- 1.2.1
+ 2.0.0
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt
index f238a1b..9b49da3 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCBarcodeAnalyzer.kt
@@ -6,6 +6,7 @@ import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import com.outsystems.plugins.barcode.controller.helper.OSBARCImageHelperInterface
import com.outsystems.plugins.barcode.model.OSBARCError
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
import com.outsystems.plugins.barcode.view.ui.theme.SizeRatioHeight
import com.outsystems.plugins.barcode.view.ui.theme.SizeRatioWidth
import java.lang.Exception
@@ -17,7 +18,7 @@ import java.lang.Exception
class OSBARCBarcodeAnalyzer(
private val scanLibrary: OSBARCScanLibraryInterface,
private val imageHelper: OSBARCImageHelperInterface,
- private val onBarcodeScanned: (String) -> Unit,
+ private val onBarcodeScanned: (OSBARCScanResult) -> Unit,
private val onScanningError: (OSBARCError) -> Unit
): ImageAnalysis.Analyzer {
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCController.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCController.kt
index cff4957..81aaefe 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCController.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCController.kt
@@ -3,8 +3,10 @@ package com.outsystems.plugins.barcode.controller
import android.app.Activity
import android.content.Intent
import android.util.Log
+import androidx.core.content.IntentCompat
import com.outsystems.plugins.barcode.model.OSBARCError
import com.outsystems.plugins.barcode.model.OSBARCScanParameters
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
import com.outsystems.plugins.barcode.view.OSBARCScannerActivity
/**
@@ -46,15 +48,17 @@ class OSBARCController {
requestCode: Int,
resultCode: Int,
intent: Intent?,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: (OSBARCError) -> Unit
) {
when (requestCode) {
SCAN_REQUEST_CODE -> {
when (resultCode) {
Activity.RESULT_OK -> {
- val result = intent?.extras?.getString(SCAN_RESULT)
- if (result.isNullOrEmpty()) {
+ val result: OSBARCScanResult? = intent?.let {
+ IntentCompat.getSerializableExtra(intent, SCAN_RESULT, OSBARCScanResult::class.java)
+ }
+ if (result == null || result.text.isEmpty()) {
onError(OSBARCError.SCANNING_GENERAL_ERROR)
return
}
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCMLKitWrapper.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCMLKitWrapper.kt
index 6fa7a5e..a3ae3e1 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCMLKitWrapper.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCMLKitWrapper.kt
@@ -3,8 +3,11 @@ package com.outsystems.plugins.barcode.controller
import android.graphics.Bitmap
import android.util.Log
import androidx.camera.core.ImageProxy
+import com.google.mlkit.vision.barcode.common.Barcode
import com.outsystems.plugins.barcode.controller.helper.OSBARCMLKitHelperInterface
import com.outsystems.plugins.barcode.model.OSBARCError
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
+import com.outsystems.plugins.barcode.model.OSBARCScannerHint
/**
* Wrapper class that implements the OSBARCScanLibraryInterface
@@ -25,18 +28,20 @@ class OSBARCMLKitWrapper(private val helper: OSBARCMLKitHelperInterface): OSBARC
override fun scanBarcode(
imageProxy: ImageProxy,
imageBitmap: Bitmap,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: (OSBARCError) -> Unit
) {
try {
helper.decodeImage(imageProxy, imageBitmap,
{ barcodes ->
- var result: String? = null
- if (barcodes.isNotEmpty()) {
- result = barcodes.first().rawValue
- }
- if (!result.isNullOrEmpty()) {
- onSuccess(result)
+ barcodes.firstOrNull()?.let { barcode ->
+ val result = OSBARCScanResult(
+ text = barcode.rawValue ?: "",
+ format = barcode.format.toOSBARCScannerHint()
+ )
+ if (result.text.isNotEmpty()) {
+ onSuccess(result)
+ }
}
},
{
@@ -49,4 +54,22 @@ class OSBARCMLKitWrapper(private val helper: OSBARCMLKitHelperInterface): OSBARC
}
}
+ private fun Int?.toOSBARCScannerHint(): OSBARCScannerHint = when (this) {
+ Barcode.FORMAT_QR_CODE -> OSBARCScannerHint.QR_CODE
+ Barcode.FORMAT_AZTEC -> OSBARCScannerHint.AZTEC
+ Barcode.FORMAT_CODABAR -> OSBARCScannerHint.CODABAR
+ Barcode.FORMAT_CODE_39 -> OSBARCScannerHint.CODE_39
+ Barcode.FORMAT_CODE_93 -> OSBARCScannerHint.CODE_93
+ Barcode.FORMAT_CODE_128 -> OSBARCScannerHint.CODE_128
+ Barcode.FORMAT_DATA_MATRIX -> OSBARCScannerHint.DATA_MATRIX
+ Barcode.FORMAT_ITF -> OSBARCScannerHint.ITF
+ Barcode.FORMAT_EAN_13 -> OSBARCScannerHint.EAN_13
+ Barcode.FORMAT_EAN_8 -> OSBARCScannerHint.EAN_8
+ Barcode.FORMAT_PDF417 -> OSBARCScannerHint.PDF_417
+ Barcode.FORMAT_UPC_A -> OSBARCScannerHint.UPC_A
+ Barcode.FORMAT_UPC_E -> OSBARCScannerHint.UPC_E
+
+ // Formats not supported by ML Kit → map to UNKNOWN
+ else -> OSBARCScannerHint.UNKNOWN
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCScanLibraryInterface.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCScanLibraryInterface.kt
index 6b2bd15..a5524b0 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCScanLibraryInterface.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCScanLibraryInterface.kt
@@ -3,6 +3,7 @@ package com.outsystems.plugins.barcode.controller
import android.graphics.Bitmap
import androidx.camera.core.ImageProxy
import com.outsystems.plugins.barcode.model.OSBARCError
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
/**
* Interface that provides the signature of the scanBarcode method
@@ -11,7 +12,7 @@ fun interface OSBARCScanLibraryInterface {
fun scanBarcode(
imageProxy: ImageProxy,
imageBitmap: Bitmap,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: (OSBARCError) -> Unit
)
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCZXingWrapper.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCZXingWrapper.kt
index 9fe2a19..9b738a3 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCZXingWrapper.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/OSBARCZXingWrapper.kt
@@ -5,6 +5,7 @@ import android.util.Log
import androidx.camera.core.ImageProxy
import com.outsystems.plugins.barcode.controller.helper.OSBARCZXingHelperInterface
import com.outsystems.plugins.barcode.model.OSBARCError
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
/**
* Wrapper class that implements the OSBARCScanLibraryInterface
@@ -25,7 +26,7 @@ class OSBARCZXingWrapper(private val helper: OSBARCZXingHelperInterface) : OSBAR
override fun scanBarcode(
imageProxy: ImageProxy,
imageBitmap: Bitmap,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: (OSBARCError) -> Unit
) {
try {
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCMLKitHelper.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCMLKitHelper.kt
index 6287665..b5b1709 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCMLKitHelper.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCMLKitHelper.kt
@@ -7,21 +7,51 @@ import com.google.mlkit.vision.barcode.BarcodeScannerOptions
import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.barcode.common.Barcode
import com.google.mlkit.vision.common.InputImage
+import com.outsystems.plugins.barcode.model.OSBARCScannerHint
+import org.jetbrains.annotations.VisibleForTesting
/**
* Helper class that implements the OSBARCMLKitHelperInterface
* to scan an image using the ML Kit library.
* It encapsulates all the code related with the ML Kit library.
*/
-class OSBARCMLKitHelper: OSBARCMLKitHelperInterface {
+class OSBARCMLKitHelper(private val hint: OSBARCScannerHint?): OSBARCMLKitHelperInterface {
companion object {
private const val LOG_TAG = "OSBARCMLKitHelper"
+
+ @VisibleForTesting
+ internal fun OSBARCScannerHint?.toMLKitBarcodeFormat(): Int? = when (this) {
+ OSBARCScannerHint.QR_CODE -> Barcode.FORMAT_QR_CODE
+ OSBARCScannerHint.AZTEC -> Barcode.FORMAT_AZTEC
+ OSBARCScannerHint.CODABAR -> Barcode.FORMAT_CODABAR
+ OSBARCScannerHint.CODE_39 -> Barcode.FORMAT_CODE_39
+ OSBARCScannerHint.CODE_93 -> Barcode.FORMAT_CODE_93
+ OSBARCScannerHint.CODE_128 -> Barcode.FORMAT_CODE_128
+ OSBARCScannerHint.DATA_MATRIX -> Barcode.FORMAT_DATA_MATRIX
+ OSBARCScannerHint.MAXICODE -> null // not supported by ML Kit
+ OSBARCScannerHint.ITF -> Barcode.FORMAT_ITF
+ OSBARCScannerHint.EAN_13 -> Barcode.FORMAT_EAN_13
+ OSBARCScannerHint.EAN_8 -> Barcode.FORMAT_EAN_8
+ OSBARCScannerHint.PDF_417 -> Barcode.FORMAT_PDF417
+ OSBARCScannerHint.RSS_14 -> null // not supported by ML Kit
+ OSBARCScannerHint.RSS_EXPANDED -> null // not supported by ML Kit
+ OSBARCScannerHint.UPC_A -> Barcode.FORMAT_UPC_A
+ OSBARCScannerHint.UPC_E -> Barcode.FORMAT_UPC_E
+ OSBARCScannerHint.UPC_EAN_EXTENSION -> null // not supported by ML Kit
+ OSBARCScannerHint.UNKNOWN -> null
+ null -> null
+ }
}
private val scanner by lazy {
- val options = BarcodeScannerOptions.Builder()
- .enableAllPotentialBarcodes()
- .build()
+ val options = BarcodeScannerOptions.Builder().apply {
+ val format = hint.toMLKitBarcodeFormat()
+ if (format != null) {
+ setBarcodeFormats(format)
+ } else {
+ enableAllPotentialBarcodes()
+ }
+ }.build()
BarcodeScanning.getClient(options)
}
@@ -51,5 +81,4 @@ class OSBARCMLKitHelper: OSBARCMLKitHelperInterface {
onError()
}
}
-
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt
index f95e38e..45927db 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelper.kt
@@ -3,23 +3,38 @@ package com.outsystems.plugins.barcode.controller.helper
import android.graphics.Bitmap
import android.graphics.Matrix
import android.util.Log
+import com.google.zxing.BarcodeFormat
import com.google.zxing.BinaryBitmap
+import com.google.zxing.DecodeHintType
import com.google.zxing.MultiFormatReader
import com.google.zxing.NotFoundException
import com.google.zxing.RGBLuminanceSource
import com.google.zxing.common.HybridBinarizer
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
+import com.outsystems.plugins.barcode.model.OSBARCScannerHint
/**
* Helper class that implements the OSBARCZXingHelperInterface
* to scan an image using the ZXing library.
* It encapsulates all the code related with the ZXing library.
*/
-class OSBARCZXingHelper: OSBARCZXingHelperInterface {
+class OSBARCZXingHelper(private val hint: OSBARCScannerHint?): OSBARCZXingHelperInterface {
companion object {
private const val LOG_TAG = "OSBARCZXingHelper"
}
+ private val reader: MultiFormatReader by lazy {
+ val format = hint.toZXingBarcodeFormat()
+ MultiFormatReader().apply {
+ if (format != null) {
+ setHints(
+ mapOf(DecodeHintType.POSSIBLE_FORMATS to setOf(format))
+ )
+ }
+ }
+ }
+
/**
* Rotates a bitmap, provided with the rotation degrees.
* @param bitmap - Bitmap object to rotate
@@ -51,14 +66,19 @@ class OSBARCZXingHelper: OSBARCZXingHelperInterface {
*/
override fun decodeImage(
pixels: IntArray, width: Int, height: Int,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: () -> Unit
) {
try {
val source = RGBLuminanceSource(width, height, pixels)
val binaryBitmap = BinaryBitmap(HybridBinarizer(source))
- val result = MultiFormatReader().decodeWithState(binaryBitmap)
- onSuccess(result.text)
+ val result = reader.decodeWithState(binaryBitmap)
+ onSuccess(
+ OSBARCScanResult(
+ text = result.text,
+ format = result.barcodeFormat.toOSBARCScannerHint()
+ )
+ )
} catch (e: NotFoundException) {
// keep trying, no barcode was found in this camera frame
e.message?.let { Log.d(LOG_TAG, it) }
@@ -66,7 +86,49 @@ class OSBARCZXingHelper: OSBARCZXingHelperInterface {
e.message?.let { Log.e(LOG_TAG, it) }
onError()
}
+ }
+ private fun OSBARCScannerHint?.toZXingBarcodeFormat(): BarcodeFormat? = when (this) {
+ OSBARCScannerHint.QR_CODE -> BarcodeFormat.QR_CODE
+ OSBARCScannerHint.AZTEC -> BarcodeFormat.AZTEC
+ OSBARCScannerHint.CODABAR -> BarcodeFormat.CODABAR
+ OSBARCScannerHint.CODE_39 -> BarcodeFormat.CODE_39
+ OSBARCScannerHint.CODE_93 -> BarcodeFormat.CODE_93
+ OSBARCScannerHint.CODE_128 -> BarcodeFormat.CODE_128
+ OSBARCScannerHint.DATA_MATRIX -> BarcodeFormat.DATA_MATRIX
+ OSBARCScannerHint.MAXICODE -> BarcodeFormat.MAXICODE
+ OSBARCScannerHint.ITF -> BarcodeFormat.ITF
+ OSBARCScannerHint.EAN_13 -> BarcodeFormat.EAN_13
+ OSBARCScannerHint.EAN_8 -> BarcodeFormat.EAN_8
+ OSBARCScannerHint.PDF_417 -> BarcodeFormat.PDF_417
+ OSBARCScannerHint.RSS_14 -> BarcodeFormat.RSS_14
+ OSBARCScannerHint.RSS_EXPANDED -> BarcodeFormat.RSS_EXPANDED
+ OSBARCScannerHint.UPC_A -> BarcodeFormat.UPC_A
+ OSBARCScannerHint.UPC_E -> BarcodeFormat.UPC_E
+ OSBARCScannerHint.UPC_EAN_EXTENSION -> BarcodeFormat.UPC_EAN_EXTENSION
+ OSBARCScannerHint.UNKNOWN -> null
+ null -> null
}
+ private fun BarcodeFormat?.toOSBARCScannerHint(): OSBARCScannerHint = when (this) {
+ BarcodeFormat.QR_CODE -> OSBARCScannerHint.QR_CODE
+ BarcodeFormat.AZTEC -> OSBARCScannerHint.AZTEC
+ BarcodeFormat.CODABAR -> OSBARCScannerHint.CODABAR
+ BarcodeFormat.CODE_39 -> OSBARCScannerHint.CODE_39
+ BarcodeFormat.CODE_93 -> OSBARCScannerHint.CODE_93
+ BarcodeFormat.CODE_128 -> OSBARCScannerHint.CODE_128
+ BarcodeFormat.DATA_MATRIX -> OSBARCScannerHint.DATA_MATRIX
+ BarcodeFormat.MAXICODE -> OSBARCScannerHint.MAXICODE
+ BarcodeFormat.ITF -> OSBARCScannerHint.ITF
+ BarcodeFormat.EAN_13 -> OSBARCScannerHint.EAN_13
+ BarcodeFormat.EAN_8 -> OSBARCScannerHint.EAN_8
+ BarcodeFormat.PDF_417 -> OSBARCScannerHint.PDF_417
+ BarcodeFormat.RSS_14 -> OSBARCScannerHint.RSS_14
+ BarcodeFormat.RSS_EXPANDED -> OSBARCScannerHint.RSS_EXPANDED
+ BarcodeFormat.UPC_A -> OSBARCScannerHint.UPC_A
+ BarcodeFormat.UPC_E -> OSBARCScannerHint.UPC_E
+ BarcodeFormat.UPC_EAN_EXTENSION -> OSBARCScannerHint.UPC_EAN_EXTENSION
+
+ else -> OSBARCScannerHint.UNKNOWN
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelperInterface.kt b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelperInterface.kt
index a482d79..3fad533 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelperInterface.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/controller/helper/OSBARCZXingHelperInterface.kt
@@ -1,6 +1,7 @@
package com.outsystems.plugins.barcode.controller.helper
import android.graphics.Bitmap
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
/**
* Interface that provides the signature of the type's methods.
@@ -11,7 +12,7 @@ interface OSBARCZXingHelperInterface {
pixels: IntArray,
width: Int,
height: Int,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: () -> Unit
)
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScanParameters.kt b/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScanParameters.kt
index 502efb2..aaee198 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScanParameters.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScanParameters.kt
@@ -12,6 +12,6 @@ data class OSBARCScanParameters(
@SerializedName("scanOrientation") val scanOrientation: Int?,
@SerializedName("scanButton") val scanButton: Boolean,
@SerializedName("scanText") val scanText: String,
- @SerializedName("hint") val hint: Int?,
+ @SerializedName("hint") val hint: OSBARCScannerHint?,
@SerializedName("androidScanningLibrary") val androidScanningLibrary: String?
) : Serializable
\ No newline at end of file
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScanResult.kt b/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScanResult.kt
new file mode 100644
index 0000000..44abf8e
--- /dev/null
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScanResult.kt
@@ -0,0 +1,8 @@
+package com.outsystems.plugins.barcode.model
+
+import java.io.Serializable
+
+data class OSBARCScanResult(
+ val text: String,
+ val format: OSBARCScannerHint = OSBARCScannerHint.UNKNOWN
+): Serializable
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScannerHint.kt b/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScannerHint.kt
new file mode 100644
index 0000000..37ff388
--- /dev/null
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/model/OSBARCScannerHint.kt
@@ -0,0 +1,22 @@
+package com.outsystems.plugins.barcode.model
+
+enum class OSBARCScannerHint {
+ QR_CODE,
+ AZTEC,
+ CODABAR,
+ CODE_39,
+ CODE_93,
+ CODE_128,
+ DATA_MATRIX,
+ MAXICODE,
+ ITF,
+ EAN_13,
+ EAN_8,
+ PDF_417,
+ RSS_14,
+ RSS_EXPANDED,
+ UPC_A,
+ UPC_E,
+ UPC_EAN_EXTENSION,
+ UNKNOWN
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt
index a79cf29..ee5f2b4 100644
--- a/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt
+++ b/src/main/kotlin/com/outsystems/plugins/barcode/view/OSBARCScannerActivity.kt
@@ -90,6 +90,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
+import androidx.core.content.IntentCompat
import androidx.core.view.WindowCompat
import androidx.window.layout.WindowMetricsCalculator
import com.outsystems.plugins.barcode.R
@@ -100,6 +101,7 @@ import com.outsystems.plugins.barcode.controller.helper.OSBARCMLKitHelper
import com.outsystems.plugins.barcode.controller.helper.OSBARCZXingHelper
import com.outsystems.plugins.barcode.model.OSBARCError
import com.outsystems.plugins.barcode.model.OSBARCScanParameters
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
import com.outsystems.plugins.barcode.view.ui.theme.ActionButtonsDistance
import com.outsystems.plugins.barcode.view.ui.theme.BarcodeScannerTheme
import com.outsystems.plugins.barcode.view.ui.theme.ButtonsBackgroundGray
@@ -166,7 +168,7 @@ class OSBARCScannerActivity : ComponentActivity() {
cameraExecutor = Executors.newSingleThreadExecutor()
- val parameters = intent.extras?.getSerializable(SCAN_PARAMETERS) as OSBARCScanParameters
+ val parameters = IntentCompat.getSerializableExtra(intent, SCAN_PARAMETERS, OSBARCScanParameters::class.java)!!
// possibly lock orientation, the screen is adaptive by default
if (parameters.scanOrientation == ORIENTATION_PORTRAIT) {
@@ -183,8 +185,8 @@ class OSBARCScannerActivity : ComponentActivity() {
barcodeAnalyzer = OSBARCBarcodeAnalyzer(
OSBARCScanLibraryFactory.createScanLibraryWrapper(
parameters.androidScanningLibrary ?: "",
- OSBARCZXingHelper(),
- OSBARCMLKitHelper()
+ OSBARCZXingHelper(parameters.hint),
+ OSBARCMLKitHelper(parameters.hint)
),
OSBARCImageHelper(),
{ result ->
@@ -920,7 +922,7 @@ class OSBARCScannerActivity : ComponentActivity() {
) == PackageManager.PERMISSION_GRANTED
}
- private fun processReadSuccess(result: String) {
+ private fun processReadSuccess(result: OSBARCScanResult) {
// we only want to process the scan result if scanning is active
if (isScanning) {
val resultIntent = Intent()
diff --git a/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt b/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt
index 2fd2aec..5d366ed 100644
--- a/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt
+++ b/src/test/kotlin/com/outsystems/plugins/barcode/ScanCodeTests.kt
@@ -7,6 +7,7 @@ import android.media.Image
import android.os.Bundle
import androidx.camera.core.ImageInfo
import androidx.camera.core.ImageProxy
+import androidx.core.content.IntentCompat
import com.outsystems.plugins.barcode.controller.OSBARCBarcodeAnalyzer
import com.outsystems.plugins.barcode.controller.OSBARCController
import com.outsystems.plugins.barcode.controller.OSBARCScanLibraryFactory
@@ -17,10 +18,15 @@ import com.outsystems.plugins.barcode.mocks.OSBARCZXingHelperMock
import com.outsystems.plugins.barcode.mocks.OSBARCScanLibraryMock
import com.outsystems.plugins.barcode.model.OSBARCError
import com.outsystems.plugins.barcode.model.OSBARCScanParameters
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
+import com.outsystems.plugins.barcode.model.OSBARCScannerHint
+import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.fail
import org.junit.Before
import org.junit.Test
+import org.mockito.Mock
+import org.mockito.MockedStatic
import org.mockito.Mockito
import java.nio.ByteBuffer
@@ -34,6 +40,7 @@ class ScanCodeTests {
private lateinit var mockByteBuffer: ByteBuffer
private lateinit var mockImageInfo: ImageInfo
private lateinit var planes: Array
+ private lateinit var mockIntentCompat: MockedStatic
private lateinit var imageHelperMock: OSBARCImageHelperInterface
private lateinit var mockBitmap: Bitmap
@@ -41,10 +48,10 @@ class ScanCodeTests {
companion object {
private const val SCAN_REQUEST_CODE = 112
private const val INVALID_REQUEST_CODE = 113
- private const val INVALID_RESULT_CODE = 9
private const val GENERAL_ERROR_CODE = 4
- private const val SCAN_RESULT = "scanResult"
- private const val RESULT_CODE = "myCode"
+ private const val SCAN_RESULT_KEY = "scanResult"
+ private val SCAN_RESULT = OSBARCScanResult("scanResult", OSBARCScannerHint.ITF)
+ private val RESULT_CODE = OSBARCScanResult("myCode", OSBARCScannerHint.QR_CODE)
}
@Before
@@ -66,6 +73,12 @@ class ScanCodeTests {
imageHelperMock = OSBARCImageHelperMock()
mockBitmap = Mockito.mock(Bitmap::class.java)
+ mockIntentCompat = Mockito.mockStatic(IntentCompat::class.java)
+ }
+
+ @After
+ fun after() {
+ mockIntentCompat.close()
}
@Test
@@ -77,7 +90,7 @@ class ScanCodeTests {
1,
false,
"",
- 1,
+ OSBARCScannerHint.QR_CODE,
"zxing"
)
barcodeController.scanCode(mockActivity, parameters)
@@ -85,11 +98,15 @@ class ScanCodeTests {
@Test
fun givenResultOKAndBarcodeValidWhenHandleScanResultThenSuccess() {
- Mockito.doReturn(mockBundle).`when`(mockIntent).extras
- Mockito.doReturn(RESULT_CODE).`when`(mockBundle).getString(SCAN_RESULT)
+ mockIntentCompat
+ .`when` {
+ IntentCompat.getSerializableExtra(mockIntent, SCAN_RESULT_KEY, OSBARCScanResult::class.java)
+ }
+ .thenReturn(RESULT_CODE)
val barcodeController = OSBARCController()
- barcodeController.handleActivityResult(SCAN_REQUEST_CODE, Activity.RESULT_OK, mockIntent,
+ barcodeController.handleActivityResult(
+ SCAN_REQUEST_CODE, Activity.RESULT_OK, mockIntent,
{
assertEquals(RESULT_CODE, it)
},
@@ -131,8 +148,11 @@ class ScanCodeTests {
@Test
fun givenStringNullWhenHandleScanResultThenGeneralError() {
- Mockito.doReturn(mockBundle).`when`(mockIntent).extras
- Mockito.doReturn(null).`when`(mockBundle).getString(SCAN_RESULT)
+ mockIntentCompat
+ .`when` {
+ IntentCompat.getSerializableExtra(mockIntent, SCAN_RESULT_KEY, OSBARCScanResult::class.java)
+ }
+ .thenReturn(null)
val barcodeController = OSBARCController()
barcodeController.handleActivityResult(SCAN_REQUEST_CODE, Activity.RESULT_OK, mockIntent,
@@ -148,8 +168,11 @@ class ScanCodeTests {
@Test
fun givenInvalidRequestCodeWhenHandleScanResultThenGeneralError() {
- Mockito.doReturn(mockBundle).`when`(mockIntent).extras
- Mockito.doReturn(null).`when`(mockBundle).getString(SCAN_RESULT)
+ mockIntentCompat
+ .`when` {
+ IntentCompat.getSerializableExtra(mockIntent, SCAN_RESULT_KEY, OSBARCScanResult::class.java)
+ }
+ .thenReturn(null)
val barcodeController = OSBARCController()
barcodeController.handleActivityResult(INVALID_REQUEST_CODE, Activity.RESULT_OK, mockIntent,
@@ -165,8 +188,11 @@ class ScanCodeTests {
@Test
fun givenInvalidResultCodeWhenHandleScanResultThenGeneralError() {
- Mockito.doReturn(mockBundle).`when`(mockIntent).extras
- Mockito.doReturn(null).`when`(mockBundle).getString(SCAN_RESULT)
+ mockIntentCompat
+ .`when` {
+ IntentCompat.getSerializableExtra(mockIntent, SCAN_RESULT_KEY, OSBARCScanResult::class.java)
+ }
+ .thenReturn(null)
val barcodeController = OSBARCController()
barcodeController.handleActivityResult(SCAN_REQUEST_CODE, GENERAL_ERROR_CODE, mockIntent,
@@ -182,8 +208,11 @@ class ScanCodeTests {
@Test
fun givenResultOKAndBarcodeEmptyWhenHandleScanResultThenScanningError() {
- Mockito.doReturn(mockBundle).`when`(mockIntent).extras
- Mockito.doReturn("").`when`(mockBundle).getString(SCAN_RESULT)
+ mockIntentCompat
+ .`when` {
+ IntentCompat.getSerializableExtra(mockIntent, SCAN_RESULT_KEY, OSBARCScanResult::class.java)
+ }
+ .thenReturn(OSBARCScanResult("", OSBARCScannerHint.UNKNOWN))
val barcodeController = OSBARCController()
barcodeController.handleActivityResult(SCAN_REQUEST_CODE, Activity.RESULT_OK, mockIntent,
@@ -576,7 +605,7 @@ class ScanCodeTests {
"mlkit",
OSBARCZXingHelperMock(),
OSBARCMLKitHelperMock().apply {
- scanResult = ""
+ scanResult = SCAN_RESULT.copy(text = "")
success = true
barcodesEmpty = false
}
diff --git a/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCMLKitHelperMock.kt b/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCMLKitHelperMock.kt
index 7f7bf28..73ca31d 100644
--- a/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCMLKitHelperMock.kt
+++ b/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCMLKitHelperMock.kt
@@ -3,13 +3,15 @@ package com.outsystems.plugins.barcode.mocks
import android.graphics.Bitmap
import androidx.camera.core.ImageProxy
import com.google.mlkit.vision.barcode.common.Barcode
+import com.outsystems.plugins.barcode.controller.helper.OSBARCMLKitHelper.Companion.toMLKitBarcodeFormat
import com.outsystems.plugins.barcode.controller.helper.OSBARCMLKitHelperInterface
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
import org.mockito.Mockito
class OSBARCMLKitHelperMock: OSBARCMLKitHelperInterface {
var success = true
- var scanResult: String? = null
+ var scanResult: OSBARCScanResult? = null
var exception = false
var barcodesEmpty = true
@@ -27,7 +29,8 @@ class OSBARCMLKitHelperMock: OSBARCMLKitHelperInterface {
}
if (success) {
- Mockito.doReturn(scanResult).`when`(mockBarcode).rawValue
+ Mockito.doReturn(scanResult?.text).`when`(mockBarcode).rawValue
+ Mockito.doReturn(scanResult?.format?.toMLKitBarcodeFormat()).`when`(mockBarcode).format
onSuccess(mutableListOf(mockBarcode))
}
else if (!exception) {
diff --git a/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCScanLibraryMock.kt b/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCScanLibraryMock.kt
index b1445a0..beee5ce 100644
--- a/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCScanLibraryMock.kt
+++ b/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCScanLibraryMock.kt
@@ -4,21 +4,23 @@ import android.graphics.Bitmap
import androidx.camera.core.ImageProxy
import com.outsystems.plugins.barcode.controller.OSBARCScanLibraryInterface
import com.outsystems.plugins.barcode.model.OSBARCError
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
+import com.outsystems.plugins.barcode.model.OSBARCScannerHint
class OSBARCScanLibraryMock: OSBARCScanLibraryInterface {
- var resultCode = ""
+ var resultCode = OSBARCScanResult("", OSBARCScannerHint.UNKNOWN)
var success = true
var exception = false
var error: OSBARCError = OSBARCError.SCANNING_GENERAL_ERROR
override fun scanBarcode(
imageProxy: ImageProxy,
imageBitmap: Bitmap,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: (OSBARCError) -> Unit
) {
if (success) {
- onSuccess("myCode")
+ onSuccess(OSBARCScanResult("myCode", OSBARCScannerHint.QR_CODE))
}
else if (!exception) {
onError(error)
diff --git a/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCZXingHelperMock.kt b/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCZXingHelperMock.kt
index 6b12777..af22e54 100644
--- a/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCZXingHelperMock.kt
+++ b/src/test/kotlin/com/outsystems/plugins/barcode/mocks/OSBARCZXingHelperMock.kt
@@ -2,11 +2,13 @@ package com.outsystems.plugins.barcode.mocks
import android.graphics.Bitmap
import com.outsystems.plugins.barcode.controller.helper.OSBARCZXingHelperInterface
+import com.outsystems.plugins.barcode.model.OSBARCScanResult
+import com.outsystems.plugins.barcode.model.OSBARCScannerHint
import org.mockito.Mockito
class OSBARCZXingHelperMock: OSBARCZXingHelperInterface {
- var scanResult = ""
+ var scanResult = OSBARCScanResult("", OSBARCScannerHint.UNKNOWN)
var success = true
var exception = false
@@ -18,7 +20,7 @@ class OSBARCZXingHelperMock: OSBARCZXingHelperInterface {
pixels: IntArray,
width: Int,
height: Int,
- onSuccess: (String) -> Unit,
+ onSuccess: (OSBARCScanResult) -> Unit,
onError: () -> Unit
) {
if (success) {