Android CameraX 使用指南及一些高级功能(简化相机开发)

 更新时间:2025年07月28日 10:12:08   作者:安卓开发者  
CameraX简化Android相机开发,解决兼容性、生命周期与API复杂性问题,支持图像分析、拍照及设备特性检查,通过最佳实践,开发者可高效实现高质量相机功能,专注业务逻辑,本文给大家介绍Android CameraX 使用指南及一些高级功能,感兴趣的朋友一起看看吧

前言

在Android开发中,相机功能一直是比较复杂的部分,需要处理不同设备的兼容性、生命周期管理以及复杂的API调用。Google推出的CameraX库极大地简化了这一过程,让开发者能够更轻松地实现高质量的相机功能。本文将带你全面了解CameraX的使用方法。

什么是CameraX?

CameraX是Jetpack系列中的一个库,它基于Camera2 API构建,但提供了更高层次的抽象,具有以下优点:

  • 简化API:比Camera2 API更易于使用
  • 生命周期感知:自动管理相机生命周期
  • 设备兼容性:处理不同厂商设备的兼容性问题
  • 一致的行为:在不同设备上提供更一致的体验

添加依赖

首先,在build.gradle文件中添加CameraX依赖:

def camerax_version = "1.3.0"
implementation "androidx.camera:camera-core:${camerax_version}"
implementation "androidx.camera:camera-camera2:${camerax_version}"
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
implementation "androidx.camera:camera-view:${camerax_version}"

基本使用流程

1. 请求相机权限

在AndroidManifest.xml中添加权限声明:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

运行时请求权限:

private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted ->
    if (isGranted) {
        startCamera()
    } else {
        Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
    }
}
// 检查并请求权限
if (ContextCompat.checkSelfPermission(
        this, Manifest.permission.CAMERA
    ) == PackageManager.PERMISSION_GRANTED
) {
    startCamera()
} else {
    requestPermissionLauncher.launch(Manifest.permission.CAMERA)
}

2. 配置预览视图

在布局文件中添加PreviewView:

<androidx.camera.view.PreviewView
    android:id="@+id/viewFinder"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3. 初始化CameraX

private fun startCamera() {
    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
    cameraProviderFuture.addListener({
        // 用于绑定相机生命周期
        val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
        // 预览
        val preview = Preview.Builder()
            .build()
            .also {
                it.setSurfaceProvider(viewFinder.surfaceProvider)
            }
        // 选择后置摄像头
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
        try {
            // 解绑之前的所有用例
            cameraProvider.unbindAll()
            // 绑定用例到生命周期
            cameraProvider.bindToLifecycle(
                this, cameraSelector, preview
            )
        } catch(exc: Exception) {
            Log.e(TAG, "Use case binding failed", exc)
        }
    }, ContextCompat.getMainExecutor(this))
}

高级功能

图像分析

CameraX可以轻松实现图像分析:

val imageAnalysis = ImageAnalysis.Builder()
    .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
    .build()
imageAnalysis.setAnalyzer(executor) { imageProxy ->
    // 在这里处理图像
    val rotationDegrees = imageProxy.imageInfo.rotationDegrees
    // 处理完成后关闭imageProxy
    imageProxy.close()
}
// 记得在bindToLifecycle中添加这个用例
cameraProvider.bindToLifecycle(
    this, cameraSelector, preview, imageAnalysis
)

拍照功能

private fun takePhoto() {
    // 创建图片捕获用例
    val imageCapture = ImageCapture.Builder()
        .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
        .build()
    // 绑定用例
    cameraProvider.bindToLifecycle(
        this, cameraSelector, preview, imageCapture
    )
    // 创建输出选项
    val outputOptions = ImageCapture.OutputFileOptions.Builder(
        File(externalMediaDirs.first(), "${System.currentTimeMillis()}.jpg")
    ).build()
    // 拍照
    imageCapture.takePicture(
        outputOptions,
        ContextCompat.getMainExecutor(this),
        object : ImageCapture.OnImageSavedCallback {
            override fun onError(exc: ImageCaptureException) {
                Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
            }
            override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                val savedUri = output.savedUri ?: Uri.fromFile(outputOptions.outputFile)
                Log.d(TAG, "Photo capture succeeded: $savedUri")
            }
        }
    )
}

处理设备特性

CameraX提供了简单的方式来检查设备支持的功能:

val cameraInfo = cameraProvider.availableCameraInfos.find {
    it.cameraSelector == cameraSelector
}
// 检查闪光灯支持
val hasFlash = cameraInfo?.torchState?.value != null
// 检查变焦支持
val hasZoom = cameraInfo?.zoomState?.value != null

最佳实践

  • 生命周期管理:确保正确绑定到生命周期所有者
  • 错误处理:妥善处理所有可能的异常
  • 资源清理:及时关闭ImageProxy等资源
  • 线程管理:使用合适的Executor
  • 性能优化:根据需求选择合适的配置(分辨率、帧率等)

总结

CameraX极大地简化了Android相机开发,让开发者能够专注于业务逻辑而不是底层细节。通过本文的介绍,你应该已经掌握了CameraX的基本用法和一些高级功能。现在,你可以尝试在自己的应用中实现相机功能了!

参考资源

到此这篇关于Android CameraX 使用指南及一些高级功能(简化相机开发)的文章就介绍到这了,更多相关Android CameraX 使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android开发中常见问题

    Android开发中常见问题

    这篇文章主要为大家详细介绍了Android开发中常见问题,主要涉及了七个问题,希望能帮助到大家,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • Android实现动态切换组件背景的方法

    Android实现动态切换组件背景的方法

    这篇文章主要介绍了Android实现动态切换组件背景的方法,需要的朋友可以参考下
    2014-07-07
  • Android实现图片预览与保存功能

    Android实现图片预览与保存功能

    在App开发中,通常为了省流提高加载速度提升用户体验我们通常在列表中或新闻中的插图都是以缩略图压缩过的图片来进行展示,当用户点击图片时我们再去加载真正像素的大图让用户预览。本文将利用Flutter实现这一功能,需要的可以参考一下
    2022-04-04
  • Android用Scroller实现一个可向上滑动的底部导航栏

    Android用Scroller实现一个可向上滑动的底部导航栏

    本篇文章主要介绍了Android用Scroller实现一个可上滑的底部导航栏,具有一定的参考价值,有兴趣的小伙伴们可以参考一下
    2017-07-07
  • Android实现ListView异步加载的方法(改进版)

    Android实现ListView异步加载的方法(改进版)

    这篇文章主要介绍了Android实现ListView异步加载的方法,针对前面介绍的方法进行了线程操作的改进,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • 详解Android StrictMode严格模式的使用方法

    详解Android StrictMode严格模式的使用方法

    这篇文章主要介绍了Android StrictMode严格模式的使用方法,需要的朋友可以参考下
    2018-01-01
  • Android数据存储方式操作模式解析

    Android数据存储方式操作模式解析

    这篇文章主要为大家介绍了Android数据存储方式操作模式解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Android实现3秒钟自动关闭界面

    Android实现3秒钟自动关闭界面

    这篇文章主要为大家详细介绍了Android实现3秒钟自动关闭界面,以支付成功为例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • 浅谈谈Android 图片选择器

    浅谈谈Android 图片选择器

    近段时间有项目要求写一个类似于微信发送图片时,用来选择照片的一个图片浏览器。相信有很多网友也有这样的需求,这里分享给大家
    2015-12-12
  • Android重写TextView实现文字整齐排版的方法(附demo源码下载)

    Android重写TextView实现文字整齐排版的方法(附demo源码下载)

    这篇文章主要介绍了Android重写TextView实现文字整齐排版的方法,结合实例形式分析了Android重写TextView实现文字整齐排版的相关技巧,并附带demo源码供读者下载参考,需要的朋友可以参考下
    2016-02-02

最新评论