写真を撮るアプリを作りたくて、まずはレンズにフォーカスしているものを映し出すようにした。
※雑にメモしています。
レンズにフォーカスしているものを描画するための下準備
TextureViewは簡単にいえば描画するためのもの。カメラアプリを作るだけではなく録画機能をつくるときもこれを使うみたい
TakePhotoActivity.java
~省略~
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
mCamera.open();
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {}
});
mCamera = new Camera(mTextureView);
カメラを使えるようにしたり、TextureViewに生成する代物をつくったりするクラス
Camera.java
class Camera {
private CameraDevice mCameraDevice;
private TextureView textureView;
private android.util.Size mCameraSize;
private CaptureRequest.Builder mPreviewBuilder;
private CameraCaptureSession mPreviewSession;
private CameraDevice.StateCallback mCameraDeviceCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice cameraDevice) {
mCameraDevice = cameraDevice;
createCaptureSession();
}
@Override
public void onDisconnected(CameraDevice cameraDevice) {
cameraDevice.close();
mCameraDevice = null;
}
@Override
public void onError(CameraDevice cameraDevice, int i) {
cameraDevice.close();
mCameraDevice = null;
}
};
CameraCaptureSession.StateCallback mCameraCaptureSession = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
mPreviewSession = cameraCaptureSession;
updatePreview();
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
}
};
public Camera(TextureView textureView) {
this.textureView = textureView;
}
public void open() {
try {
CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
for (String cameraId : manager.getCameraIdList()) {
CameraCharacteristics cameraCharacteristics = manager.getCameraCharacteristics(cameraId);
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_BACK) {
StreamConfigurationMap map = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
mCameraSize = map.getOutputSizes(SurfaceTexture.class)[0];
if (ActivityCompat.checkSelfPermission(TakePhotoActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(TakePhotoActivity.this, new String[]{
Manifest.permission.CAMERA
}, mRequestCode);
return;
}
manager.openCamera(cameraId, mCameraDeviceCallback, null);
return;
}
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void createCaptureSession() {
if (!mTextureView.isAvailable()) {
return;
}
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mCameraSize.getWidth(), mCameraSize.getHeight());
Surface surface = new Surface(surfaceTexture);
try {
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
} catch (CameraAccessException e) {
e.printStackTrace();
}
mPreviewBuilder.addTarget(surface);
try {
mCameraDevice.createCaptureSession(Collections.singletonList(surface), mCameraCaptureSession, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
private void updatePreview() {
mPreviewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
HandlerThread thread = new HandlerThread("Camera Preview");
thread.start();
android.os.Handler backgroundHandler = new android.os.Handler(thread.getLooper());
try {
mPreviewSession.setRepeatingRequest(mPreviewBuilder.build(), null, backgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}