布局只用到了SurfaceView跟Button。有的手机黑屏,需要给SurfaceViewHolder设置FixedSize。
public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback
private SurfaceView mCameraSurfaceView;
private SurfaceHolder mSurfaceHolder;
//相机相关代码,三个必须的
private CameraManager mCameraManager;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCameraCaptureSession;
//阻止相机关闭前退出app
private Semaphore mCameraOpenCloseLock = new Semaphore(1);
//摄像头id 0:后摄像头 1:前摄像头
private static final String mCameraId = "" + CameraCharacteristics.LENS_FACING_FRONT;
//opencamera方法中需要ImageReader和handler
private ImageReader mImageReader;
private Handler mHandler;
private Size previewsize;
private ImageReader.OnImageAvailableListener mImageAvailableListenter = new ImageReader.OnImageAvailableListener() {
@SuppressLint("NewApi")
@Override
public void onImageAvailable(ImageReader reader) {
mCameraDevice.close();
//这里获取到图片数据
……
}
};
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
///为了使照片竖直显示
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);
}
/**
* 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;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
initView();
initSurfaceView();
}
private void initView() {
mCameraSurfaceView = (SurfaceView) findViewById(R.id.camera_surfaceview);
mFrameIv = (ImageView) findViewById(R.id.frame_imageview);
mTakePhotoBt = (Button) findViewById(R.id.takephoto_bt);
mFocusView = findViewById(R.id.focus_index);
}
private void initSurfaceView() {
mCameraSurfaceView.setBackgroundColor(TRIM_MEMORY_BACKGROUND);
mSurfaceHolder = mCameraSurfaceView.getHolder();
mSurfaceHolder.setKeepScreenOn(true);
mSurfaceHolder.addCallback(this);
}
@Override
protected void onResume() {
mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
//这里可以设置也可以不设置,使用过程中发现有的手机不设置这个时会出现黑屏现象
mSurfaceHolder.setFixedSize(800, 600);
super.onResume();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
//不设置holder的Fixedsize时设置initCamera2(mCameraSurfaceView.getWidth(),mCameraSurfaceView.getHeight());
initCamera2(800, 600);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@SuppressLint("NewApi")
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCameraDevice != null) {
mCameraDevice.close();
}
}
@SuppressLint("NewApi")
private void initCamera2(int width, int height) {
if (checkCameraPermission()) {
try {
String camerId = mCameraManager.getCameraIdList()[0];
CameraCharacteristics characteristics = mCameraManager.getCameraCharacteristics(camerId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
previewsize = map.getOutputSizes(SurfaceTexture.class)[0];
HandlerThread handlerthread = new HandlerThread("Camera2");
handlerthread.start();
mHandler = new Handler(handlerthread.getLooper());
mImageReader = ImageReader.newInstance(width, height, ImageFormat.JPEG, /*maxImages*/2);
mImageReader.setOnImageAvailableListener(mImageAvailableListenter, mHandler);
mCameraManager.openCamera(mCameraId, mCameraDeviceCallBack, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
} else {
finish();
return;
}
}
private boolean checkCameraPermission() {
if (ContextCompat.checkSelfPermission(getApplicationContext(),
Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getApplicationContext(), "没有相机权限", Toast.LENGTH_LONG).show();
return false;
} else {
return true;
}
}
@SuppressLint("NewApi")
private CameraDevice.StateCallback mCameraDeviceCallBack = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice camera) {
try {
//当相机被打开,该方法将被回调,因此再这里进行相机预览设置
mCameraOpenCloseLock.release();
mCameraDevice = camera;
//开启预览
createCameraCaptureSession();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onDisconnected(@NonNull CameraDevice camera) {
mCameraOpenCloseLock.release();
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
}
@Override
public void onError(@NonNull CameraDevice camera, int error) {
}
};
private CaptureRequest.Builder mCaptureRequestBuilder;
@SuppressLint("NewApi")//开启预览
private void createCameraCaptureSession() throws CameraAccessException {
//创建预览需要的CaptureRequest.Builder
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//添加surface为CaptureRequest.Builder的目标
mCaptureRequestBuilder.addTarget(mSurfaceHolder.getSurface());
//创建CameraCaptureSession该对象负责管理处理预览请求和拍照请求
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(),
mImageReader.getSurface()), mSessionPreviewStateCallback, mHandler);
}
@SuppressLint("NewApi")
private CameraCaptureSession.StateCallback mSessionPreviewStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
//摄像头已经准备好,开始显示预览
mCameraCaptureSession = session;
//自动对焦
mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
//打开闪光灯
// mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
//显示预览
CaptureRequest previewRequest = mCaptureRequestBuilder.build();
mCameraCaptureSession.setRepeatingRequest(previewRequest, null, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
Log.e("Camera2", "相机预览失败");
}
};
//
public void takePicture(View view) {
takePic();
}
@SuppressLint("NewApi")
public void takePic() {
if (mCameraDevice == null) return;
// 创建拍照需要的CaptureRequest.Builder
try {
// 将imageReader的surface作为CaptureRequest.Builder的目标
mCaptureRequestBuilder.addTarget(mImageReader.getSurface());
// 自动对焦
mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 自动曝光
mCaptureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 获取手机方向
int rotation = getWindowManager().getDefaultDisplay().getRotation();
// 根据设备方向计算设置照片的方向
mCaptureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
//拍照
CaptureRequest mCaptureRequest = mCaptureRequestBuilder.build();
mCameraCaptureSession.capture(mCaptureRequest, null, mHandler);
} catch