{"id":3464,"date":"2025-04-10T11:54:21","date_gmt":"2025-04-10T11:54:21","guid":{"rendered":"https:\/\/alsaeeddev.com\/?p=3464"},"modified":"2025-04-15T01:18:23","modified_gmt":"2025-04-15T01:18:23","slug":"barcode-scanner-app-in-android-java","status":"publish","type":"post","link":"https:\/\/alsaeeddev.com\/shop\/barcode-scanner-app-in-android-java\/","title":{"rendered":"\ud83d\udcf7 Barcode Scanner App in Android Java"},"content":{"rendered":"<p>If you&#8217;re searching for a simple yet powerful way to create a Barcode Scanner App in Android Java using Android Studio, you&#8217;re in the right place! This tutorial will guide you through building a fully functional barcode and QR code scanner using Google\u2019s Mobile Vision API and Android\u2019s CameraSource class.<\/p>\n<p>This project is ideal for retail apps, inventory management systems, attendance apps, and more.<\/p>\n<h2>\u2705 Features of This Barcode Scanner App<\/h2>\n<ul>\n<li>Real-time barcode scanning using device camera<\/li>\n<li>Supports all barcode formats (QR, UPC, Data Matrix, etc.)<\/li>\n<li>Auto-focus enabled for accurate scanning<\/li>\n<li>Audio beep tone when a barcode is detected<\/li>\n<li>Displays decoded data in a TextView<\/li>\n<\/ul>\n<h2>\ud83d\udee0\ufe0f Tools &amp; Setup Requirements<\/h2>\n<ul>\n<li>Android Studio<\/li>\n<li>Java language<\/li>\n<li>Minimum SDK: 21 (Lollipop)<\/li>\n<li>Dependencies:<\/li>\n<\/ul>\n<pre><code>implementation 'com.google.android.gms:play-services-vision:20.1.3'<\/code><\/pre>\n<h2>\ud83d\udcc4 Full Java Code for Barcode Scanner (MainActivity.java)<\/h2>\n<pre><code>public class MainActivity extends AppCompatActivity {\r\n\r\n    private SurfaceView surfaceView;\r\n    private BarcodeDetector barcodeDetector;\r\n    private CameraSource cameraSource;\r\n    private static final int REQUEST_CAMERA_PERMISSION = 201;\r\n    private ToneGenerator toneGen1;\r\n    private TextView barcodeText;\r\n    private String barcodeData;\r\n\r\n    @Override\r\n    protected void onCreate(Bundle savedInstanceState) {\r\n        super.onCreate(savedInstanceState);\r\n        setContentView(R.layout.activity_main);\r\n\r\n        toneGen1 = new ToneGenerator(AudioManager.STREAM_MUSIC, 100);\r\n        surfaceView = findViewById(R.id.surface_view);\r\n        barcodeText = findViewById(R.id.barcode_text);\r\n\r\n        initialiseDetectorsAndSources();\r\n    }\r\n\r\n    private void initialiseDetectorsAndSources() {\r\n        barcodeDetector = new BarcodeDetector.Builder(this)\r\n                .setBarcodeFormats(Barcode.ALL_FORMATS)\r\n                .build();\r\n\r\n        cameraSource = new CameraSource.Builder(this, barcodeDetector)\r\n                .setRequestedPreviewSize(640, 480)\r\n                .setAutoFocusEnabled(true)\r\n                .build();\r\n\r\n        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {\r\n            @Override\r\n            public void surfaceCreated(SurfaceHolder holder) {\r\n                try {\r\n                    if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {\r\n                        cameraSource.start(surfaceView.getHolder());\r\n                    } else {\r\n                        ActivityCompat.requestPermissions(MainActivity.this,\r\n                                new String[]{Manifest.permission.CAMERA},\r\n                                REQUEST_CAMERA_PERMISSION);\r\n                    }\r\n                } catch (IOException e) {\r\n                    e.printStackTrace();\r\n                }\r\n            }\r\n\r\n            @Override\r\n            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {}\r\n\r\n            @Override\r\n            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {\r\n                cameraSource.stop();\r\n            }\r\n        });\r\n\r\n        barcodeDetector.setProcessor(new Detector.Processor&lt;Barcode&gt;() {\r\n            @Override\r\n            public void release() {}\r\n\r\n            @Override\r\n            public void receiveDetections(@NonNull Detector.Detections&lt;Barcode&gt; detections) {\r\n                final SparseArray&lt;Barcode&gt; barcodes = detections.getDetectedItems();\r\n\r\n                if (barcodes.size() != 0) {\r\n                    barcodeText.post(() -&gt; {\r\n                        if (barcodes.valueAt(0).email != null) {\r\n                            barcodeData = barcodes.valueAt(0).email.address;\r\n                        } else {\r\n                            barcodeData = barcodes.valueAt(0).displayValue;\r\n                        }\r\n\r\n                        barcodeText.setText(barcodeData);\r\n                        toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP, 150);\r\n                    });\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    @Override\r\n    protected void onPause() {\r\n        super.onPause();\r\n        Objects.requireNonNull(getSupportActionBar()).hide();\r\n        cameraSource.release();\r\n    }\r\n\r\n    @Override\r\n    protected void onResume() {\r\n        super.onResume();\r\n        Objects.requireNonNull(getSupportActionBar()).hide();\r\n        initialiseDetectorsAndSources();\r\n    }\r\n}<\/code><\/pre>\n<h2>\ud83d\udd0d Code Explanation<\/h2>\n<ol>\n<li><strong>SurfaceView &amp; CameraSource<\/strong><br \/>\n&#8211; SurfaceView: Renders the live camera preview.<br \/>\n&#8211; CameraSource: Controls the camera feed and feeds frames into the BarcodeDetector.<\/li>\n<li><strong>BarcodeDetector<\/strong><br \/>\n&#8211; Set to detect all barcode formats using Barcode.ALL_FORMATS.<\/li>\n<li><strong>Permissions<\/strong><br \/>\n&#8211; Checks for camera permission before starting the camera. Requests it if not already granted.<\/li>\n<li><strong>ToneGenerator<\/strong><br \/>\n&#8211; A beep sound plays every time a barcode is successfully detected.<\/li>\n<li><strong>Barcode Processing<\/strong><br \/>\n&#8211; If the barcode contains an email, it\u2019s extracted separately; otherwise, the display value is shown.<br \/>\n&#8211; Data is updated on the UI thread using <code>post()<\/code> for safe rendering.<\/li>\n<li><strong>Preview Size<\/strong><br \/>\n&#8211; Set using <code>.setRequestedPreviewSize(640, 480)<\/code> for balance between quality and performance.<\/li>\n<\/ol>\n<h2>\ud83d\udcd0 UI Layout (activity_main.xml)<\/h2>\n<pre><code>&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\r\n&lt;androidx.constraintlayout.widget.ConstraintLayout\r\n    xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\r\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\r\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"\r\n    android:layout_width=\"match_parent\"\r\n    android:layout_height=\"match_parent\"\r\n    tools:context=\".MainActivity\"&gt;\r\n\r\n    &lt;SurfaceView\r\n        android:id=\"@+id\/surface_view\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"480dp\"\r\n        app:layout_constraintTop_toTopOf=\"parent\"\r\n        app:layout_constraintLeft_toLeftOf=\"parent\"\r\n        app:layout_constraintRight_toRightOf=\"parent\" \/&gt;\r\n\r\n    &lt;TextView\r\n        android:id=\"@+id\/barcode_text\"\r\n        android:layout_width=\"match_parent\"\r\n        android:layout_height=\"50dp\"\r\n        android:layout_marginLeft=\"30dp\"\r\n        android:layout_marginRight=\"30dp\"\r\n        app:layout_constraintTop_toBottomOf=\"@id\/surface_view\"\r\n        android:layout_marginTop=\"50dp\"\r\n        android:text=\"Barcode Text\"\r\n        android:textSize=\"25sp\"\r\n        android:padding=\"5dp\" \/&gt;\r\n\r\n&lt;\/androidx.constraintlayout.widget.ConstraintLayout&gt;\r\n<\/code><\/pre>\n<h2>\ud83d\udd12 Important Permissions (AndroidManifest.xml)<\/h2>\n<pre><code>&lt;uses-permission android:name=\"android.permission.CAMERA\" \/&gt;\r\n&lt;uses-feature android:name=\"android.hardware.camera\" android:required=\"true\" \/&gt;\r\n<\/code><\/pre>\n<h2>\u2705 Conclusion<\/h2>\n<p>This guide helped you build a real-time barcode scanner app using Java in Android Studio. You learned how to use SurfaceView, CameraSource, BarcodeDetector, and handle permissions, audio tones, and camera lifecycle.<\/p>\n<p><strong>You can expand this app by:<\/strong><\/p>\n<ul style=\"margin-top: -8px;\">\n<li>Saving scanned data to a database<\/li>\n<li>Opening URLs directly from QR codes<\/li>\n<li>Switching between front and back camera<\/li>\n<\/ul>\n<hr \/>\n<p><iframe loading=\"lazy\" title=\"Build a Barcode Scanner App in Android Java | Free Source Code |  #shorts #androidstudio #java\" width=\"640\" height=\"480\" src=\"https:\/\/www.youtube.com\/embed\/De6YsmILcrI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/p>\n<hr \/>\n<p><a href=\"https:\/\/github.com\/alsaeeddev\/BarcodeScan\/archive\/refs\/heads\/main.zip\">Download Source Code<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re searching for a simple yet powerful way to create a Barcode Scanner App in Android Java using Android Studio, you&#8217;re in the right place! This tutorial will guide you through building a fully functional barcode and QR code scanner using Google\u2019s Mobile Vision API and Android\u2019s CameraSource class. This project is ideal for [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3465,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1,117,164],"tags":[22,27,30,17,29,26,23,19,14,31,20,25,18,12,21,16,24,15,13,28],"class_list":["post-3464","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","category-java","category-source-codes","tag-android-app-development","tag-android-camera-api-tutorial","tag-android-camera-app-java","tag-android-camerasource-example","tag-android-inventory-app","tag-android-permissions-example","tag-android-projects-for-beginners","tag-android-qr-scanner-app","tag-android-studio-barcode-scanner","tag-android-studio-sample-project","tag-android-studio-tutorial-java","tag-android-surfaceview-camera","tag-barcode-detector-android","tag-barcode-scanner-android","tag-barcode-scanner-source-code","tag-google-mobile-vision-api","tag-java-android-app-tutorial","tag-java-barcode-scanner","tag-qr-code-scanner-java","tag-real-time-barcode-scanner"],"_links":{"self":[{"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/posts\/3464","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/comments?post=3464"}],"version-history":[{"count":60,"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/posts\/3464\/revisions"}],"predecessor-version":[{"id":4045,"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/posts\/3464\/revisions\/4045"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/media\/3465"}],"wp:attachment":[{"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/media?parent=3464"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/categories?post=3464"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alsaeeddev.com\/shop\/wp-json\/wp\/v2\/tags?post=3464"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}