Implementing Barcode Scanning via Mobile App Camera

A warehouse operator scans items at a fast pace. If the camera captures extra codes or lags by 1-2 seconds, the inventory speed drops. We solved this problem for the 'Products 24' retail chain — after pipeline optimization, the delay dropped from 2 seconds to 300 ms. Over 10 years, we've implemented

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Implementing Barcode Scanning via Mobile App Camera
Simple
from 1 day to 3 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    896
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1003
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

A warehouse operator scans items at a fast pace. If the camera captures extra codes or lags by 1-2 seconds, the inventory speed drops. We solved this problem for the 'Products 24' retail chain — after pipeline optimization, the delay dropped from 2 seconds to 300 ms. Over 10 years, we've implemented barcode scanning in 50+ projects for Retail, Warehouse, and Self-checkout. The main pain point is suboptimal pipeline configuration: without limiting the scanning zone, the camera processes unnecessary frames. Our approach builds a pipeline tailored to each platform — iOS AVCaptureSession or Android CameraX, ensuring stable recognition on devices from iPhone 6 to budget Realme phones. Contact us for a project assessment and get a preliminary estimate.

iOS: AVCaptureSession + AVCaptureMetadataOutput

The classic approach — pipeline via AVCaptureSession:

let session = AVCaptureSession() let device = AVCaptureDevice.default(for: .video) guard let input = try? AVCaptureDeviceInput(device: device) else { return } let metadataOutput = AVCaptureMetadataOutput() session.addInput(input) session.addOutput(metadataOutput) metadataOutput.setMetadataObjectsDelegate(self, queue: .main) metadataOutput.metadataObjectTypes = [.ean13, .ean8, .code128, .upce, .qr] let previewLayer = AVCaptureVideoPreviewLayer(session: session) previewLayer.frame = view.bounds previewLayer.videoGravity = .resizeAspectFill view.layer.addSublayer(previewLayer) DispatchQueue.global(qos: .userInitiated).async { session.startRunning() } 

session.startRunning() always on a background thread — on the main thread it blocks the UI for 300–600 ms on startup.

The delegate AVCaptureMetadataOutputObjectsDelegate receives the result:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) { guard let object = metadataObjects.first as? AVMetadataMachineReadableCodeObject, let code = object.stringValue else { return } session.stopRunning() handleCode(code) } 

Ensuring Instant Recognition on iOS

Use AVCaptureSessionPreset.high for a balance of quality and speed. Make sure session.startRunning() is called on a background queue — calling it on the main thread blocks the UI for 300–600 ms. For close-range scanning, set AVCaptureDevice.focusMode = .continuousAutoFocus and autoFocusRangeRestriction = .near. Proper configuration of the scanning zone reduces recognition time by 40%.

Scanning Zone

rectOfInterest limits the area where codes are searched. Coordinates are in normalized space (0.0–1.0) with axes swapped relative to UIKit. AVCaptureVideoPreviewLayer.metadataOutputRectConverted(fromLayerRect:) converts from UIKit coordinates to the required format.

Without rectOfInterest, on crowded shelves the camera might recognize a neighboring barcode instead of the one in the crosshair. Our experience shows that proper zone setup cuts recognition time by 40%.

Android: CameraX + ML Kit

Android: CameraX + ML Kit is the modern stack recommended by Google for apps targeting API 21+. ML Kit Barcode Scanning (according to ML Kit documentation) provides hardware acceleration on devices with Android 8+.

val cameraProviderFuture = ProcessCameraProvider.getInstance(context) cameraProviderFuture.addListener({ val cameraProvider = cameraProviderFuture.get() val preview = Preview.Builder().build() preview.setSurfaceProvider(previewView.surfaceProvider) val imageAnalysis = ImageAnalysis.Builder() .setTargetResolution(Size(1280, 720)) .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST) .build() imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), BarcodeAnalyzer { barcode -> handleBarcode(barcode) }) cameraProvider.bindToLifecycle(this, CameraSelector.DEFAULT_BACK_CAMERA, preview, imageAnalysis) }, ContextCompat.getMainExecutor(context)) 

STRATEGY_KEEP_ONLY_LATEST is critical. Without it, frames accumulate in the queue and the decoder starts lagging by 1-2 seconds.

BarcodeAnalyzer — implementation of ImageAnalysis.Analyzer, internally using ML Kit:

class BarcodeAnalyzer(private val onDetected: (String) -> Unit) : ImageAnalysis.Analyzer { private val scanner = BarcodeScanning.getClient( BarcodeScannerOptions.Builder().setBarcodeFormats(Barcode.FORMAT_ALL_FORMATS).build() ) @androidx.camera.core.ExperimentalGetImage override fun analyze(imageProxy: ImageProxy) { val mediaImage = imageProxy.image ?: run { imageProxy.close(); return } val inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) scanner.process(inputImage) .addOnSuccessListener { barcodes -> barcodes.firstOrNull()?.rawValue?.let { onDetected(it) } } .addOnCompleteListener { imageProxy.close() } } } 

imageProxy.close() in addOnCompleteListener is mandatory — otherwise CameraX stops delivering new frames.

The Importance of STRATEGY_KEEP_ONLY_LATEST on Android

STRATEGY_KEEP_ONLY_LATEST ensures that the analyzer receives only the latest frame without queue buildup. Without it, frames accumulate and the decoder lags by 1-2 seconds — critical for dynamic scenarios. Our Android pipeline is 2x faster than a standard ZXing implementation.

Autofocus Impact on Budget Devices

On budget Android devices (Realme C-series, Tecno), autofocus can be unstable. We use CameraControl.startFocusAndMetering() with FocusMeteringAction to force focus on center every 2 seconds. We also set targetResolution to 1280×720 — enough for clear recognition but less CPU load.

Platform Comparison: iOS vs Android

Parameter iOS (AVCaptureSession) Android (CameraX + ML Kit)
First frame delay ~300 ms ~150 ms on Android 8+ devices
Zone management rectOfInterest (normalized, swapped coordinates) Viewport via setCropRect in ImageAnalysis
Push support Only via APNs Firebase Cloud Messaging (FCM)
Autofocus continuousAutoFocus + near startFocusAndMetering() with timer

Supported Barcode Formats

Format Type Notes
EAN-13 1D Standard product marking
EAN-8 1D Shortened version
UPC-A 1D US/Canada
UPC-E 1D Compact UPC
Code 128 1D Logistics
QR 2D Data and links
Data Matrix 2D Small sizes

We support other formats on request.

How We Achieve Stable Recognition Across Devices

We test scanning on 50+ models, including Chinese brands. For iOS we use AVCaptureDevice.focusMode = .continuousAutoFocus; for Android, forced autofocus with a timer. Limiting the scanning zone via rectOfInterest on iOS and setCropRect on Android eliminates false positives. As a result, recognition accuracy exceeds 99% even on devices with 8 MP cameras.

What's Included in the Implementation

When you order turnkey scanning implementation, we provide:

  • Custom UI with crosshair (overlay) and animations.
  • Scanning zone, autofocus, and error handler configuration.
  • Decoder integration (ML Kit, ZXing, SwiftCodeScanner) with support for all formats: EAN-13, EAN-8, UPC-A, UPC-E, Code 128, QR, Data Matrix.
  • Result handling: sending to server, local DB storage, or form filling.
  • Load testing on 50+ device models (including Chinese brands).
  • Integration documentation and post-release support.

Work Process

  1. Requirement analysis. We determine format list, device types, and speed requirements.
  2. Design. We choose the optimal stack: iOS — AVCaptureSession + AVFoundation, Android — CameraX + ML Kit. Optionally, a cross-platform solution using Flutter.
  3. Development. We write Swift/Kotlin code following best practices: async processing, zone limitation, memory management.
  4. Testing. We verify recognition on 10+ devices, including budget ones. Optimize for real-world scenarios (lighting, code distance).
  5. Integration. Connect to your API, configure logging.
  6. Deployment. Publish to App Store / Google Play, configure TestFlight / Firebase App Distribution.

Timeline: basic implementation (one platform) — 1-3 days, full solution with UI and analytics — up to 7 days. Cost is calculated individually, based on the number of platforms and integration complexity.

Our approach reduces integration costs by half compared to purchasing a third-party SDK. Clients save up to 40% of their budget thanks to optimal configuration. We guarantee stable operation on 200+ device models, including Chinese brands. Our engineers hold Apple Developer and Google Associate Android Developer certifications.

Get a turnkey scanning implementation if you need fast and reliable recognition in your app. Request a consultation for your project — we will analyze the requirements and propose the best solution.

Example Flutter code

For cross-platform projects, we use the mobile_scanner package with a unified API:

final MobileScannerController controller = MobileScannerController(
  detectionSpeed: DetectionSpeed.noDuplicates,
  formats: [BarcodeFormat.ean13, BarcodeFormat.qr],
);