Barcode Scanner¶
The FioriBarcodeScannerBox
and FioriBarcodeScannerDialog
are composable functions implemented based on CameraX
and Google's MLKit
barcode scanning library. They handle the camera stream and image transformation for barcode detection in real-time. They support three scan modes:
-
Single mode detects one barcode at a time.
-
Multi mode detects multiple barcodes at a time.
-
Multi-image mode returns the captured images to the client code when multiple barcodes are detected and scanned.
Both composable functions provide optional parameters so that developers can leverage the following features
-
Developers can determine whether to use the Region of Interest(
ROI
) and display detection bounding box inOverlayConfig
. WithROI
, only the image within the region of interest will be applied to detection. Once the detection bounding box is turned on, the recognized barcode will be marked on camera preview. See "OverlayConfig" for additional information. -
BarcodeConfig
allows users to configure the detection processor itself, including the ability to turn on auto-focus and specify supported barcode formats. See "BarcodeConfig" for additional information. -
AssociatedHyperlink
is a container that allows user to place hints in the preview screen. Developers may bind highlighted keywords to a hyperlink. See "Hyperlink" for additional information. -
Barcode validation ensures the barcodes match certain validation criteria. See "Validation Support" for additional information.
Setting up FioriBarcodeScanner
¶
Set up FioriBarcodeScannerBox
using something similar to the following sample code:
-
Using default configurations for
FioriBarcodeScannerBox
:FioriBarcodeScannerBox( detectorListener = object :OnMultiBarCodeDetectorListener { override fun onBarcodeDetected(barcode: String) { } } )
onBarcodeDetected(barcode:String)
is called back once a barcode has been found within preview (orROI
). -
Applying configurations and validator to
FioriBarcodeScannerBox
:FioriBarcodeScannerBox( overlayConfig = OverlayConfig.Builder().build(), // Set up overlay configuration here. hyperlink = AssociatedHyperlink.Builder().build(), // Set up customized hint and corresponding hyperlink here. barcodeConfig =BarcodeConfig.Builder().build(), // Set up barcode scanning processor configuration here. permissionDeniedCallback ={ // This will be triggered if the user has denied the granting of permission for the camera for barcode scanner. // Dismiss the box in the function. }, onDismissRequest ={ // This will be triggered if user has clicked the Cancel button on the top left of FioriBarcodeScanningBox. // Dismiss the box in the function. }, // If this parameter is set to null, the cancel box will not be rendered on the top left of FioriBarcodeScanningBox. barcodeValidator = object:BarcodeValidator{ override fun isValid(barcode: String): Boolean { return false // write your own rules here to check whether the result string is valid or not. } }, detectorListener = object :OnMultiBarCodeDetectorListener { override fun onBarcodeDetected(barcode: String) { // Handle detection result here // This will only be triggered if single mode is configured in 'barcodeConfig' } override fun onBarcodeNotFound():Boolean{ // This implementation is optional // This callback will be triggered if a barcode is not found by the processor after a user clicks the 'Choose Picture' button. return false // May also return 'true' to intercept further internal processing. } override fun onMultiBarcodeDetected(barcodes:List<Barcode>){ // This implementation is optional // This callback will only be triggered when multi mode is turned on in 'barcodeConfig' and one or more barcodes are found in the preview image // Handle detection result here. } override fun onMultiBarcodeCaptured(barcodeBitmap: Bitmap,barcodes:List<Barcode>){ // This implementation is optional // This callback is only triggered when image mode is turned on in 'barcodeConfig' and one or more barcodes are found in preview image or ROI. // Barcodes found in the image along with the preview image processed by the barcode processor will be available in this callback. // Handle the detection result here. } } )
The differences between FioriBarcodeScannerDialog
and FioriBarcodeScannerBox
are that there is no modifier in the dialog function and there is a Boolean parameter in the dialog function to control whether to display the dialog.
FioriBarcodeScannerDialog
is a pop-up that is rendered full-screen, whereas FioriBarcodeScannerBox
is a layout composable that contained by a box composable layout and the placement and measurement can be modified using 'modifier' parameter.
This is the scanner box with multi mode enabled.
This is the scanner dialog with ROI
OverlayConfig
¶
Use the OverlayConfig
class to configure the UI features of the barcode scanner overlay mask. Developers may build their own configuration using something similar to the following sample codes:
val overlayConfig = OverlayConfig.Builder()
.showMask(true) // Determine wheter to turn on the Region of Interest(ROI) in the center of the screen,
//Use 'true'(the default value) to turn on ROI, 'false' to turn ROI off
.setFrameRadius(150.dp) // Set the radius of the ROI box. The default value is '150.dp'.
.showBounds(false) // Determine whether to display the rectangles tracking the barcodes in preview.
//Use 'true' to display bounds, 'false' (the default value) to turn bounds off.
.setBoundsStroke(1.dp) //Set the stroke width of the rectangles tracking the barcodes. The default value is '1.dp'.
.setInvalidBoundColor(Color.Green) // Set the color of the bounds of the rectangles tracking barcodes that do not pass the validation.
// The default value is 'Color.Green'.
.setValidBoundColor(Color.Red) // Set the color of the bounds of the rectangles tracking barcodes that pass the validation,
// The default value is 'Color.Red'.
.build()
BarcodeConfig
¶
Use BarcodeConfig
class to configure different capabilities for the BarcodeScanner
internal processor.
val barcodeConfig = BarcodeConfig.Builder()
.setAutoFocus(true) //Determine whether to turn auto-focus on or not. This does not work if auto-focus is not supported.
// This is turned on by default.
.setBarCodeFormat(Barcode.FORMAT_ALL_FORMATS) // Set the barcode formats that can be recognized.
// Formats can be combined using an 'or' operation
.setScanInterval(150) // Set scan interval in milliseconds (as detection performance can vary on different devices).
// To reduce the volume of the detection queue, make sure you are using the proper values under different conditions.
.isSupportMultiMode(false)
.isSupportImageMode(false) // If multi mode is turned on, all barcodes within the preview frame will be called back.
// Furthermore, the image being detected will be called back, along with barcodes found within it, if image mode is turned on
// If neither mode is turned on, only the first barcode called back in the processor will be called back to the user.
.setLensFacing(LensFacing.BACK) // By default, the scanner uses the back camera as the input source. You can also set the front camera here, it can be set here. Note that if the specified lens is not available, scanner will choose the first available camera in the device.
.build()
For information on valid barcode formats, see Scan barcodes with ML Kit on Android.
Hyperlink
¶
You can configure Hyperlink
in the hint below the ROI
. The highlighted hyperlink opens in an external browser.
val hint = AssociatedHyperlink.Builder()
.appendNormalString("your own string with ") // The string appended here is the normal hint that will be displayed below the ROI.
.appendKeyword(keyword ="hyperlink", url="https://www.sap.com" )
// The keyword is appended in the chain and the URL is bounded with the hyperlink.
.setHyperlinksForKeywords(keyword = "own", url="https://help.sap.com" )
// The keyword will be scanned in the appended string.
// The keyword that matches the keyword parameter will be highlighted as a hyperlink bounded with the URL.
Validation Support¶
FioriBarcodeScannerBox
and FioriBarcodeScannerDialog
allow the client code to provide a validator
for the value of each barcode and display a colored
rectangle around the barcode, indicating whether validation was successful or not.
You can customize the colors for successful and failed validations using "Overlayconfig".
val barcodeValidator = object:BarcodeValidator{
override fun isValid(barcode: String): Boolean {
// Determine which kind of barcode is valid.
return false // If 'false' is returned, the barcode is not valid. If 'true', the barcode is valid.
}
}