Search code examples
javaandroidandroid-studiozxing

Unable to scan QR code using Zxing library


I'm trying to integrate Zxing into my android application so the user can scan a qr code and it returns the contents of the QR code. I am able to open the barcode scanner however although it looks like it's doing something it doesn't scan the QR code. I have tested it on bar codes and it works so it looks like the issue is specific to qr codes. I've included some code snippets below.

Manifest File

<activity
            android:name="com.journeyapps.barcodescanner.CaptureActivity"
            android:screenOrientation="portrait"
            tools:replace="android:screenOrientation"
            android:stateNotNeeded="true"/>

QR scanner fragment

package com.example.ntuevent.ui.qrScanner;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.example.ntuevent.R;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

public class QRScannerFragment extends Fragment implements View.OnClickListener {

    private QRScannerViewModel qrScannerViewModel;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        qrScannerViewModel =
                ViewModelProviders.of(this).get(QRScannerViewModel.class);
        View root = inflater.inflate(R.layout.fragment_qr_scanner, container, false);
        final TextView textView = root.findViewById(R.id.text_qr_scanner);
        qrScannerViewModel.getText().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                textView.setText(s);
            }
        });

        root.findViewById(R.id.qr_scanner_button).setOnClickListener(this);

        return root;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.qr_scanner_button:
                /* Request camera access */
                ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, 1);
                launchQrScanner();
        }
    }

    private void launchQrScanner() {
        if (validateCameraPermission()) {
            /* Start the scanner */
            IntentIntegrator intentIntegrator = new IntentIntegrator(getActivity());

            /* Customisation options */
            intentIntegrator.setDesiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES);
            intentIntegrator.setPrompt("Scan a barcode");
            intentIntegrator.setCameraId(0);  // Use a specific camera of the device
            intentIntegrator.setBeepEnabled(false);
            intentIntegrator.setOrientationLocked(true);


            /* Start QR scanner */
            intentIntegrator.initiateScan();
        }
    }

    private boolean validateCameraPermission() {
        /* Validates if app has access to camera */
        if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(getContext().getApplicationContext(), "Enable camera permissions to access this feature", Toast.LENGTH_SHORT).show();
            return false;
        }

        return true;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);

        if (intentResult != null) {
            if (intentResult.getContents() == null)
                Toast.makeText(getContext().getApplicationContext(), "Scan was cancelled", Toast.LENGTH_SHORT).show();
            else
                Toast.makeText(getContext().getApplicationContext(), intentResult.getContents(), Toast.LENGTH_SHORT).show();
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }
}

Any help would be great!


Solution

  • do like me for QR code scanner, I used this code for 2 projects and worked without any problem.

    first, add below libraries to your Gradle:

      implementation 'me.dm7.barcodescanner:zxing:1.9.13'
      implementation 'com.journeyapps:zxing-android-embedded:3.6.0@aar'
      implementation 'com.google.zxing:core:3.3.3'
    

    second, in your QR code scanner activity add below codes:

    private IntentIntegrator qrScan;
    

    in onCreate add below:

        qrScan = new IntentIntegrator(this);
        qrScan.setOrientationLocked(false);
        qrScan.initiateScan();
    

    after onCreate add below:

      @Override
       protected void onActivityResult(int requestCode, int resultCode, Intent data) {
       IntentResult result = IntentIntegrator.parseActivityResult(requestCode, 
       resultCode, data);
        if (result != null) {
            if (result.getContents() == null) {
             //scan have an error 
            } else {
               //scan is successful 
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }