public class Camera2Helper implements SurfaceHolder.Callback {
private int mCameraId;
private final SurfaceView mSurfaceView;
private ImageReader mImageReader;
private int mWidth = 0;
private int mHeight = 0;
private Handler tCameraHandler;
private CameraCaptureSession mCameraCaptureSession;
private HandlerThread tHandlerThread;
private volatile CameraDevice mCameraDevice;
public void setWidth(int width) {
this.mWidth = width;
}
public void setHeight(int height) {
this.mHeight = height;
}
public Camera2Helper(int cameraId, SurfaceView surfaceView) {
mCameraId = cameraId;
mSurfaceView = surfaceView;
//保持屏幕长亮
mSurfaceView.setKeepScreenOn(true);
mSurfaceView.getHolder().addCallback(this);
}
public void switchCamera() {
// 判断是否为空原因,当用户快速点击切换会导致摄像头资源问题,从而系统崩溃
// 处理思路,切换时只要知道mCameraDevice已经被初始化完成即可,那如何判断呢
// 每次切换会释放mCameraDevice,每次onOpened完成之后会赋值mCameraDevice
if(mCameraDevice==null){
return;
}
closeCamera();
if (CameraCharacteristics.LENS_FACING_BACK == mCameraId) {
mCameraId = CameraCharacteristics.LENS_FACING_FRONT;
} else {
mCameraId = CameraCharacteristics.LENS_FACING_BACK;
}
stopThread();
mSurfaceView.getHolder().addCallback(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
initCamera();
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//home键之后重新初始化
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
initCamera();
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
//home键之后surfaceDestroyed这时候不需要摄像头资源则关闭释放
closeCamera();
stopThread();
mSurfaceView.getHolder().addCallback(this);
}
public void closeCamera() {
if (null != mCameraCaptureSession) {
mCameraCaptureSession.close();
mCameraCaptureSession = null;
}
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
if (mSurfaceView.getHolder() != null) {
mSurfaceView.getHolder().removeCallback(this);
}
}
public void stopThread() {
tHandlerThread.quitSafely();
try {
tHandlerThread.join();
tHandlerThread = null;
tCameraHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@SuppressLint("MissingPermission")
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void initCamera() {
tHandlerThread = new HandlerThread("Camera2");
tHandlerThread.start();
tCameraHandler = new Handler(mSurfaceView.getContext().getMainLooper());
mImageReader = ImageReader.newInstance(mWidth, mHeight,
ImageFormat.YUV_420_888, 1);
mImageReader.setOnImageAvailableListener(new ImageReader
.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
}
}, tCameraHandler);
CameraManager mCameraManager = null;
mCameraManager = (CameraManager) mSurfaceView.getContext().getSystemService(Context.CAMERA_SERVICE);
try {
mCameraManager.openCamera(String.valueOf(mCameraId), mStateCallback, tCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 摄像头创建监听
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) { // 打开摄像头
mCameraDevice = camera;
// 开启预览
createPreview();
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) { // 关闭摄像头
if (null != mCameraDevice) {
mCameraDevice.close();
mCameraDevice = null;
}
}
@Override
public void onError(@NonNull CameraDevice camera, int error) { // 发生错误
}
};
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void createPreview() {
try {
// 创建预览需要的CaptureRequest.Builder
final CaptureRequest.Builder previewRequestBuilder = mCameraDevice
.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将SurfaceView的surface作为CaptureRequest.Builder的目标
previewRequestBuilder.addTarget(mSurfaceView.getHolder().getSurface());
// previewRequestBuilder.addTarget(mImageReader.getSurface());
// 创建CameraCaptureSession,该对象负责管理处理预览请求
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceView.getHolder().getSurface()),
new CCSStateCallback(previewRequestBuilder),
tCameraHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
class CCSStateCallback extends CameraCaptureSession.StateCallback {
private CaptureRequest.Builder previewRequestBuilder;
CCSStateCallback(CaptureRequest.Builder previewRequestBuilder) {
this.previewRequestBuilder = previewRequestBuilder;
}
@Override
public void onConfigured(CameraCaptureSession session) {
if (null == mCameraDevice) {
return;
}
// 当摄像头已经准备好时,开始显示预览
mCameraCaptureSession = session;
try {
// 自动对焦
// previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
// CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 显示预览
CaptureRequest previewRequest = previewRequestBuilder.build();
mCameraCaptureSession.setRepeatingRequest(previewRequest,
null, tCameraHandler);
} catch (CameraAccessException | IllegalStateException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}
}
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕宽度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
final Camera2Helper camera2Helper=new Camera2Helper(CameraCharacteristics.LENS_FACING_BACK,surfaceView);
camera2Helper.setWidth(width);
camera2Helper.setHeight(height);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
camera2Helper.switchCamera();
}
});
参考链接:https://www.jianshu.com/p/d83161e77e90