18

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

使用示例:包含扫描二维码列表和相机预览的主视图。扫描新的二维码时,会将其添加到列表中。

可能吗?

4

2 回答 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
}
于 2016-02-16T09:20:29.917 回答
2

希望这对您有用,您可以在不打开相机应用程序的情况下从背景捕获图像

https://stackoverflow.com/a/24849344/1312796

于 2016-02-19T23:41:18.520 回答