Reputation: 698
while I run my app in real phones it's ok but in android studio emulator it cause this error :
Photo capture failed: Camera is closed
this is my code strange thing is that when I switch front camera it works good but when I use back it doesn't work.
I used CameraX with jetpack compose library and tested with api 31 and 33
I tried it without dissmis() in onClick but still doesn't work I want to know is my code wrong or android studio's emulators has problem.
@Composable
fun CameraScreen(changeImage: (Uri) -> Unit,onDismiss: () -> Unit) {
val context = LocalContext.current
val lifecycleOwner = androidx.lifecycle.compose.LocalLifecycleOwner.current
var preview by remember { mutableStateOf<Preview?>(null) }
var imageCapture: ImageCapture? = null
var lensFacing by remember { mutableStateOf(CameraSelector.LENS_FACING_BACK) }
var zoomRatio by remember { mutableStateOf(1.0f) }
var camera by remember { mutableStateOf<Camera?>(null) }
var previewView by remember { mutableStateOf<PreviewView>(PreviewView(context)) }
LaunchedEffect(lensFacing) {
val cameraProvider = context.getCameraProvider()
try {
cameraProvider.unbindAll()
preview = Preview.Builder().build().also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
imageCapture = ImageCapture.Builder().build()
val cameraSelector = CameraSelector.Builder()
.requireLensFacing(lensFacing)
.build()
camera = cameraProvider.bindToLifecycle(
lifecycleOwner, cameraSelector, preview, imageCapture
)
} catch (exc: Exception) {
Log.e("Camera", "Use case binding failed", exc)
}
}
Box(modifier = Modifier.fillMaxSize()) {
AndroidView(
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
detectTransformGestures { _, _, zoom, _ ->
// Adjust zoom ratio based on the pinch gesture
val newZoom = max(
1f,
min(zoomRatio * zoom, 5f)
) // Assuming max zoom is 5x, adjust as needed
zoomRatio = newZoom
camera?.cameraControl?.setZoomRatio(newZoom)
}
},
factory = { ctx ->
PreviewView(ctx).also {
previewView = it
}
}
)
Row(
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceEvenly
) {
// Button to switch camera
Button(onClick = {
lensFacing = if (lensFacing == CameraSelector.LENS_FACING_BACK)
CameraSelector.LENS_FACING_FRONT
else
CameraSelector.LENS_FACING_BACK
}) {
Text(text = "Switch Camera")
}
// Button to capture image
Button(onClick = {
val fileName = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(System.currentTimeMillis()) + ".jpg"
val photoFile = File(context.filesDir, fileName)
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
imageCapture?.takePicture(
outputOptions,
ContextCompat.getMainExecutor(context),
object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Log.e("Camera", "Photo capture failed: ${exc.message}", exc)
}
override fun onImageSaved(output: ImageCapture.OutputFileResults) {
val savedUri = Uri.fromFile(photoFile)
changeImage(savedUri)
Log.d("Camera", "Photo capture succeeded: $savedUri")
// Handle the saved image URI here
onDismiss()
}
}
)
}) {
Text("Capture")
}
}
}
}`
Upvotes: 1
Views: 95