Android SharedPreferences Tutorial and Example

Building A Barcode Scanner App On Android

A barcode scanner is a practical Android project because it combines camera access, real-time image processing, user interface design, and local data storage. A small app can scan an EAN-13 product code, show its value, and save a history of recently scanned items without requiring a remote server.

This project suits learners who have already worked with activities, permissions, and basic Kotlin. It also reflects everyday use in Australia, where barcodes appear on supermarket products, parcel labels, library items, and goods sold at weekend markets from Sydney to Perth.

Choose The Scanning Approach

The simplest modern approach is CameraX for the camera preview and Google ML Kit Barcode Scanning for recognition. CameraX manages the device camera across a wide range of Android phones, while ML Kit identifies formats such as QR codes, EAN-13, EAN-8, UPC-A, Code 128, and Data Matrix.

Create a new Android Studio project using Kotlin and a recent minimum SDK that suits your audience. Add the CameraX core, camera-camera2, lifecycle, and view dependencies, along with the ML Kit barcode-scanning library. Keeping these components current matters because manufacturers vary widely; a budget Android handset used in regional Queensland may behave differently from a newer Pixel or Samsung device in Melbourne.

Limit recognition to formats your app actually needs. For a grocery-focused tool, EAN-13 and EAN-8 are useful choices, while a warehouse utility may also require Code 128. Narrowing the format list can reduce unnecessary processing and make the scanner feel more responsive.

Request Camera Permission Safely

Camera access must be declared in the manifest with the CAMERA permission. It must also be requested at runtime on modern Android versions. Ask when the user reaches the scanning screen rather than immediately after installation, and explain that the permission is required to analyse the barcode through the live preview.

If permission is denied, display a useful state with a button that opens the application settings. Avoid leaving a blank preview or repeatedly triggering the permission dialog. Australian users may be scanning in bright outdoor conditions at a farmers market or inside a dim Woolworths aisle, so the interface should clearly explain how to move the code into view and improve lighting.

A practical permission flow checks whether access is already granted, requests it when necessary, and starts CameraX only after approval. When the activity pauses, stop or unbind the camera use case so the app does not consume battery or retain the camera unexpectedly.

Build The Camera Preview

Place a PreviewView in the layout and connect it to a ProcessCameraProvider. Bind a preview use case and an image-analysis use case to the activity lifecycle. The preview should fill most of the screen, with a contrasting scanning frame that helps users position a small label accurately.

The analyser receives frames through ImageAnalysis.Analyzer. Convert each ImageProxy into an InputImage using its media image and rotation degrees, then pass it to ML Kit. Always close the ImageProxy after processing, including failure paths; otherwise, the camera pipeline can stall after a few frames.

Use a backpressure strategy such as KEEP_ONLY_LATEST. This prevents a slow recognition operation from creating a long queue of outdated frames. Set the analyser to run on a background executor, while changes to TextViews, buttons, or RecyclerViews must happen on the main thread.

Handle Results Without Repeated Scans

ML Kit returns one or more Barcode objects. For each result, inspect rawValue and display the decoded text. A retail barcode normally returns digits, but a QR code may contain a URL, plain text, or structured information. Check the barcode format before deciding how to present the result.

A live camera can recognise the same code in dozens of consecutive frames. Store the last detected value and ignore matching results for a short interval, or pause analysis after the first successful scan. A vibration or brief sound can provide confirmation, though the user should be able to disable it for quiet environments such as a library.

Validate the value before saving it. Remove accidental whitespace, reject empty results, and show a friendly message when the code is valid but not supported by the current feature set. For Australian retail products, do not assume that every EAN-13 value can reveal a product name locally; the barcode usually identifies a number, while product data requires a separate catalogue.

Present Useful Product Information

After a successful scan, show the number in a result card with actions such as Copy, Scan Again, Save, and Search. A clean layout works well on compact phones and remains readable when the device is mounted above a checkout bench. Include a clear loading state if the app requests product information from an API.

A small local database makes the project more useful. SQLite or Room can store the barcode, display name, scan timestamp, and optional notes. A ListView can support a beginner exercise, while RecyclerView is a better choice for filtering and larger histories. Save timestamps in a consistent format and display them according to the user’s locale, including familiar Australian date ordering where appropriate.

SharedPreferences can store lightweight choices such as sound enabled, preferred scan format, or whether the result screen should open automatically. Keep personal information out of the scan history unless it is genuinely needed. A barcode may be harmless, but notes attached to medical, workplace, or household items can become sensitive.

Test The Scanner In Real Conditions

Test with printed labels, glossy packaging, damaged barcodes, curved bottles, and screens displaying codes. Try different distances and angles rather than relying only on a large, high-contrast test image. Include both landscape and portrait orientations, and verify that the analyser continues correctly after the activity is recreated.

Run tests on several devices and lighting conditions. A phone used on a sunny Brisbane balcony may overexpose a white label, while a scanner operating in a dim Adelaide storeroom may need better guidance. Check focus behaviour, battery use, rotation, permission denial, and the result of pressing the Android back button during analysis.

Keep the code modular by separating camera setup, barcode recognition, result presentation, and storage. This makes later changes easier, whether you add export to CSV, a product lookup service, or a stock-counting mode. Developers who customise their editor can also benefit from macro writing tips when automating repetitive coding tasks around layouts, test data, or project files.

A finished scanner should feel deliberate rather than complicated: permission handling is transparent, recognition stops at the right moment, saved results are easy to review, and every failure state explains what happened. With CameraX, ML Kit, and a modest local database, the project provides a strong foundation for more advanced Android applications serving Australian shoppers, community groups, and small businesses.