CameraManager——Camera的过时替代方法

2024-09-03 15:08

本文主要是介绍CameraManager——Camera的过时替代方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CameraManager

用于检测,表征和连接的系统服务管理器 CameraDevices。
有关与相机设备通信的更多详细信息,请阅读相机开发人员指南或camera2 包文档。
此类的实例,必须使用能够获得Context.getSystemService(Class)与所述参数CameraManager.class或Context.getSystemService(String)使用参数Context.CAMERA_SERVICE。

getCameraIdList

public String[] getCameraIdList ()

按标识符返回当前连接的摄像机设备列表,包括其他摄像机API客户端可能正在使用的摄像机。
不可移动摄像头使用从0开始的整数作为其标识符,而可移动摄像头具有每个单独设备的唯一标识符,即使它们是相同的模型

返回
String[]:当前连接的摄像机设备列表。该值永远不会为空。

openCamera

public void openCamera(String cameraId,CameraDevice.StateCallback callback,Handler handler)

  • 打开与具有给定ID的摄像机的连接。
  • 使用getCameraIdList()以获取可用的相机设备的列表。请注意,即使列出了id,如果设备在对getCameraIdList()和openCamera(String, CameraDevice.StateCallback, Handler)的呼叫之间断开连接,或者如果优先级较高的摄像机API客户端开始使用摄像机设备,则打开可能会失败。
  • 从API第23级开始,由于设备的优先级较低,调用了cameramanamanager.availabilityCallback.oncameraunavailable(string)回调的设备,当调用的camera api客户端的优先级高于当前camera ap时,仍可以通过调用此方法打开后台camera api客户端。使用此设备的客户端,一般来说,如果应用程序进程中正在运行Top、Foreground活动,则在访问相机时,进程将被赋予最高优先级,并且即使另一个相机API客户端正在使用相机设备,此方法也将成功。任何以这种方式失去对相机控制的低优先级应用程序都将收到cameradevice.StateCallback.OnDisconnected(cameradevice)回调。
  • 一旦相机成功打开,CameraDevice.StateCallback.onOpened(CameraDevice)将使用新打开的方式调用CameraDevice。然后可以通过调用CameraDevice.createCaptureSession(SessionConfiguration)和 设置摄像机设备进行操作CameraDevice.createCaptureRequest(int)
    如果在此函数调用返回后初始化期间摄像机断开连接,则将跳过CameraDevice.StateCallback.onDisconnected(CameraDevice)与处于断开状态的CameraDevice(以及CameraDevice.StateCallback.onOpened(CameraDevice))。
    如果打开相机设备失败,则将调用设备回调的onError方法,并且相机设备上的后续调用将抛出CameraAccessException。
  • 需要CAMERA权限。

参数
cameraId:String:要打开的摄像机设备的唯一标识符,该值不得为null。
callback:CameraDevice.StateCallback:打开相机后调用的回调,该值不得为null。
handler:应该调用回调的handler或null,handler的参数使用当前线程的循环器。

openCamera

public void openCamera (String cameraId,
Executor executor,
CameraDevice.StateCallback callback)

使用给定的ID打开相机的连接。
此方法的行为与openCamera(String,StateCallback,Handler)的行为相匹配,除了它使用Executor作为参数而不是Handler。
需要相机权限

参数
cameraId:要打开的摄像机设备的唯一标识符,该值不得为null。
executor:调用回调时将使用的executor。这个值不能为null。通过此Executor调度回调和侦听器事件,提供一种简单的方法来控制使用哪个线程。 要通过应用程序的主线程调度事件,可以使用Context.getMainExecutor()。 要通过共享线程池调度事件,您可以使用AsyncTask.THREAD_POOL_EXECUTOR.

registerAvailabilityCallback

public void registerAvailabilityCallback (Executor executor,
CameraManager.AvailabilityCallback callback)

注册一个回调以获得有关相机设备可用性的通知。
此方法的行为与registerAvailabilityCallback(AvailabilityCallback,Handler)的行为匹配,除了它使用Executor作为参数而不是Handler。

registerAvailabilityCallback

public void registerAvailabilityCallback (CameraManager.AvailabilityCallback callback,
Handler handler)

  • 注册一个回调以获得有关相机设备可用性的通知。
  • 再次注册相同的回调将替换handler提供的新回调。
  • 第一次注册回调时,会立即调用所有当前已知的摄像机设备的可用性状态。
  • 每当相机API客户端打开相机设备时,都会调用CameraManager.AvailabilityCallback.onCameraUnavailable(String)。 从API级别23开始,其他相机API客户端仍然可以打开这样的相机设备,如果它们具有比相机设备的现有客户端更高的优先级,则驱逐现有客户端。 有关详细信息,请参阅open()。
  • 由于此回调将在相机服务中注册,因此请务必在不再需要时取消注册; 否则回调将继续无限期地接收事件,并可能阻止其他资源被释放。 具体来说,回调将独立于一般活动生命周期而独立于各个CameraManager实例的状态进行调用。

registerTorchCallback

public void registerTorchCallback (CameraManager.TorchCallback callback,Handler handler)

  • 注册一个回调以获得有关torch 模式状态的通知。
  • 再次注册相同的回调将使用提供的新处理程序替换处理程序。
    第一次注册回调时,立即使用闪光灯装置的所有当前已知相机设备的手电筒模式状态调用。
  • 由于此回调将在相机服务中注册,因此请务必在不再需要时取消注册; 否则回调将继续无限期地接收事件,并可能阻止其他资源被释放。 具体来说,回调将独立于一般活动生命周期而独立于各个CameraManager实例的状态进行调用。

registerTorchCallback

注册一个回调以获得有关torch 模式状态的通知。
此方法的行为与registerTorchCallback(TorchCallback, Handler)的行为匹配,除了它使用Executor作为参数而不是Handler。

setTorchMode

public void setTorchMode (String cameraId,
boolean enabled)

  • 无需打开相机设备即可设置给定ID的相机的闪光灯组件的手电筒模式。
  • 使用getCameraIdList()获取可用摄像头设备列表,并使用getCameraCharacteristics(String)检查摄像头设备是否具有闪光灯组件。 请注意,即使相机设备配有闪光灯组件,如果正在使用打开手电筒模式所需的相机设备或其他相机资源,则开启手电筒模式可能会失败
  • 如果调用setTorchMode(String,boolean)成功打开或关闭手电筒模式,将调用CameraManager.TorchCallback.onTorchModeChanged(String,boolean)。 但是,即使打开手电筒模式成功,应用程序也不拥有闪光灯组件或相机设备的专有权。 当闪光灯所属的摄像机设备不可用或其他摄像机资源使手电筒打开时,手电筒模式将关闭并变为不可用(将调用CameraManager.TorchCallback.onTorchModeUnavailable(String))。 此外,其他应用程序可以自由调用setTorchMode(String,boolean)来关闭手电筒模式(将调用CameraManager.TorchCallback.onTorchModeChanged(String,boolean))。 如果打开手电筒模式的最新应用程序退出,则将关闭手电筒模式。

unregisterAvailabilityCallback

public void unregisterAvailabilityCallback (CameraManager.AvailabilityCallback callback)

删除以前添加的回调; 回调将不再接收连接和断开连接回调。
删除未注册无用的回调。

unregisterTorchCallback

public void unregisterTorchCallback (CameraManager.TorchCallback callback)

删除以前添加的回调; 回调将不再接收手电筒模式状态回调。
删除未注册无用的回调。

Camera使用示例

package com.yds.animation.camera;import android.support.v4.app.Fragment;import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;import com.yds.animation.camerademo.R;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;public class Camera2BasicFragment extends Fragmentimplements View.OnClickListener, ActivityCompat.OnRequestPermissionsResultCallback {/*** Conversion from screen rotation to JPEG orientation.*/private static final SparseIntArray ORIENTATIONS = new SparseIntArray();private static final int REQUEST_CAMERA_PERMISSION = 1;private static final String FRAGMENT_DIALOG = "dialog";static {ORIENTATIONS.append(Surface.ROTATION_0, 90);ORIENTATIONS.append(Surface.ROTATION_90, 0);ORIENTATIONS.append(Surface.ROTATION_180, 270);ORIENTATIONS.append(Surface.ROTATION_270, 180);}/*** Tag for the {@link Log}.*/private static final String TAG = "Camera2BasicFragment";/*** Camera state: Showing camera preview.*/private static final int STATE_PREVIEW = 0;/*** Camera state: Waiting for the focus to be locked.*/private static final int STATE_WAITING_LOCK = 1;/*** Camera state: Waiting for the exposure to be precapture state.*/private static final int STATE_WAITING_PRECAPTURE = 2;/*** Camera state: Waiting for the exposure state to be something other than precapture.*/private static final int STATE_WAITING_NON_PRECAPTURE = 3;/*** Camera state: Picture was taken.*/private static final int STATE_PICTURE_TAKEN = 4;/*** Max preview width that is guaranteed by Camera2 API*/private static final int MAX_PREVIEW_WIDTH = 1920;/*** Max preview height that is guaranteed by Camera2 API*/private static final int MAX_PREVIEW_HEIGHT = 1080;/*** {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a* {@link TextureView}.*/private final TextureView.SurfaceTextureListener mSurfaceTextureListener= new TextureView.SurfaceTextureListener() {@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {openCamera(width, height);}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {configureTransform(width, height);}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {return true;}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture texture) {}};/*** ID of the current {@link CameraDevice}.*/private String mCameraId;/*** An {@link AutoFitTextureView} for camera preview.*/private AutoFitTextureView mTextureView;/*** A {@link CameraCaptureSession } for camera preview.*/private CameraCaptureSession mCaptureSession;/*** A reference to the opened {@link CameraDevice}.*/private CameraDevice mCameraDevice;/*** The {@link android.util.Size} of camera preview.*/private Size mPreviewSize;/*** {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.*/private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {@Overridepublic void onOpened(@NonNull CameraDevice cameraDevice) {// This method is called when the camera is opened.  We start camera preview here.mCameraOpenCloseLock.release();mCameraDevice = cameraDevice;createCameraPreviewSession();}@Overridepublic void onDisconnected(@NonNull CameraDevice cameraDevice) {mCameraOpenCloseLock.release();cameraDevice.close();mCameraDevice = null;}@Overridepublic void onError(@NonNull CameraDevice cameraDevice, int error) {mCameraOpenCloseLock.release();cameraDevice.close();mCameraDevice = null;Activity activity = getActivity();if (null != activity) {activity.finish();}}};/*** An additional thread for running tasks that shouldn't block the UI.*/private HandlerThread mBackgroundThread;/*** A {@link Handler} for running tasks in the background.*/private Handler mBackgroundHandler;/*** An {@link ImageReader} that handles still image capture.*/private ImageReader mImageReader;/*** This is the output file for our picture.*/private File mFile;/*** This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a* still image is ready to be saved.*/private final ImageReader.OnImageAvailableListener mOnImageAvailableListener= new ImageReader.OnImageAvailableListener() {@Overridepublic void onImageAvailable(ImageReader reader) {mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));}};/*** {@link CaptureRequest.Builder} for the camera preview*/private CaptureRequest.Builder mPreviewRequestBuilder;/*** {@link CaptureRequest} generated by {@link #mPreviewRequestBuilder}*/private CaptureRequest mPreviewRequest;/*** The current state of camera state for taking pictures.** @see #mCaptureCallback*/private int mState = STATE_PREVIEW;/*** A {@link Semaphore} to prevent the app from exiting before closing the camera.*/private Semaphore mCameraOpenCloseLock = new Semaphore(1);/*** Whether the current camera device supports Flash or not.*/private boolean mFlashSupported;/*** Orientation of the camera sensor*/private int mSensorOrientation;/*** A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture.*/private CameraCaptureSession.CaptureCallback mCaptureCallback= new CameraCaptureSession.CaptureCallback() {private void process(CaptureResult result) {switch (mState) {case STATE_PREVIEW: {// We have nothing to do when the camera preview is working normally.break;}case STATE_WAITING_LOCK: {Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);if (afState == null) {captureStillPicture();} else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {// CONTROL_AE_STATE can be null on some devicesInteger aeState = result.get(CaptureResult.CONTROL_AE_STATE);if (aeState == null ||aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {mState = STATE_PICTURE_TAKEN;captureStillPicture();} else {runPrecaptureSequence();}}break;}case STATE_WAITING_PRECAPTURE: {// CONTROL_AE_STATE can be null on some devicesInteger aeState = result.get(CaptureResult.CONTROL_AE_STATE);if (aeState == null ||aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {mState = STATE_WAITING_NON_PRECAPTURE;}break;}case STATE_WAITING_NON_PRECAPTURE: {// CONTROL_AE_STATE can be null on some devicesInteger aeState = result.get(CaptureResult.CONTROL_AE_STATE);if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {mState = STATE_PICTURE_TAKEN;captureStillPicture();}break;}}}@Overridepublic void onCaptureProgressed(@NonNull CameraCaptureSession session,@NonNull CaptureRequest request,@NonNull CaptureResult partialResult) {process(partialResult);}@Overridepublic void onCaptureCompleted(@NonNull CameraCaptureSession session,@NonNull CaptureRequest request,@NonNull TotalCaptureResult result) {process(result);}};/*** Shows a {@link Toast} on the UI thread.** @param text The message to show*/private void showToast(final String text) {final Activity activity = getActivity();if (activity != null) {activity.runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();}});}}/*** Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that* is at least as large as the respective texture view size, and that is at most as large as the* respective max size, and whose aspect ratio matches with the specified value. If such size* doesn't exist, choose the largest one that is at most as large as the respective max size,* and whose aspect ratio matches with the specified value.** @param choices           The list of sizes that the camera supports for the intended output*                          class* @param textureViewWidth  The width of the texture view relative to sensor coordinate* @param textureViewHeight The height of the texture view relative to sensor coordinate* @param maxWidth          The maximum width that can be chosen* @param maxHeight         The maximum height that can be chosen* @param aspectRatio       The aspect ratio* @return The optimal {@code Size}, or an arbitrary one if none were big enough*/private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {// Collect the supported resolutions that are at least as big as the preview SurfaceList<Size> bigEnough = new ArrayList<>();// Collect the supported resolutions that are smaller than the preview SurfaceList<Size> notBigEnough = new ArrayList<>();int w = aspectRatio.getWidth();int h = aspectRatio.getHeight();for (Size option : choices) {if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&option.getHeight() == option.getWidth() * h / w) {if (option.getWidth() >= textureViewWidth &&option.getHeight() >= textureViewHeight) {bigEnough.add(option);} else {notBigEnough.add(option);}}}// Pick the smallest of those big enough. If there is no one big enough, pick the// largest of those not big enough.if (bigEnough.size() > 0) {return Collections.min(bigEnough, new CompareSizesByArea());} else if (notBigEnough.size() > 0) {return Collections.max(notBigEnough, new CompareSizesByArea());} else {Log.e(TAG, "Couldn't find any suitable preview size");return choices[0];}}public static Camera2BasicFragment newInstance() {return new Camera2BasicFragment();}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_camera2_basic, container, false);}@Overridepublic void onViewCreated(final View view, Bundle savedInstanceState) {view.findViewById(R.id.picture).setOnClickListener(this);view.findViewById(R.id.info).setOnClickListener(this);mTextureView = (AutoFitTextureView) view.findViewById(R.id.texture);}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);mFile = new File(getActivity().getExternalFilesDir(null), "pic.jpg");}@Overridepublic void onResume() {super.onResume();startBackgroundThread();// When the screen is turned off and turned back on, the SurfaceTexture is already// available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open// a camera and start preview from here (otherwise, we wait until the surface is ready in// the SurfaceTextureListener).if (mTextureView.isAvailable()) {openCamera(mTextureView.getWidth(), mTextureView.getHeight());} else {mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);}}@Overridepublic void onPause() {closeCamera();stopBackgroundThread();super.onPause();}private void requestCameraPermission() {if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG);} else {requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);}}@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {if (requestCode == REQUEST_CAMERA_PERMISSION) {if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {ErrorDialog.newInstance(getString(R.string.request_permission)).show(getChildFragmentManager(), FRAGMENT_DIALOG);}} else {super.onRequestPermissionsResult(requestCode, permissions, grantResults);}}/*** Sets up member variables related to camera.** @param width  The width of available size for camera preview* @param height The height of available size for camera preview*/@SuppressWarnings("SuspiciousNameCombination")private void setUpCameraOutputs(int width, int height) {Activity activity = getActivity();CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);try {for (String cameraId : manager.getCameraIdList()) {CameraCharacteristics characteristics= manager.getCameraCharacteristics(cameraId);// We don't use a front facing camera in this sample.Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {continue;}StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);if (map == null) {continue;}// For still image captures, we use the largest available size.Size largest = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),new CompareSizesByArea());mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),ImageFormat.JPEG, /*maxImages*/2);mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);// Find out if we need to swap dimension to get the preview size relative to sensor// coordinate.int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();//noinspection ConstantConditionsmSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);boolean swappedDimensions = false;switch (displayRotation) {case Surface.ROTATION_0:case Surface.ROTATION_180:if (mSensorOrientation == 90 || mSensorOrientation == 270) {swappedDimensions = true;}break;case Surface.ROTATION_90:case Surface.ROTATION_270:if (mSensorOrientation == 0 || mSensorOrientation == 180) {swappedDimensions = true;}break;default:Log.e(TAG, "Display rotation is invalid: " + displayRotation);}Point displaySize = new Point();activity.getWindowManager().getDefaultDisplay().getSize(displaySize);int rotatedPreviewWidth = width;int rotatedPreviewHeight = height;int maxPreviewWidth = displaySize.x;int maxPreviewHeight = displaySize.y;if (swappedDimensions) {rotatedPreviewWidth = height;rotatedPreviewHeight = width;maxPreviewWidth = displaySize.y;maxPreviewHeight = displaySize.x;}if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {maxPreviewWidth = MAX_PREVIEW_WIDTH;}if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {maxPreviewHeight = MAX_PREVIEW_HEIGHT;}// Danger, W.R.! Attempting to use too large a preview size could  exceed the camera// bus' bandwidth limitation, resulting in gorgeous previews but the storage of// garbage capture data.mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,maxPreviewHeight, largest);// We fit the aspect ratio of TextureView to the size of preview we picked.int orientation = getResources().getConfiguration().orientation;if (orientation == Configuration.ORIENTATION_LANDSCAPE) {mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());} else {mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());}// Check if the flash is supported.Boolean available = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);mFlashSupported = available == null ? false : available;mCameraId = cameraId;return;}} catch (CameraAccessException e) {e.printStackTrace();} catch (NullPointerException e) {// Currently an NPE is thrown when the Camera2API is used but not supported on the// device this code runs.ErrorDialog.newInstance(getString(R.string.camera_error)).show(getChildFragmentManager(), FRAGMENT_DIALOG);}}/*** Opens the camera specified by {@link Camera2BasicFragment#mCameraId}.*/private void openCamera(int width, int height) {if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)!= PackageManager.PERMISSION_GRANTED) {requestCameraPermission();return;}setUpCameraOutputs(width, height);configureTransform(width, height);Activity activity = getActivity();CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);try {if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {throw new RuntimeException("Time out waiting to lock camera opening.");}manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();} catch (InterruptedException e) {throw new RuntimeException("Interrupted while trying to lock camera opening.", e);}}/*** Closes the current {@link CameraDevice}.*/private void closeCamera() {try {mCameraOpenCloseLock.acquire();if (null != mCaptureSession) {mCaptureSession.close();mCaptureSession = null;}if (null != mCameraDevice) {mCameraDevice.close();mCameraDevice = null;}if (null != mImageReader) {mImageReader.close();mImageReader = null;}} catch (InterruptedException e) {throw new RuntimeException("Interrupted while trying to lock camera closing.", e);} finally {mCameraOpenCloseLock.release();}}/*** Starts a background thread and its {@link Handler}.*/private void startBackgroundThread() {mBackgroundThread = new HandlerThread("CameraBackground");mBackgroundThread.start();mBackgroundHandler = new Handler(mBackgroundThread.getLooper());}/*** Stops the background thread and its {@link Handler}.*/private void stopBackgroundThread() {mBackgroundThread.quitSafely();try {mBackgroundThread.join();mBackgroundThread = null;mBackgroundHandler = null;} catch (InterruptedException e) {e.printStackTrace();}}/*** Creates a new {@link CameraCaptureSession} for camera preview.*/private void createCameraPreviewSession() {try {SurfaceTexture texture = mTextureView.getSurfaceTexture();assert texture != null;// We configure the size of default buffer to be the size of camera preview we want.texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());// This is the output Surface we need to start preview.Surface surface = new Surface(texture);// We set up a CaptureRequest.Builder with the output Surface.mPreviewRequestBuilder= mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);mPreviewRequestBuilder.addTarget(surface);// Here, we create a CameraCaptureSession for camera preview.mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {// The camera is already closedif (null == mCameraDevice) {return;}// When the session is ready, we start displaying the preview.mCaptureSession = cameraCaptureSession;try {// Auto focus should be continuous for camera preview.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);// Flash is automatically enabled when necessary.setAutoFlash(mPreviewRequestBuilder);// Finally, we start displaying the camera preview.mPreviewRequest = mPreviewRequestBuilder.build();mCaptureSession.setRepeatingRequest(mPreviewRequest,mCaptureCallback, mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {showToast("Failed");}}, null);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.* This method should be called after the camera preview size is determined in* setUpCameraOutputs and also the size of `mTextureView` is fixed.** @param viewWidth  The width of `mTextureView`* @param viewHeight The height of `mTextureView`*/private void configureTransform(int viewWidth, int viewHeight) {Activity activity = getActivity();if (null == mTextureView || null == mPreviewSize || null == activity) {return;}int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();Matrix matrix = new Matrix();RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());float centerX = viewRect.centerX();float centerY = viewRect.centerY();if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);float scale = Math.max((float) viewHeight / mPreviewSize.getHeight(),(float) viewWidth / mPreviewSize.getWidth());matrix.postScale(scale, scale, centerX, centerY);matrix.postRotate(90 * (rotation - 2), centerX, centerY);} else if (Surface.ROTATION_180 == rotation) {matrix.postRotate(180, centerX, centerY);}mTextureView.setTransform(matrix);}/*** Initiate a still image capture.*/private void takePicture() {lockFocus();}/*** Lock the focus as the first step for a still image capture.*/private void lockFocus() {try {// This is how to tell the camera to lock focus.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CameraMetadata.CONTROL_AF_TRIGGER_START);// Tell #mCaptureCallback to wait for the lock.mState = STATE_WAITING_LOCK;mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Run the precapture sequence for capturing a still image. This method should be called when* we get a response in {@link #mCaptureCallback} from {@link #lockFocus()}.*/private void runPrecaptureSequence() {try {// This is how to tell the camera to trigger.mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);// Tell #mCaptureCallback to wait for the precapture sequence to be set.mState = STATE_WAITING_PRECAPTURE;mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Capture a still picture. This method should be called when we get a response in* {@link #mCaptureCallback} from both {@link #lockFocus()}.*/private void captureStillPicture() {try {final Activity activity = getActivity();if (null == activity || null == mCameraDevice) {return;}// This is the CaptureRequest.Builder that we use to take a picture.final CaptureRequest.Builder captureBuilder =mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);captureBuilder.addTarget(mImageReader.getSurface());// Use the same AE and AF modes as the preview.captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);setAutoFlash(captureBuilder);// Orientationint rotation = activity.getWindowManager().getDefaultDisplay().getRotation();captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));CameraCaptureSession.CaptureCallback CaptureCallback= new CameraCaptureSession.CaptureCallback() {@Overridepublic void onCaptureCompleted(@NonNull CameraCaptureSession session,@NonNull CaptureRequest request,@NonNull TotalCaptureResult result) {showToast("Saved: " + mFile);Log.d(TAG, mFile.toString());unlockFocus();}};mCaptureSession.stopRepeating();mCaptureSession.abortCaptures();mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);} catch (CameraAccessException e) {e.printStackTrace();}}/*** Retrieves the JPEG orientation from the specified screen rotation.** @param rotation The screen rotation.* @return The JPEG orientation (one of 0, 90, 270, and 360)*/private int getOrientation(int rotation) {// Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X)// We have to take that into account and rotate JPEG properly.// For devices with orientation of 90, we simply return our mapping from ORIENTATIONS.// For devices with orientation of 270, we need to rotate the JPEG 180 degrees.return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360;}/*** Unlock the focus. This method should be called when still image capture sequence is* finished.*/private void unlockFocus() {try {// Reset the auto-focus triggermPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);setAutoFlash(mPreviewRequestBuilder);mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,mBackgroundHandler);// After this, the camera will go back to the normal state of preview.mState = STATE_PREVIEW;mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,mBackgroundHandler);} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.picture: {takePicture();break;}case R.id.info: {Activity activity = getActivity();if (null != activity) {new AlertDialog.Builder(activity).setMessage(R.string.intro_message).setPositiveButton(android.R.string.ok, null).show();}break;}}}private void setAutoFlash(CaptureRequest.Builder requestBuilder) {if (mFlashSupported) {requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);}}/*** Saves a JPEG {@link Image} into the specified {@link File}.*/private static class ImageSaver implements Runnable {/*** The JPEG image*/private final Image mImage;/*** The file we save the image into.*/private final File mFile;ImageSaver(Image image, File file) {mImage = image;mFile = file;}@Overridepublic void run() {ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();byte[] bytes = new byte[buffer.remaining()];buffer.get(bytes);FileOutputStream output = null;try {output = new FileOutputStream(mFile);output.write(bytes);} catch (IOException e) {e.printStackTrace();} finally {mImage.close();if (null != output) {try {output.close();} catch (IOException e) {e.printStackTrace();}}}}}/*** Compares two {@code Size}s based on their areas.*/static class CompareSizesByArea implements Comparator<Size> {@Overridepublic int compare(Size lhs, Size rhs) {// We cast here to ensure the multiplications won't overflowreturn Long.signum((long) lhs.getWidth() * lhs.getHeight() -(long) rhs.getWidth() * rhs.getHeight());}}/*** Shows an error message dialog.*/public static class ErrorDialog extends DialogFragment {private static final String ARG_MESSAGE = "message";public static ErrorDialog newInstance(String message) {ErrorDialog dialog = new ErrorDialog();Bundle args = new Bundle();args.putString(ARG_MESSAGE, message);dialog.setArguments(args);return dialog;}@NonNull@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) {final Activity activity = getActivity();return new AlertDialog.Builder(activity).setMessage(getArguments().getString(ARG_MESSAGE)).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialogInterface, int i) {activity.finish();}}).create();}}/*** Shows OK/Cancel confirmation dialog about camera permission.*/public static class ConfirmationDialog extends DialogFragment {@NonNull@Overridepublic Dialog onCreateDialog(Bundle savedInstanceState) {final Fragment parent = getParentFragment();return new AlertDialog.Builder(getActivity()).setMessage(R.string.request_permission).setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {parent.requestPermissions(new String[]{Manifest.permission.CAMERA},REQUEST_CAMERA_PERMISSION);}}).setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Activity activity = parent.getActivity();if (activity != null) {activity.finish();}}}).create();}}}

这篇关于CameraManager——Camera的过时替代方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133303

相关文章

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

使用JS/Jquery获得父窗口的几个方法(笔记)

<pre name="code" class="javascript">取父窗口的元素方法:$(selector, window.parent.document);那么你取父窗口的父窗口的元素就可以用:$(selector, window.parent.parent.document);如题: $(selector, window.top.document);//获得顶级窗口里面的元素 $(

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法

消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法   消除安卓SDK更新时的“https://dl-ssl.google.com refused”异常的方法 [转载]原地址:http://blog.csdn.net/x605940745/article/details/17911115 消除SDK更新时的“