package com.zxing.camera;
|
|
import android.content.Context;
|
import android.content.pm.FeatureInfo;
|
import android.content.pm.PackageManager;
|
import android.graphics.Point;
|
import android.hardware.Camera;
|
import android.hardware.camera2.CameraAccessException;
|
import android.hardware.camera2.CameraCharacteristics;
|
import android.os.Build;
|
import android.os.Handler;
|
import android.util.Log;
|
import android.view.SurfaceHolder;
|
|
import com.zxing.camera.open.OpenCameraInterface;
|
|
import java.io.IOException;
|
|
/**
|
* This object wraps the Camera service object and expects to be the only one
|
* talking to it. The implementation encapsulates the steps needed to take
|
* preview-sized images, which are used for both preview and decoding.
|
*/
|
public class CameraManager {
|
|
private static final String TAG = CameraManager.class.getSimpleName();
|
private boolean status = false; // 记录手机状态
|
private final Context context;
|
private final CameraConfigurationManager configManager;
|
/**
|
* Preview frames are delivered here, which we pass on to the registered
|
* handler. Make sure to clear the handler so it will only receive one
|
* message.
|
*/
|
private final PreviewCallback previewCallback;
|
private Camera camera;
|
private AutoFocusManager autoFocusManager;
|
private boolean initialized;
|
private boolean previewing;
|
private int requestedCameraId = -1;
|
|
public CameraManager(Context context) {
|
this.context = context;
|
this.configManager = new CameraConfigurationManager(context);
|
previewCallback = new PreviewCallback(configManager);
|
}
|
|
/**
|
* Opens the camera driver and initializes the hardware parameters.
|
*
|
* @param holder The surface object which the camera will draw preview frames
|
* into.
|
* @throws IOException Indicates the camera driver failed to open.
|
*/
|
public synchronized void openDriver(SurfaceHolder holder) throws IOException {
|
Camera theCamera = camera;
|
if (theCamera == null) {
|
|
if (requestedCameraId >= 0) {
|
theCamera = OpenCameraInterface.open(requestedCameraId);
|
} else {
|
theCamera = OpenCameraInterface.open();
|
}
|
|
if (theCamera == null) {
|
throw new IOException();
|
}
|
camera = theCamera;
|
}
|
theCamera.setPreviewDisplay(holder);
|
|
if (!initialized) {
|
initialized = true;
|
configManager.initFromCameraParameters(theCamera);
|
}
|
|
Camera.Parameters parameters = theCamera.getParameters();
|
String parametersFlattened = parameters == null ? null : parameters.flatten(); // Save
|
// these,
|
// temporarily
|
try {
|
configManager.setDesiredCameraParameters(theCamera, false);
|
} catch (RuntimeException re) {
|
// Driver failed
|
Log.w(TAG, "Camera rejected parameters. Setting only minimal safe-mode parameters");
|
Log.i(TAG, "Resetting to saved camera params: " + parametersFlattened);
|
// Reset:
|
if (parametersFlattened != null) {
|
parameters = theCamera.getParameters();
|
parameters.unflatten(parametersFlattened);
|
try {
|
theCamera.setParameters(parameters);
|
configManager.setDesiredCameraParameters(theCamera, true);
|
} catch (RuntimeException re2) {
|
// Well, darn. Give up
|
Log.w(TAG, "Camera rejected even safe-mode parameters! No configuration");
|
}
|
}
|
}
|
|
}
|
|
public synchronized boolean isOpen() {
|
return camera != null;
|
}
|
|
/**
|
* Closes the camera driver if still in use.
|
*/
|
public synchronized void closeDriver() {
|
if (camera != null) {
|
camera.release();
|
camera = null;
|
// Make sure to clear these each time we close the camera, so that
|
// any scanning rect
|
// requested by intent is forgotten.
|
}
|
}
|
|
/**
|
* Asks the camera hardware to begin drawing preview frames to the screen.
|
*/
|
public synchronized void startPreview() {
|
Camera theCamera = camera;
|
if (theCamera != null && !previewing) {
|
theCamera.startPreview();
|
previewing = true;
|
autoFocusManager = new AutoFocusManager(context, camera);
|
}
|
}
|
|
/**
|
* Tells the camera to stop drawing preview frames.
|
*/
|
public synchronized void stopPreview() {
|
if (autoFocusManager != null) {
|
autoFocusManager.stop();
|
autoFocusManager = null;
|
}
|
if (camera != null && previewing) {
|
camera.stopPreview();
|
previewCallback.setHandler(null, 0);
|
previewing = false;
|
}
|
}
|
|
/**
|
* A single preview frame will be returned to the handler supplied. The data
|
* will arrive as byte[] in the message.obj field, with width and height
|
* encoded as message.arg1 and message.arg2, respectively.
|
*
|
* @param handler The handler to send the message to.
|
* @param message The what field of the message to be sent.
|
*/
|
public synchronized void requestPreviewFrame(Handler handler, int message) {
|
Camera theCamera = camera;
|
if (theCamera != null && previewing) {
|
previewCallback.setHandler(handler, message);
|
theCamera.setOneShotPreviewCallback(previewCallback);
|
}
|
}
|
|
/**
|
* Allows third party apps to specify the camera ID, rather than determine
|
* it automatically based on available cameras and their orientation.
|
*
|
* @param cameraId camera ID of the camera to use. A negative value means
|
* "no preference".
|
*/
|
public synchronized void setManualCameraId(int cameraId) {
|
requestedCameraId = cameraId;
|
}
|
|
/**
|
* 获取相机分辨率
|
*
|
* @return
|
*/
|
public Point getCameraResolution() {
|
return configManager.getCameraResolution();
|
}
|
|
public Camera.Size getPreviewSize() {
|
if (null != camera) {
|
return camera.getParameters().getPreviewSize();
|
}
|
return null;
|
}
|
|
public Camera getCamera() {
|
return camera;
|
}
|
|
|
}
|