Camera2 で像を描画するようにしてみた

写真を撮るアプリを作りたくて、まずはレンズにフォーカスしているものを映し出すようにした。
※雑にメモしています。

レンズにフォーカスしているものを描画するための下準備
-
_TextureViewは簡単にいえば描画するためのもの。カメラアプリを作るだけではなく録画機能をつくるときもこれを使うみたい_

``` java: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に生成する代物をつくったりするクラス
-
```Java: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();
            }
        }

    }
```