1 /* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.basicpermissions.camera; 18 19 import android.content.Context; 20 import android.hardware.Camera; 21 import android.util.AttributeSet; 22 import android.util.Log; 23 import android.view.Surface; 24 import android.view.SurfaceHolder; 25 import android.view.SurfaceView; 26 27 import java.io.IOException; 28 29 /** 30 * Camera preview that displays a {@link Camera}. 31 * <p> 32 * Handles basic lifecycle methods to display and stop the preview. 33 * <p> 34 * Implementation is based directly on the documentation at 35 * http://developer.android.com/guide/topics/media/camera.html 36 */ 37 public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 38 39 private static final String TAG = "CameraPreview"; 40 41 private SurfaceHolder mHolder; 42 private Camera mCamera; 43 private Camera.CameraInfo mCameraInfo; 44 private int mDisplayOrientation; 45 46 public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) { 47 this(context, attrs, defStyleAttr, null, null, 0); 48 } 49 50 public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr, 51 Camera camera, Camera.CameraInfo cameraInfo, int displayOrientation) { 52 super(context, attrs, defStyleAttr); 53 54 // Do not initialise if no camera has been set 55 if (camera == null || cameraInfo == null) { 56 return; 57 } 58 mCamera = camera; 59 mCameraInfo = cameraInfo; 60 mDisplayOrientation = displayOrientation; 61 62 // Install a SurfaceHolder.Callback so we get notified when the 63 // underlying surface is created and destroyed. 64 mHolder = getHolder(); 65 mHolder.addCallback(this); 66 } 67 68 /** 69 * Calculate the correct orientation for a {@link Camera} preview that is displayed on screen. 70 * <p> 71 * Implementation is based on the sample code provided in 72 * {@link Camera#setDisplayOrientation(int)}. 73 */ 74 public static int calculatePreviewOrientation(Camera.CameraInfo info, int rotation) { 75 int degrees = 0; 76 77 switch (rotation) { 78 case Surface.ROTATION_0: 79 degrees = 0; 80 break; 81 case Surface.ROTATION_90: 82 degrees = 90; 83 break; 84 case Surface.ROTATION_180: 85 degrees = 180; 86 break; 87 case Surface.ROTATION_270: 88 degrees = 270; 89 break; 90 } 91 92 int result; 93 if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 94 result = (info.orientation + degrees) % 360; 95 result = (360 - result) % 360; // compensate the mirror 96 } else { // back-facing 97 result = (info.orientation - degrees + 360) % 360; 98 } 99 100 return result; 101 } 102 103 public void surfaceCreated(SurfaceHolder holder) { 104 // The Surface has been created, now tell the camera where to draw the preview. 105 try { 106 mCamera.setPreviewDisplay(holder); 107 mCamera.startPreview(); 108 Log.d(TAG, "Camera preview started."); 109 } catch (IOException e) { 110 Log.d(TAG, "Error setting camera preview: " + e.getMessage()); 111 } 112 } 113 114 public void surfaceDestroyed(SurfaceHolder holder) { 115 // empty. Take care of releasing the Camera preview in your activity. 116 } 117 118 public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 119 // If your preview can change or rotate, take care of those events here. 120 // Make sure to stop the preview before resizing or reformatting it. 121 122 if (mHolder.getSurface() == null) { 123 // preview surface does not exist 124 Log.d(TAG, "Preview surface does not exist"); 125 return; 126 } 127 128 // stop preview before making changes 129 try { 130 mCamera.stopPreview(); 131 Log.d(TAG, "Preview stopped."); 132 } catch (Exception e) { 133 // ignore: tried to stop a non-existent preview 134 Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 135 } 136 137 int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation); 138 mCamera.setDisplayOrientation(orientation); 139 140 try { 141 mCamera.setPreviewDisplay(mHolder); 142 mCamera.startPreview(); 143 Log.d(TAG, "Camera preview started."); 144 } catch (Exception e) { 145 Log.d(TAG, "Error starting camera preview: " + e.getMessage()); 146 } 147 } 148 } 149