无需全屏相机的QR码扫描

18

我需要在我的 Android 应用程序中,当应用程序的主视图在屏幕上时连续扫描 QR 码。主视图应包含一个具有相机预览功能的窗口,但不是全屏幕相机预览。

使用示例:主视图包含已扫描 QR 码列表和相机预览。当扫描到新的 QR 码时,它将添加到列表中。

这可能吗?


请查看ZBar Android示例 https://github.com/ZBar/ZBar/tree/master/android - Marware
2个回答

3
我没有一个完整的可用例子,但是我可以给你展示我一个项目中的片段,其中我也将相机预览放在了比全屏小的视图中。我只想传达这个想法。
您需要的是一个FrameLayout来容纳相机预览。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/absoluteLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/transparent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="200dp"
        android:layout_height="200dip" >
    </FrameLayout>

</RelativeLayout>

现在我们需要一个PreviewListener,这也是一个View。
import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/** A basic Camera preview class */
public class CameraPreviewListener extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreviewListener(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);

        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Take care of releasing the Camera preview in your activity.
        Log.d("camera", "surfaceDestroyed");
        if(holder.equals(mHolder)){
            holder.removeCallback(this);            
        }else{
            holder.removeCallback(this);
            mHolder.removeCallback(this);
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();

        } catch (Exception e){
            e.printStackTrace();
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d("camera", "Error starting camera preview: " + e.getMessage());
        }
    }

    public void removeCallback(){
        mHolder = getHolder();
        mHolder.removeCallback(this);
    }
}

最后,您需要在活动中组装所有内容。
import android.hardware.Camera;

Camera mCamera =  = getCameraInstance();
CameraPreviewListener cpl = new CameraPreviewListener(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(cpl);

获取摄像机可以使用以下方法。
/** A safe way to get an instance of the Camera object. */
public Camera getCameraInstance() {
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
        Parameters p = c.getParameters();
        List<Size> sizes = p.getSupportedPictureSizes();

        Size x = null;

        if (sizes.size() < 1) {
            throw new Exception("there are not supported picture sizes at all !!!");
        }

        for (Size s : sizes) {
            if (s.width == 640 && s.height == 480) {
                x = s;
            }
        }

        if (x == null) {
            x = sizes.get(0);
            p.setPictureSize(x.width, x.height);
        } else {
            p.setPictureSize(640, 480);
        }
        p.setJpegQuality(20);
        p.setGpsLatitude(MapViewer.latitude);
        p.setGpsLongitude(MapViewer.longitude);
        c.setParameters(p);
    } catch (Exception e) {
        // Camera is not available (in use or does not exist)
        Log.d(TAG + "(getCameraInstance)", e.getMessage());
    }
    return c; // returns null if camera is unavailable
}

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接