在 Jetpack Compose 中解锁 CameraX 的强大功能
作者 / Google 开发者关系工程师 Jolanda Verhoef
此外,应用可以顺畅地在桌面模式之间切换:
添加库依赖项
[versions]..camerax = "1.5.0-alpha03"accompanist = "0.36.0" # or whatever matches with your Compose version[libraries]..# Contains the basic camera functionality such as SurfaceRequestandroidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" }# Contains the CameraXViewfinder composableandroidx-camera-compose = { module = "androidx.camera:camera-compose", version.ref = "camerax" }# Allows us to bind the camera preview to our UI lifecycleandroidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" }# The specific camera implementation that renders the previewandroidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" }# The helper library to grant the camera permissionaccompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
dependencies {..implementation(libs.androidx.camera.core)implementation(libs.androidx.camera.compose)implementation(libs.androidx.camera.lifecycle)implementation(libs.androidx.camera.camera2)implementation(libs.accompanist.permissions)}
授予相机权限
<manifest xmlns:android="http://schemas.android.com/apk/res/android"><uses-feature android:name="android.hardware.camera" android:required="true" /><uses-permission android:name="android.permission.CAMERA" />..</manifest>
Accompanist 权限库
https://google.github.io/accompanist/permissions/
class MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)enableEdgeToEdge()setContent {MyApplicationTheme {CameraPreviewScreen()}}}}@OptIn(ExperimentalPermissionsApi::class)@Composablefun CameraPreviewScreen(modifier: Modifier = Modifier) {val cameraPermissionState = rememberPermissionState(android.Manifest.permission.CAMERA)if (cameraPermissionState.status.isGranted) {CameraPreviewContent(modifier)} else {Column(modifier = modifier.fillMaxSize().wrapContentSize().widthIn(max = 480.dp),horizontalAlignment = Alignment.CenterHorizontally) {val textToShow = if (cameraPermissionState.status.shouldShowRationale) {// If the user has denied the permission but the rationale can be shown,// then gently explain why the app requires this permission"Whoops! Looks like we need your camera to work our magic!" +"Don't worry, we just wanna see your pretty face (and maybe some cats). " +"Grant us permission and let's get this party started!"} else {// If it's the first time the user lands on this feature, or the user// doesn't want to be asked again for this permission, explain that the// permission is required"Hi there! We need your camera to work our magic! ✨\n" +"Grant us permission and let's get this party started! \uD83C\uDF89"}Text(textToShow, textAlign = TextAlign.Center)Spacer(Modifier.height(16.dp))Button(onClick = { cameraPermissionState.launchPermissionRequest() }) {Text("Unleash the Camera!")}}}}@Composableprivate fun CameraPreviewContent(modifier: Modifier = Modifier) {// TODO: Implement}
创建 ViewModel
class CameraPreviewViewModel : ViewModel() {// Used to set up a link between the Camera and your UI.private val _surfaceRequest = MutableStateFlow<SurfaceRequest?>(null)val surfaceRequest: StateFlow<SurfaceRequest?> = _surfaceRequestprivate val cameraPreviewUseCase = Preview.Builder().build().apply {setSurfaceProvider { newSurfaceRequest ->_surfaceRequest.update { newSurfaceRequest }}}suspend fun bindToCamera(appContext: Context, lifecycleOwner: LifecycleOwner) {val processCameraProvider = ProcessCameraProvider.awaitInstance(appContext)processCameraProvider.bindToLifecycle(lifecycleOwner, DEFAULT_FRONT_CAMERA, cameraPreviewUseCase)// Cancellation signals we're done with the cameratry { awaitCancellation() } finally { processCameraProvider.unbindAll() }}}
实现相机预览界面
@Composablefun CameraPreviewContent(viewModel: CameraPreviewViewModel,modifier: Modifier = Modifier,lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current) {val surfaceRequest by viewModel.surfaceRequest.collectAsStateWithLifecycle()val context = LocalContext.currentLaunchedEffect(lifecycleOwner) {viewModel.bindToCamera(context.applicationContext, lifecycleOwner)}surfaceRequest?.let { request ->CameraXViewfinder(surfaceRequest = request,modifier = modifier)}}
结果
// Copyright 2024 Google LLC. SPDX-License-Identifier: Apache-2.0
谷歌开发者特别招募活动进行中
诚邀热爱技术的你加入
通过多种形式 (文章/视频/coding 等) 创作与 Google 技术相关的讲解分享、实践案例或活动感受等内容,以及分享您应用 AI 技术的故事经历与成果。我们将为您提供平台和资源,助力您在分享中提升技能。更有惊喜权益等您领取,快来报名参与吧!