Android easy camera permission
build.gradle
AndroidX camera dependencies, should be added to build.gradle dependencies {} section, like usual libraries
implementation 'androidx.camera:camera-view:1.1.0'
implementation 'androidx.camera:camera-core:1.1.0'
implementation 'androidx.camera:camera-camera2:1.1.0'
implementation 'androidx.camera:camera-lifecycle:1.1.0'
Camera.kt
Simple AndroidX camera preview, uses AndroidView to insert View as Compose element
@Composable
fun CameraPreview(
modifier: Modifier = Modifier,
cameraSelector: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA,
scaleType: PreviewView.ScaleType = PreviewView.ScaleType.FILL_CENTER,
) {
val lifecycleOwner = LocalLifecycleOwner.current
AndroidView(
modifier = modifier,
factory = { context ->
val previewView = PreviewView(context).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
}
val cameraProviderFuture = ProcessCameraProvider.getInstance(context)
cameraProviderFuture.addListener({
val cameraProvider = cameraProviderFuture.get()
// Preview
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(previewView.surfaceProvider)
}
try {
// Must unbind the use-cases before rebinding them.
cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
lifecycleOwner, cameraSelector, preview
)
} catch (exc: Exception) {
exc.printStackTrace()
}
}, ContextCompat.getMainExecutor(context))
previewView
}
)
}
MainActivity.kt
Checking permission on activity start, if not granted asking for it, otherwise starting CameraPreview()
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Content()
}
}
@Composable
private fun Content() {
CameraTestTheme {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background)
) {
var granted by remember {
mutableStateOf(PackageManager.PERMISSION_GRANTED == checkSelfPermission(Manifest.permission.CAMERA))
}
if (granted) {
// CAMERA PERMISSION GRANTED, CAN WORK WITH CAMERA
CameraPreview()
} else {
val launcher =
rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) {
granted = it
}
SideEffect {
launcher.launch(Manifest.permission.CAMERA)
}
}
}
}
}
}