Java tutorial
import android.hardware.camera2.TotalCaptureResult; 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.params.StreamConfigurationMap; import android.support.v7.app.AppCompatActivity; import android.graphics.SurfaceTexture; import android.content.Context; import android.graphics.ImageFormat; import android.media.Image; import android.media.ImageReader; import android.os.Environment; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.util.Size; import android.view.Surface; import android.view.TextureView; import android.view.View; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private CameraDevice mCameraDevice = null; private CaptureRequest.Builder mCaptureRequestBuilder = null; private CameraCaptureSession mCameraCaptureSession = null; private TextureView mTextureView = null; private Size mPreviewSize = null; static class CompareSizesByArea implements Comparator<Size> { @Override public int compare(Size lhs, Size rhs) { return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight()); } } private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(CameraDevice camera) { mCameraDevice = camera; SurfaceTexture texture = mTextureView.getSurfaceTexture(); if (texture == null) { return; } texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight()); Surface surface = new Surface(texture); try { mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); } catch (CameraAccessException e) { e.printStackTrace(); } mCaptureRequestBuilder.addTarget(surface); try { mCameraDevice.createCaptureSession(Arrays.asList(surface), mPreviewStateCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onError(CameraDevice camera, int error) { } @Override public void onDisconnected(CameraDevice camera) { } }; private TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { return false; } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { openCamera(); } }; private CameraCaptureSession.StateCallback mPreviewStateCallback = new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { startPreview(session); } @Override public void onConfigureFailed(CameraCaptureSession session) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextureView = (TextureView) findViewById(R.id.textureView); mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); } @Override protected void onPause() { super.onPause(); if (mCameraDevice != null) { mCameraDevice.close(); mCameraDevice = null; } } @Override public void onResume() { super.onResume(); if (mTextureView.isAvailable()) { openCamera(); } else { mTextureView.setSurfaceTextureListener(mSurfaceTextureListener); } } private void openCamera() { CameraManager manager = (CameraManager) getSystemService(CAMERA_SERVICE); try { String cameraId = manager.getCameraIdList()[0]; CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId); StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0]; manager.openCamera(cameraId, mStateCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } } private void startPreview(CameraCaptureSession session) { mCameraCaptureSession = session; mCaptureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); HandlerThread backgroundThread = new HandlerThread("CameraPreview"); backgroundThread.start(); Handler backgroundHandler = new Handler(backgroundThread.getLooper()); try { mCameraCaptureSession.setRepeatingRequest(mCaptureRequestBuilder.build(), null, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } private File getPictureFile() { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(System.currentTimeMillis()); String fileName = "PHOTO_" + timeStamp + ".jpg"; return new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), fileName); } protected void takePicture(View view) { if (null == mCameraDevice) { return; } CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); try { CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraDevice.getId()); StreamConfigurationMap configurationMap = characteristics .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); if (configurationMap == null) return; Size largest = Collections.max(Arrays.asList(configurationMap.getOutputSizes(ImageFormat.JPEG)), new CompareSizesByArea()); ImageReader reader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(), ImageFormat.JPEG, 1); List<Surface> outputSurfaces = new ArrayList<Surface>(2); outputSurfaces.add(reader.getSurface()); outputSurfaces.add(new Surface(mTextureView.getSurfaceTexture())); final CaptureRequest.Builder captureBuilder = mCameraDevice .createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(reader.getSurface()); captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { Image image = null; try { image = reader.acquireLatestImage(); ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.capacity()]; buffer.get(bytes); OutputStream output = new FileOutputStream(getPictureFile()); output.write(bytes); output.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (image != null) { image.close(); } } } }; HandlerThread thread = new HandlerThread("CameraPicture"); thread.start(); final Handler backgroudHandler = new Handler(thread.getLooper()); reader.setOnImageAvailableListener(readerListener, backgroudHandler); final CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { super.onCaptureCompleted(session, request, result); Toast.makeText(MainActivity.this, "Picture Saved", Toast.LENGTH_SHORT).show(); startPreview(session); } }; mCameraDevice.createCaptureSession(outputSurfaces, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { try { session.capture(captureBuilder.build(), captureCallback, backgroudHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(CameraCaptureSession session) { } }, backgroudHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } }