android 使用 google 条码 api 从相机扫描条码(缺少什么?)

android scan barcode from camera with google barcode api (what is missing?)

在我的应用依赖项中我有

compile 'com.google.android.gms:play-services:11.0.4'

在清单文件中我有

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

这是我的 activity_main.xml 文件

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="cameratest.test.hasan.com.barcodetest.MainActivity">




    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="text"
        android:text="Name"
        android:layout_marginTop="107dp"
        android:layout_marginEnd="39dp" />

    <RelativeLayout
        android:id="@+id/cameraHolder"
        android:layout_width="176dp"
        android:layout_height="144dp"
        android:layout_marginEnd="75dp"
        android:layout_marginTop="74dp"
        android:keepScreenOn="true"></RelativeLayout>
</RelativeLayout>

MainActivity.java

 public class MainActivity extends AppCompatActivity {
    CameraSurface cameraSurface;
    RelativeLayout relativeLayout;
    EditText etBarkod ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etBarkod = (EditText)findViewById(R.id.editText);
        etBarkod.setOnEditorActionListener(new BarkodEditorActionListener(this.getBaseContext()));
        relativeLayout = (RelativeLayout)findViewById(R.id.cameraHolder);
        relativeLayout.setOnTouchListener(new MovingViewListener());
        cameraSurface = new CameraSurface(this.getBaseContext());
        cameraSurface.setBarkodEditText(etBarkod);
        relativeLayout.addView(cameraSurface);
    }
}

和 CameraSurface.java class 是

    public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback {
    Context context;
    Camera mCamera;
    CameraSource cameraSource;
    SurfaceHolder msurfaceHolder;
    EditText etBarkod;
    public CameraSurface(Context context) {
        super(context);
        super.setKeepScreenOn(true);
        this.context = context;
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,RelativeLayout.LayoutParams.MATCH_PARENT);
        super.setLayoutParams(params);
        msurfaceHolder = this.getHolder();

        msurfaceHolder.addCallback(this);
        msurfaceHolder.setKeepScreenOn(true);
        msurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        attachBarcodeDetector();
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {

        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);

        try {
            mCamera.setPreviewDisplay(msurfaceHolder);
            mCamera.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Camera.Parameters param;
        param = mCamera.getParameters();
        param.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        param.setPreviewFrameRate(0);
        param.setPreviewSize(176, 144);
        mCamera.setParameters(param);
        try {
            //noinspection MissingPermission
            cameraSource.start(msurfaceHolder);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private void attachBarcodeDetector(){
        BarcodeDetector barcodeDetector =
                new BarcodeDetector.Builder(context)
                        .setBarcodeFormats(Barcode.ALL_FORMATS)
                        .build();

    cameraSource = new CameraSource
            .Builder(context, barcodeDetector)
            .setRequestedPreviewSize(176, 144)
            .setAutoFocusEnabled(true)
            .build();
    barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
        @Override
        public void release() {

        }

        @Override
        public void receiveDetections(Detector.Detections<Barcode> detections) {
            final EditText barkod= etBarkod;
            final SparseArray<Barcode> barcodes = detections.getDetectedItems();
            if (barcodes.size() != 0) {
                barkod.post(new Runnable() {    // Use the post method of the TextView
                    public void run() {
                        barkod.setText(    // Update the TextView
                                barcodes.valueAt(0).displayValue
                        );
                    }
                });
            }
        }
    });
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        cameraSource.stop();
    }
    public EditText setBarkodEditText(EditText editText){
        return this.etBarkod = editText;
    }
}

相机工作正常,聚焦良好支持定义的预览大小,但条形码检测器不检测条形码,因此 edittext 值不会改变。

注意:此代码运行良好,我真的不知道我更改了什么,但之后它不再运行了。 我试图了解这段代码有什么问题,但我无法弄清楚。 所以我需要你的帮助。 提前致谢。

Check this may help you:

private void scanBarcode() {
    mCameraView.setZOrderMediaOverlay(true);
    mHolder = mCameraView.getHolder();
    mBarcode = new BarcodeDetector.Builder(this).setBarcodeFormats(Barcode.ALL_FORMATS | Barcode.EAN_13 | Barcode.EAN_8 | Barcode.UPC_A | Barcode.UPC_E | Barcode.CODE_39 | Barcode.CODE_93 |
            Barcode.CODE_128 | Barcode.ITF | Barcode.CODABAR | Barcode.ISBN | Barcode.QR_CODE | Barcode.DATA_MATRIX | Barcode.PDF417 | Barcode.AZTEC).build();

    if (!mBarcode.isOperational()) {
        Toast.makeText(getApplicationContext(), "Sorry,Couldn't setup the detector", Toast.LENGTH_LONG).show();
        this.finish();
    }

    mCameraSource = new CameraSource.Builder(this, mBarcode)
            .setFacing(CameraSource.CAMERA_FACING_BACK)
            .setRequestedFps(15.0f)
            .setAutoFocusEnabled(true)
            .setRequestedPreviewSize(1600, 1024)
            .build();
    mCameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                if (ContextCompat.checkSelfPermission(ScanActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                    mCameraSource.start(mCameraView.getHolder());
                } else {
                    ActivityCompat.requestPermissions(ScanActivity.this, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

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

        }

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

    mBarcode.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) {
                barkod.setText(barcodes.valueAt(0));           
            }
        }
    });
}

请使用 isOperational () 方法查询检测器运行状态

if (!detector.isOperational()) {

}