如何写一个不带全屏相机的QR码扫描?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (25)

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

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

这可能实现吗?

提问于
用户回答回答于

你也可以在不打开相机应用程序的情况下从背景中捕捉图像。

用户回答回答于

我没有一个完整的工作示例,但是我可以从我的项目中为你提供片段,其中我还将相机预览放在比全屏小的视图中。你需要的是一个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
}

扫码关注云+社区

领取腾讯云代金券