1 /* 2 * Copyright 2017 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.SurfaceHolder 24 import android.view.SurfaceView 25 import com.example.android.basicpermissions.util.calculatePreviewOrientation 26 27 import java.io.IOException 28 29 /** 30 * Camera preview that displays a [Camera]. 31 * 32 * 33 * Handles basic lifecycle methods to display and stop the preview. 34 * 35 * 36 * Implementation is based directly on the documentation at 37 * http://developer.android.com/guide/topics/media/camera.html 38 */ 39 class CameraPreview @JvmOverloads constructor( 40 context: Context, 41 attrs: AttributeSet? = null, 42 defStyleAttr: Int = 0, 43 private val camera: Camera? = null, 44 private val cameraInfo: Camera.CameraInfo? = null, 45 private val displayOrientation: Int = 0 46 ) : SurfaceView(context, attrs, defStyleAttr), SurfaceHolder.Callback { 47 48 init { 49 50 // Do not initialise if no camera has been set 51 if (camera != null && cameraInfo != null) { 52 // Install a SurfaceHolder.Callback so we get notified when the 53 // underlying surface is created and destroyed. 54 holder.addCallback(this@CameraPreview) 55 } 56 } 57 58 override fun surfaceCreated(holder: SurfaceHolder) { 59 // The Surface has been created, now tell the camera where to draw the preview. 60 try { 61 camera?.run { 62 setPreviewDisplay(holder) 63 startPreview() 64 } 65 Log.d(TAG, "Camera preview started.") 66 } catch (e: IOException) { 67 Log.d(TAG, "Error setting camera preview: ${e.message}") 68 } 69 70 } 71 72 override fun surfaceDestroyed(holder: SurfaceHolder) { 73 // empty. Take care of releasing the Camera preview in your activity. 74 } 75 76 override fun surfaceChanged(holder: SurfaceHolder, format: Int, w: Int, h: Int) { 77 // If your preview can change or rotate, take care of those events here. 78 // Make sure to stop the preview before resizing or reformatting it. 79 80 if (holder.surface == null) { 81 // preview surface does not exist 82 Log.d(TAG, "Preview surface does not exist") 83 return 84 } 85 Log.d(TAG, "Preview stopped.") 86 camera?.run { 87 // stop preview before making changes 88 stopPreview() 89 cameraInfo?.let { 90 setDisplayOrientation(it.calculatePreviewOrientation(displayOrientation)) 91 } 92 setPreviewDisplay(holder) 93 startPreview() 94 Log.d(TAG, "Camera preview started.") 95 } 96 } 97 98 companion object { 99 private val TAG = "CameraPreview" 100 } 101 } 102