Question

I tried my best to find the solution before asking, however, I can't seem to locate a similar situation.

I've implemented a QR scanner for an app I am working on. I'm using the zxing library, specifically using the imports below. Also, the apps uses "Barcode Scanner" from play store (I was prompted to install).

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

The issue is that the scanner only works 1 out every 3-6 scans. I either get a null return, or no output. It always returns back to my source screen, and never produces an actual error.

I used this tutorial as a source: Android SDK: Create a Barcode Reader

Here is the relevant info from mainactivity:

    public void onClick(View v){
            //respond to clicks
            if(v.getId()==R.id.scanQRButton){
                //scan
                IntentIntegrator scanIntegrator = new IntentIntegrator(this);
                scanIntegrator.initiateScan();
                formatTxt.setText( "Scan Initiated");
                contentTxt.setText(" Scan Results: " + scanContent);

                if(scanContent != null){

                    String userid,medname,tabstaken,dob;


                    StringTokenizer st = new StringTokenizer(scanContent, ",");
                         // token 0
                         dob = st.nextToken();
                         //token 1
                         medname = st.nextToken();
                         //token 2
                         tabstaken = st.nextToken();
                         //token 3
                         //rxnumber

                    DatabaseHandler db = new DatabaseHandler(getApplicationContext());

                    HashMap<String,String> user = new HashMap<String, String>();
                    user = db.getUserDetails();

                    //Store the userlog by passing to UserLogEntry
                    userid = user.get("uid");
                    //debug.setText("Userid: "+ userid+ " medname: " + medname + " tabs: " +tabstaken);

                    UserLogEntry userlog = new UserLogEntry(getApplicationContext(),userid,medname,tabstaken);
                    userlog.addUserLog();



                }



            }

        }

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        //retrieve scan result
        IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);

        if (scanningResult != null) {
            //we have a result
            scanContent = scanningResult.getContents();



        }
        else{
            Toast toast = Toast.makeText(getApplicationContext(), 
                "No scan data received!", Toast.LENGTH_SHORT);
            toast.show();
        }
    }


}

And here are the ZXing classes from the library package I'm using:

IntentResults:

https://code.google.com/p/zxing/source/browse/trunk/android-integration/src/com/google/zxing/integration/android/IntentResult.java?r=1273

IntentIntegrator:

https://code.google.com/p/zxing/source/browse/trunk/android-integration/src/com/google/zxing/integration/android/IntentIntegrator.java?spec=svn2260&r=2260

Any ideas on how to get this to work %100 of the time?

Thanks!

Was it helpful?

Solution

So I tried several different ways to get the scanner to work with zxing, and nothing would work. It just felt buggy no matter what I did. That on top of the fact that integrating the scanner so it doesn't need a third party app (as in Barcode scanner) was a major pain. I decided to look for an alternative and found ZBar.

If anyone has any problems using zxing for QR scanning I'd recommend using Zbar instead. The code itself is much simpler. You can use the example given on the zbar page and pretty much copy and paste it into your project without changes(or very little). Also, integrating it as an all inclusive scanner is simple as can be.

I'm including the instructions here for a more inclusive answer. This information is available in tutorials, and at the ZBar page, however, it doesn't hurt to include them here in my answer.

  1. First download the zip here: https://github.com/dm77/ZBarScanner
  2. Then add "ZBarScannerLibrary" as an existing android project.
  3. For ZBarScannerLibrary: Right click->properties->android and check "Is Library"
  4. Select your project (the one you're adding qr scanner to), right click->properties->android->Add select ZBarScannerLibrary.
  5. Now add the ZBar code given on the page: https://github.com/dm77/ZBarScanner (shown below to be helpful.
  6. Enjoy qr scanning without pulling out your hair

Here is the main activity for the sample provided with ZBar. Don't forget to add the appropriate lines to android manifest:

<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" />

Within the application element, add the activity declaration:

<activity android:name="com.dm.zbar.android.scanner.ZBarScannerActivity"
        android:screenOrientation="landscape"
        android:label="@string/app_name" />

I used a String Tokenizer to pull apart the QR results and sort them into specific variables.

    package com.dm.zbar.android.examples;

    import android.app.Activity;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.os.Bundle;
    import android.text.TextUtils;
    import android.view.View;
    import android.widget.Toast;
    import com.dm.zbar.android.scanner.ZBarConstants;
    import com.dm.zbar.android.scanner.ZBarScannerActivity;
    import net.sourceforge.zbar.Symbol;

    public class MainActivity extends Activity {

    private static final int ZBAR_SCANNER_REQUEST = 0;
    private static final int ZBAR_QR_SCANNER_REQUEST = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void launchScanner(View v) {
        if (isCameraAvailable()) {
            Intent intent = new Intent(this, ZBarScannerActivity.class);
            startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
        } else {
            Toast.makeText(this, "Rear Facing Camera Unavailable", Toast.LENGTH_SHORT).show();
        }
    }

    public void launchQRScanner(View v) {
        if (isCameraAvailable()) {
            Intent intent = new Intent(this, ZBarScannerActivity.class);
            intent.putExtra(ZBarConstants.SCAN_MODES, new int[]{Symbol.QRCODE});
            startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
        } else {
            Toast.makeText(this, "Rear Facing Camera Unavailable", Toast.LENGTH_SHORT).show();
        }
    }

    public boolean isCameraAvailable() {
        PackageManager pm = getPackageManager();
        return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case ZBAR_SCANNER_REQUEST:
            case ZBAR_QR_SCANNER_REQUEST:
                if (resultCode == RESULT_OK) {
                    Toast.makeText(this, "Scan Result = " + data.getStringExtra(ZBarConstants.SCAN_RESULT), Toast.LENGTH_SHORT).show();
                } else if(resultCode == RESULT_CANCELED && data != null) {
                    String error = data.getStringExtra(ZBarConstants.ERROR_INFO);
                    if(!TextUtils.isEmpty(error)) {
                        Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
                    }
                }
                break;
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top