diff --git a/app/src/main/java/com/nekdenis/camera/MainActivity.kt b/app/src/main/java/com/nekdenis/camera/MainActivity.kt index 97e3827..9a38adb 100644 --- a/app/src/main/java/com/nekdenis/camera/MainActivity.kt +++ b/app/src/main/java/com/nekdenis/camera/MainActivity.kt @@ -1,19 +1,31 @@ package com.nekdenis.camera import android.Manifest +import android.content.Context import android.content.pm.PackageManager import android.os.Bundle -import android.widget.Toast +import android.view.ViewGroup import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent +import androidx.camera.core.CameraSelector +import androidx.camera.lifecycle.ProcessCameraProvider +import androidx.camera.view.PreviewView import androidx.compose.material.MaterialTheme import androidx.compose.material.Surface import androidx.compose.material.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.viewinterop.AndroidView import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import com.nekdenis.camera.ui.theme.CameraComposeWorkshopTheme +import android.widget.Toast +import androidx.activity.compose.setContent +import androidx.lifecycle.LifecycleOwner +import com.google.common.util.concurrent.ListenableFuture class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -59,10 +71,41 @@ class MainActivity : ComponentActivity() { // A surface container using the 'background' color from the theme Surface(color = MaterialTheme.colors.background) { Greeting("Android") + CameraPreview() } } } } + + @Composable + fun CameraPreview( + modifier: Modifier = Modifier, + cameraSelector: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA, + scaleType: PreviewView.ScaleType = PreviewView.ScaleType.FILL_CENTER, + ) { + val lifecycleOwner = LocalLifecycleOwner.current + val context = LocalContext.current + val previewView = remember { PreviewView(context) } + val cameraProviderFuture = remember { + ProcessCameraProvider.getInstance(context) + .configureCamera(previewView, lifecycleOwner, cameraSelector, context) + } + AndroidView( + modifier = modifier, + factory = { + previewView.apply { + this.scaleType = scaleType + layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + // Preview is incorrectly scaled in Compose on some devices without this + implementationMode = PreviewView.ImplementationMode.COMPATIBLE + } + + previewView + }) + } } @@ -77,4 +120,31 @@ fun DefaultPreview() { CameraComposeWorkshopTheme { Greeting("Android") } +} + +private fun ListenableFuture.configureCamera( + previewView: PreviewView, + lifecycleOwner: LifecycleOwner, + cameraSelector: CameraSelector, + context: Context +): ListenableFuture { + addListener({ + val preview = androidx.camera.core.Preview.Builder() + .build() + .apply { + setSurfaceProvider(previewView.surfaceProvider) + } + + try { + get().apply { + unbindAll() + bindToLifecycle( + lifecycleOwner, cameraSelector, preview + ) + } + } catch (exc: Exception) { + TODO("process errors") + } + }, ContextCompat.getMainExecutor(context)) + return this } \ No newline at end of file