How to read barcodes with the camera on Android?

江枫思渺然 提交于 2019-12-03 17:54:03

问题


I want my application to recognize barcodes taken by camera. Is it possible using Android SDK?

Something like this: Barcode Scanner


回答1:


It's not built into the SDK, but you can use the Zxing library. It's free, open source, and Apache-licensed.

The 2016 recommendation is to use the Barcode API, which also works offline.




回答2:


2016 update

With the latest release of Google Play Services, v7.8, you have access to the new Mobile Vision API. That's probably the most convenient way to implement barcode scanning now, and it also works offline.

From the Android Barcode API:

The Barcode API detects barcodes in real-time, on device, in any orientation. It can also detect multiple barcodes at once.

It reads the following barcode formats:

  • 1D barcodes: EAN-13, EAN-8, UPC-A, UPC-E, Code-39, Code-93, Code-128, ITF, Codabar
  • 2D barcodes: QR Code, Data Matrix, PDF-417, AZTEC

It automatically parses QR Codes, Data Matrix, PDF-417, and Aztec values, for the following supported formats:

  • URL
  • Contact information (VCARD, etc.)
  • Calendar event
  • Email
  • Phone
  • SMS
  • ISBN
  • WiFi
  • Geo-location (latitude and longitude)
  • AAMVA driver license/ID



回答3:


Here is a sample code: my app uses ZXing Barcode Scanner.

  1. You need these 2 classes: IntentIntegrator and IntentResult

  2. Call scanner (e.g. OnClickListener, OnMenuItemSelected...), "PRODUCT_MODE" - it scans standard 1D barcodes (you can add more).:

    IntentIntegrator.initiateScan(this, 
               "Warning", 
               "ZXing Barcode Scanner is not installed, download?",
               "Yes", "No",
               "PRODUCT_MODE");
    
  3. Get barcode as a result:

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {  
      switch (requestCode) {
      case IntentIntegrator.REQUEST_CODE:
         if (resultCode == Activity.RESULT_OK) {
    
            IntentResult intentResult = 
               IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
    
            if (intentResult != null) {
    
               String contents = intentResult.getContents();
               String format = intentResult.getFormatName();
    
               this.elemQuery.setText(contents);
               this.resume = false;
               Log.d("SEARCH_EAN", "OK, EAN: " + contents + ", FORMAT: " + format);
            } else {
               Log.e("SEARCH_EAN", "IntentResult je NULL!");
            }
         } else if (resultCode == Activity.RESULT_CANCELED) {
            Log.e("SEARCH_EAN", "CANCEL");
         }
      }
    }
    

contents holds barcode number




回答4:


Here is sample code using camera api

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.Frame;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;

public class MainActivity extends AppCompatActivity {

TextView barcodeInfo;
SurfaceView cameraView;
CameraSource cameraSource;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    cameraView = (SurfaceView) findViewById(R.id.camera_view);
      barcodeInfo = (TextView) findViewById(R.id.txtContent);


    BarcodeDetector barcodeDetector =
            new BarcodeDetector.Builder(this)
                    .setBarcodeFormats(Barcode.CODE_128)//QR_CODE)
                    .build();

    cameraSource = new CameraSource
            .Builder(this, barcodeDetector)
            .setRequestedPreviewSize(640, 480)
            .build();

    cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {

            try {
                cameraSource.start(cameraView.getHolder());
            } catch (IOException ie) {
                Log.e("CAMERA SOURCE", ie.getMessage());
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            cameraSource.stop();
        }
    });


    barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
        @Override
        public void release() {
        }

        @Override
        public void receiveDetections(Detector.Detections<Barcode> detections) {

            final SparseArray<Barcode> barcodes = detections.getDetectedItems();

            if (barcodes.size() != 0) {
                barcodeInfo.post(new Runnable() {    // Use the post method of the TextView
                    public void run() {
                        barcodeInfo.setText(    // Update the TextView
                                barcodes.valueAt(0).displayValue
                        );
                    }
                });
            }
        }
    });
}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.gateway.cameraapibarcode.MainActivity">

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <SurfaceView
        android:layout_width="640px"
        android:layout_height="480px"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:id="@+id/camera_view"/>

    <TextView
        android:text=" code reader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/txtContent"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Process"
        android:id="@+id/button"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true" />
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imgview"/>
</LinearLayout>
</RelativeLayout>

build.gradle(Module:app)

add compile 'com.google.android.gms:play-services:7.8.+' in dependencies




回答5:


You can also use barcodefragmentlib which is an extension of zxing but provides barcode scanning as fragment library, so can be very easily integrated.

Here is the supporting documentation for usage of library




回答6:


module app:

implementation 'com.google.zxing:core:3.2.1'

implementation 'com.journeyapps:zxing-android-embedded:3.2.0@aar'

AndroidManifest.xml

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

MainActivity.java

public class MainActivity extends AppCompatActivity {

    Button BarCode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BarCode = findViewById(R.id.button_barcode);
        final Activity activity = this;

        BarCode.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                IntentIntegrator intentIntegrator = new IntentIntegrator(activity);
                intentIntegrator.setDesiredBarcodeFormats(intentIntegrator.ALL_CODE_TYPES);
                intentIntegrator.setBeepEnabled(false);
                intentIntegrator.setCameraId(0);
                intentIntegrator.setPrompt("SCAN");
                intentIntegrator.setBarcodeImageEnabled(false);
                intentIntegrator.initiateScan();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        IntentResult Result = IntentIntegrator.parseActivityResult(requestCode , resultCode ,data);
        if(Result != null){
            if(Result.getContents() == null){
                Log.d("MainActivity" , "cancelled scan");
                Toast.makeText(this, "cancelled", Toast.LENGTH_SHORT).show();
            }
            else {
                Log.d("MainActivity" , "Scanned");
                Toast.makeText(this,"Scanned -> " + Result.getContents(), Toast.LENGTH_SHORT).show();
            }
        }
        else {
            super.onActivityResult(requestCode , resultCode , data);
        }
    }
}



回答7:


With Google Firebase ML Kit's barcode scanning API, you can read data encoded using most standard barcode formats.

https://firebase.google.com/docs/ml-kit/read-barcodes?authuser=0

You can follow this link to read barcodes efficiently.




回答8:


There are two parts in building barcode scanning feature, one capturing barcode image using camera and second extracting barcode value from the image.

Barcode image can be captured from your app using camera app and barcode value can be extracted using Firebase Machine Learning Kit barcode scanning API.

Here is an example app https://www.zoftino.com/android-barcode-scanning-example




回答9:


I had an issue with the parseActivityForResult arguments. I got this to work:

package JMA.BarCodeScanner;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class JMABarcodeScannerActivity extends Activity {

    Button captureButton;
    TextView tvContents;
    TextView tvFormat;
    Activity activity;

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

        activity = this;
        captureButton = (Button)findViewById(R.id.capture);
        captureButton.setOnClickListener(listener);
        tvContents = (TextView)findViewById(R.id.tvContents);
        tvFormat = (TextView)findViewById(R.id.tvFormat);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent intent) 
    {  
        switch (requestCode) 
        {
            case IntentIntegrator.REQUEST_CODE:
            if (resultCode == Activity.RESULT_OK) 
            {
                IntentResult intentResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);

                if (intentResult != null) 
                {
                   String contents = intentResult.getContents();
                   String format = intentResult.getFormatName();
                   tvContents.setText(contents.toString());
                   tvFormat.setText(format.toString());

                   //this.elemQuery.setText(contents);
                   //this.resume = false;
                   Log.d("SEARCH_EAN", "OK, EAN: " + contents + ", FORMAT: " + format);
                } else {
                    Log.e("SEARCH_EAN", "IntentResult je NULL!");
                }
            } 
            else if (resultCode == Activity.RESULT_CANCELED) {
                Log.e("SEARCH_EAN", "CANCEL");
            }
        }
    }

    private View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
             IntentIntegrator integrator = new IntentIntegrator(activity);
             integrator.initiateScan();
        }
    };
}

Latyout for Activity:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/capture"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Take a Picture"/>

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/tvContents"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/tvFormat"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>


来源:https://stackoverflow.com/questions/4443891/how-to-read-barcodes-with-the-camera-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!