diff --git a/docs/hosted/express/getting-started/rollout.md b/docs/hosted/express/getting-started/rollout.md index a3176bbd..dcae4c4b 100644 --- a/docs/hosted/express/getting-started/rollout.md +++ b/docs/hosted/express/getting-started/rollout.md @@ -75,7 +75,7 @@ To automatically synchronize your Scandit Express configuration with Scandit, yo 2. Click on your project card. 3. The Android Scandit Express App specifies the following Application Restriction: - ```java + ```xml Tip: The built‑in UI components (e.g., `SparkScanView`, `BarcodeFindView`) manage camera start/stop when you route lifecycle calls to them. --- @@ -78,7 +70,6 @@ DataCaptureContext dataCaptureContext = **Dependencies**: `ScanditCaptureCore`, `ScanditBarcodeCapture`. -Kotlin (Activity/Fragment extract): ```kotlin import com.scandit.datacapture.barcode.spark.ui.SparkScanView import com.scandit.datacapture.barcode.spark.ui.SparkScanViewSettings @@ -106,21 +97,6 @@ sparkScan.addListener(object : SparkScanListener { }) ``` -Java (snippets equivalent): -```java -SparkScanSettings settings = new SparkScanSettings(); -HashSet syms = new HashSet<>(); -syms.add(Symbology.EAN13_UPCA); -settings.enableSymbologies(syms); - -SparkScan sparkScan = new SparkScan(settings); -SparkScanViewSettings viewSettings = new SparkScanViewSettings(); -SparkScanView sparkView = SparkScanView.newInstance(parentView, dataCaptureContext, sparkScan, viewSettings); - -@Override protected void onResume() { sparkView.onResume(); super.onResume(); } -@Override protected void onPause() { sparkView.onPause(); super.onPause(); } -``` - --- ## Barcode Capture (low‑level single scan) @@ -129,7 +105,6 @@ SparkScanView sparkView = SparkScanView.newInstance(parentView, dataCaptureConte **Dependencies**: `ScanditCaptureCore`, `ScanditBarcodeCapture`. -Kotlin (essentials): ```kotlin val barcodeSettings = BarcodeCaptureSettings().apply { enableSymbologies(setOf(Symbology.CODE128, Symbology.QR)) @@ -155,7 +130,6 @@ barcodeCapture.addListener(object : BarcodeCaptureListener { **When to use**: highlight items that match a *list*; quickly search shelves/containers. **Note**: MatrixScan Count/Find are powered by **BarcodeFind** + **BarcodeFindView**. -Kotlin: ```kotlin val findSettings = BarcodeFindSettings().apply { setSymbologyEnabled(Symbology.EAN13_UPCA, true) @@ -186,8 +160,6 @@ findView.setListener(object : BarcodeFindViewUiListener { findView.startSearching() ``` -Java equivalents mirror the above (per docs). - --- ## Smart Label Capture (barcodes + printed text in one shot) diff --git a/docs/sdks/android/label-capture/advanced.md b/docs/sdks/android/label-capture/advanced.md index 91c06a60..b766b0f7 100644 --- a/docs/sdks/android/label-capture/advanced.md +++ b/docs/sdks/android/label-capture/advanced.md @@ -17,9 +17,6 @@ To customize the appearance of an overlay you can implement a [LabelCaptureBasic The method [brushForLabel()](https://docs.scandit.com/data-capture-sdk/android/label-capture/api/ui/label-capture-basic-overlay-listener.html#method-scandit.datacapture.label.ui.ILabelCaptureBasicOverlayListener.BrushForLabel) is called every time a label is captured, and [brushForField()](https://docs.scandit.com/data-capture-sdk/android/label-capture/api/ui/label-capture-basic-overlay-listener.html#method-scandit.datacapture.label.ui.ILabelCaptureBasicOverlayListener.BrushForField) is called for each of its fields to determine the brush for the label or field. - - - ```kotlin overlay.listener = object : LabelCaptureBasicOverlayListener { /* @@ -55,49 +52,6 @@ overlay.listener = object : LabelCaptureBasicOverlayListener { } ``` - - - -```java -overlay.setListener(new LabelCaptureBasicOverlayListener() { - @Nullable - @Override - public Brush brushForLabel( - @NonNull LabelCaptureBasicOverlay overlay, - @NonNull CapturedLabel label - ) { - return null; - } - - @Nullable - @Override - public Brush brushForField( - @NonNull LabelCaptureBasicOverlay overlay, - @NonNull LabelField field, - @NonNull CapturedLabel label - ) { - if (field.getName().equals("")) { - return new Brush( - getResources().getColor(R.color.barcode_overlay_fill), - getResources().getColor(R.color.barcode_overlay_stroke), - 0f - ); - } - - if (field.getName().equals("")) { - return new Brush( - getResources().getColor(R.color.expiry_date_overlay_fill), - getResources().getColor(R.color.expiry_date_overlay_stroke), - 0f - ); - } - - return null; - } -}); -``` - - :::tip You can also use `LabelCaptureBasicOverlay.setLabelBrush()` and `LabelCaptureBasicOverlay.setCapturedFieldBrush()` to configure the overlay if you don't need to customize the appearance based on the name or content of the fields. @@ -107,9 +61,6 @@ You can also use `LabelCaptureBasicOverlay.setLabelBrush()` and `LabelCaptureBas For more advanced use cases, such as adding custom views or implementing Augmented Reality (AR) features, you can use the `LabelCaptureAdvancedOverlay`. The example below creates an advanced overlay, configuring it to display a styled warning message below expiry date fields when they’re close to expiring, while ignoring other fields. - - - ```kotlin // Create an advanced overlay that allows for custom views to be added over detected label fields // This is the key component for implementing Augmented Reality features @@ -190,123 +141,6 @@ advancedOverlay.listener = object : LabelCaptureAdvancedOverlayListener { } ``` - - - -```java -// Create an advanced overlay that allows for custom views to be added over detected label fields -// This is the key component for implementing Augmented Reality features -LabelCaptureAdvancedOverlay advancedOverlay = LabelCaptureAdvancedOverlay.newInstance( - labelCapture, dataCaptureView); - -// Configure the advanced overlay with a listener that handles AR content creation and positioning -advancedOverlay.setListener(new LabelCaptureAdvancedOverlayListener() { - - @Nullable - @Override - public View viewForCapturedLabel( - @NonNull LabelCaptureAdvancedOverlay overlay, - @NonNull CapturedLabel capturedLabel - ) { - // We return null since we're only adding AR elements to specific fields, not the entire label - return null; - } - - @NonNull - @Override - public Anchor anchorForCapturedLabel( - @NonNull LabelCaptureAdvancedOverlay overlay, - @NonNull CapturedLabel capturedLabel - ) { - // This defines where on the detected label the AR view would be anchored - return Anchor.CENTER; - } - - @NonNull - @Override - public PointWithUnit offsetForCapturedLabel( - @NonNull LabelCaptureAdvancedOverlay overlay, - @NonNull CapturedLabel capturedLabel, - @NonNull View view - ) { - // This defines the offset from the anchor point for the label's AR view - return new PointWithUnit( - new FloatWithUnit(0f, MeasureUnit.PIXEL), - new FloatWithUnit(0f, MeasureUnit.PIXEL) - ); - } - - @Nullable - @Override - public View viewForCapturedLabelField( - @NonNull LabelCaptureAdvancedOverlay overlay, - @NonNull LabelField labelField - ) { - // We only want to create AR elements for expiry date fields that are text-based - if (labelField.getName().toLowerCase().contains("expiry") && - labelField.getType() == LabelFieldType.TEXT) { - - // - // data extraction from expiry date field and days until expiry date calculation - // - - // Assume we have a method `daysUntilExpiry()` that returns the days left until expiry - int daysUntilExpiry = daysUntilExpiry(labelField.getText()); - int dayLimit = 3; // Example threshold - - if (daysUntilExpiry < dayLimit) { - // Create and configure the AR element - a TextView with appropriate styling - // This view will appear as an overlay on the camera feed - TextView textView = new TextView(context); - textView.setText("Item expires soon!"); - textView.setTextColor(Color.WHITE); - textView.setBackgroundColor(Color.RED); - textView.setPadding(16, 8, 16, 8); - - // Add an icon to the left of the text for visual guidance - Drawable drawable = ContextCompat.getDrawable(context, R.drawable.ic_warning); - if (drawable != null) { - drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); - textView.setCompoundDrawables(drawable, null, null, null); - } - textView.setCompoundDrawablePadding(16); // Padding between icon and text - - return textView; - } - } - // Return null for any fields that aren't expiry dates, which means no AR overlay - return null; - } - - @NonNull - @Override - public Anchor anchorForCapturedLabelField( - @NonNull LabelCaptureAdvancedOverlay overlay, - @NonNull LabelField labelField - ) { - // BOTTOM_CENTER places it right below the expiry date text for better visibility - return Anchor.BOTTOM_CENTER; - } - - @NonNull - @Override - public PointWithUnit offsetForCapturedLabelField( - @NonNull LabelCaptureAdvancedOverlay overlay, - @NonNull LabelField labelField, - @NonNull View view - ) { - // This defines the offset from the anchor point - return new PointWithUnit( - new FloatWithUnit(0f, MeasureUnit.DIP), - new FloatWithUnit(22f, MeasureUnit.DIP) - ); - } -}); -``` - - - - ## Validation Flow Implementing a validation flow in your Smart Label Capture application differs from the [Get Started](/sdks/android/label-capture/get-started.md) steps outlined earlier as follows: @@ -315,9 +149,6 @@ Implementing a validation flow in your Smart Label Capture application differs f Validation flow uses a different overlay, the [LabelCaptureValidationFlowOverlay](https://docs.scandit.com/data-capture-sdk/android/label-capture/api/ui/label-capture-validation-flow-overlay.html). This overlay provides a user interface that guides users through the label capture process, including validation steps. - - - ```kotlin // Create the overlay val validationFlowOverlay = LabelCaptureValidationFlowOverlay.newInstance( @@ -329,27 +160,9 @@ val validationFlowOverlay = LabelCaptureValidationFlowOverlay.newInstance( // Set the listener to receive validation events validationFlowOverlay.listener = this ``` - - - -```java -// Create the overlay -validationFlowOverlay = LabelCaptureValidationFlowOverlay.newInstance( - getContext(), - labelCapture, - dataCaptureView -); -// Set the listener to receive validation events -validationFlowOverlay.setListener(this); -``` - - ### Adjust the Hint Messages - - - ```kotlin // Configure the validation flow with custom settings val validationSettings = LabelCaptureValidationFlowSettings.newInstance().apply { @@ -364,31 +177,11 @@ val validationSettings = LabelCaptureValidationFlowSettings.newInstance().apply // Apply the settings to the overlay validationFlowOverlay.applySettings(validationSettings) ``` - - - - -```java -// Configure the validation flow with custom settings -LabelCaptureValidationFlowSettings validationSettings = LabelCaptureValidationFlowSettings.newInstance(); - -validationSettings.setStandbyHintText("No label detected, camera paused"); -validationSettings.setValidationHintText("fields captured"); // X/Y (X fields out of total Y) is shown in front of this string -validationSettings.setValidationErrorText("Input not valid"); - -// Apply the settings to the overlay -validationFlowOverlay.applySettings(validationSettings); -``` - - ### Define a Listener To handle validation events, implement the [LabelCaptureValidationFlowOverlayListener](https://docs.scandit.com/data-capture-sdk/android/label-capture/api/ui/label-capture-validation-flow-listener.html) interface. - - - ```kotlin // This is called by the validation flow overlay when a label has been fully captured and validated override fun onValidationFlowLabelCaptured(fields: List) { @@ -398,24 +191,3 @@ override fun onValidationFlowLabelCaptured(fields: List) { val expiryDate = fields.find { it.name == "" }?.text } ``` - - - -```java -// This is called by the validation flow overlay when a label has been fully captured and validated -@Override -public void onValidationFlowLabelCaptured(@NonNull List fields) { - - String barcodeData = null; - for (LabelField field : fields) { - if (field.getName().equals("")) { - barcodeData = field.getBarcode().getData(); - } else if (field.getName().equals("")) { - String expiryDate = field.getText(); - } - } -} -``` - - - diff --git a/docs/sdks/android/label-capture/get-started.md b/docs/sdks/android/label-capture/get-started.md index ec8debd8..b157a054 100644 --- a/docs/sdks/android/label-capture/get-started.md +++ b/docs/sdks/android/label-capture/get-started.md @@ -50,9 +50,6 @@ It is configured through [LabelCaptureSettings](https://docs.scandit.com/data-ca You can use Label Definitions provided in Smart Label Capture to set pre-built label types or define your label using pre-built fields. For more information, see the [Label Definitions](label-definitions.md) section. ::: - - - ```kotlin import com.scandit.datacapture.label.capture.LabelCapture import com.scandit.datacapture.label.capture.LabelCaptureSettings @@ -80,54 +77,15 @@ val settings = LabelCaptureSettings.builder() val labelCapture = LabelCapture.forDataCaptureContext(dataCaptureContext, settings) ``` - - - - -```java -import com.scandit.datacapture.label.capture.LabelCapture; -import com.scandit.datacapture.label.capture.LabelCaptureSettings; -import com.scandit.datacapture.label.data.LabelDateComponentFormat; -import com.scandit.datacapture.label.data.LabelDateFormat; - -LabelCaptureSettings settings = LabelCaptureSettings.builder() - .addLabel() - /* - * Add a barcode field with the expected symbologies and pattern. - * You can omit the pattern if the content of the barcode is unknown. - */ - .addCustomBarcode() - .setSymbologies(Symbology.EAN13_UPCA, Symbology.CODE128) - .buildFluent("") - .buildFluent("") -.build(); - -/* -* Create the label capture mode with the settings and data capture context created earlier. -*/ -LabelCapture labelCapture = LabelCapture.forDataCaptureContext(dataCaptureContext, settings); -``` - - - - ## Define a Listener to Handle Captured Labels To get informed whenever a new label has been recognized, add a [LabelCaptureListener](https://docs.scandit.com/data-capture-sdk/android/label-capture/api/label-capture-listener.html#interface-scandit.datacapture.label.ILabelCaptureListener) through [LabelCapture.addListener()](https://docs.scandit.com/data-capture-sdk/android/label-capture/api/label-capture.html#method-scandit.datacapture.label.LabelCapture.AddListener) and implement the listener methods to suit your application’s needs. -First conform to the `LabelCaptureListener` interface. Here is an example of how to implement a listener that processes the captured labels based on the label capture settings defined above: +First conform to the `LabelCaptureListener` interface. Here is an example of how to implement a listener that processes the captured labels based on the label capture settings defined above. - - +In this example, we create a `LabelCaptureRepository` class that implements the `LabelCaptureListener` interface. This class is responsible for handling the captured labels and processing them accordingly. + +Depending on your app architecture and whether you use dependency injection or not, you may use a fragment or a repository to implement the listener. ```kotlin labelCapture.addListener(object : LabelCaptureListener { @@ -174,81 +132,6 @@ labelCapture.addListener(object : LabelCaptureListener { }) ``` - - - -In this example, we create a `LabelCaptureRepository` class that implements the `LabelCaptureListener` interface. This class is responsible for handling the captured labels and processing them accordingly. - -Depending on your app architecture and whether you use dependency injection or not, you may use a fragment or a repository to implement the listener. - -```java -public class LabelCaptureRepository implements LabelCaptureListener { - - /* - * We use MutableLiveData to post captured labels to the UI thread. - * You don't need to use MutableLiveData in your implementation, but it's important good practice to keep the UI thread free from heavy processing. - */ - private final MutableLiveData capturedLabels = new MutableLiveData<>(); - - // ... other methods - - @Override - public void onSessionUpdated( - @NonNull LabelCapture labelCapture, - @NonNull LabelCaptureSession session, - @NonNull FrameData frameData) { - /* - * The session update callback is called for every processed frame. - * Check if the session contains any captured labels; if not, continue capturing. - */ - List labels = session.getCapturedLabels(); - - if (!labels.isEmpty()) { - final CapturedLabel label = labels.get(0); - - /* - * Given the label capture settings defined above, - * the barcode field would always be present. - */ - String barcodeData = label.getFields().stream() - .filter(field -> field.getName().equals("")) - .findFirst() - .map(field -> field.getBarcode().getData()) - .orElse(null); - - /* - * The expiry date field is optional. - * Check for null in your result handling. - */ - String expiryDate = label.getFields().stream() - .filter(field -> field.getName().equals("")) - .findFirst() - .map(LabelField::getText) - .orElse(null); - - /* - * Disable the label capture mode after a label has been captured - * to prevent it from capturing the same label multiple times. - */ - labelCapture.setEnabled(false); - - /* - * Post the captured results for further processing. - */ - capturedLabels.postValue(new CapturedLabelEvent(barcodeData, expiryDate)); - - /* - * Consider communicating a successful scan with audio and vibration feedback. - * See the Feedback section for more information. - */ - Feedback.defaultFeedback().emit(); - } - } -} -``` - - - ## Visualize the Scan Process The capture process can be visualized by adding a [DataCaptureView](https://docs.scandit.com/data-capture-sdk/android/core/api/ui/data-capture-view.html#class-scandit.datacapture.core.ui.DataCaptureView) to your view hierarchy. The view controls what UI elements such as the viewfinder, as well as the overlays that are shown to visualize captured labels. @@ -264,9 +147,6 @@ The overlays can be used independently of each other, but you can also use both Here is an example of how to add a `LabelCaptureBasicOverlay` to the `DataCaptureView`: - - - ```kotlin /* * Create the data capture view and attach it to the data capture context created earlier. @@ -290,34 +170,6 @@ val overlay = LabelCaptureBasicOverlay.newInstance(labelCapture, dataCaptureView overlay.viewfinder = RectangularViewfinder(RectangularViewfinderStyle.SQUARE) ``` - - - -```java -/* - * Create the data capture view and attach it to the data capture context created earlier. - */ -DataCaptureView dataCaptureView = DataCaptureView.newInstance(this, dataCaptureContext); - -/* - * Add the data capture view to your view hierarchy, e.g. with setContentView or findViewById. - */ -ViewGroup container = findViewById(R.id.container); /* get your containing view here, e.g. with inflate or findViewById */ -container.addView( - dataCaptureView, - new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT) -); - -/* - * Create the overlay with the label capture mode and data capture view created earlier. - */ -LabelCaptureBasicOverlay overlay = LabelCaptureBasicOverlay.newInstance(labelCapture, dataCaptureView); -overlay.setViewfinder(new RectangularViewfinder(RectangularViewfinderStyle.SQUARE)); -``` - - - - :::tip See the [Advanced Configurations](advanced.md) section for more information about how to customize the appearance of the overlays and how to use the advanced overlay to display arbitrary Android views such as text views, icons or images. ::: @@ -353,23 +205,10 @@ You can use the default feedback, or configure your own sound or vibration. If you already have a [Feedback](https://docs.scandit.com/data-capture-sdk/android/core/api/feedback.html#class-scandit.datacapture.core.Feedback) instance implemented in your application, remove it to avoid double feedback. ::: - - - ```kotlin labelCapture.feedback = LabelCaptureFeedback.defaultFeedback() ``` - - - -```java -labelCapture.setFeedback(LabelCaptureFeedback.defaultFeedback()); -``` - - - - :::note Audio feedback is only played if the device is not muted. :::