/* * Copyright (C) 2008 ZXing authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.zxing.camera; import java.io.IOException; import android.content.Context; import android.graphics.Point; import android.hardware.Camera; import android.hardware.Camera.Size; import android.os.Handler; import android.util.Log; import android.view.SurfaceHolder; import com.google.zxing.open.OpenCameraInterface; /** * 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. * * @author dswitkin@google.com (Daniel Switkin) */ public class CameraManager { private static final String TAG = CameraManager.class.getSimpleName(); private final Context context; private final CameraConfigurationManager configManager; private Camera camera; private AutoFocusManager autoFocusManager; private boolean initialized; private boolean previewing; private int requestedCameraId = -1; /** * 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; 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; } } /** * Convenience method for * {@link org.madmatrix.zxing.android.CaptureActivity} */ public synchronized void setTorch(boolean newSetting) { if (newSetting != configManager.getTorchState(camera)) { if (camera != null) { if (autoFocusManager != null) { autoFocusManager.stop(); } configManager.setTorch(camera, newSetting); if (autoFocusManager != null) { autoFocusManager.start(); } } } } /** * 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 Size getPreviewSize() { if (null != camera) { return camera.getParameters().getPreviewSize(); } return null; } }