You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio如何打开相机仅显示实时预览不触发拍照

Android 实现无拍照功能的相机实时预览+自定义叠加层

优先使用Jetpack CameraX实现,这是官方目前推荐的相机开发组件,已经封装了绝大多数设备的兼容逻辑,不需要自己处理预览尺寸适配、角度旋转、生命周期绑定等琐碎问题,且可以自由选择只启用预览能力,不会自带默认拍照UI。

1. 配置权限与依赖

首先在AndroidManifest.xml中添加必要的权限和特性声明:

<!-- 相机权限,仅预览不需要存储权限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 声明应用依赖相机硬件,应用市场会自动过滤无相机的设备 -->
<uses-feature android:name="android.hardware.camera" android:required="true" />

在模块级的build.gradle依赖块中添加CameraX相关依赖,版本号可选择当前最新的稳定版:

def camerax_version = "1.3.1"
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}"

Android 6.0及以上版本需要动态申请相机危险权限,在初始化相机前先校验权限状态,未授权时弹出系统权限申请弹窗,拿到权限后再执行相机初始化逻辑。

2. 编写布局实现叠加层

使用ConstraintLayout或者FrameLayout作为根布局,底层放置相机预览控件,上层直接放置任意你需要的叠加层控件即可——布局层级更高的View会自动悬浮在预览画面之上,不需要对相机做任何特殊配置。
示例布局代码:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 底层:相机预览控件,默认占满全屏 -->
    <androidx.camera.view.PreviewView
        android:id="@+id/previewView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:scaleType="fillCenter" />

    <!-- 上层:自定义叠加层,可自由添加任意View -->
    <!-- 示例:中间的识别框 -->
    <View
        android:id="@+id/recognize_frame"
        android:layout_width="240dp"
        android:layout_height="240dp"
        android:background="@drawable/frame_border"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
    <!-- 示例:顶部提示文字 -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请将目标对准识别框"
        android:textColor="#FFFFFF"
        android:textSize="16sp"
        android:layout_marginTop="48dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

叠加层的View和普通页面View没有任何区别,可自由设置点击事件、动画、自定义绘制逻辑,不会影响底层相机预览。

3. 初始化相机,仅绑定预览用例

CameraX通过绑定不同用例实现不同功能:绑定ImageCapture对应拍照能力,绑定ImageAnalysis对应帧分析能力。如果只需要预览,仅绑定Preview预览用例即可,不会存在任何拍照相关的触发逻辑。
示例实现代码(Kotlin):

class CameraPreviewActivity : AppCompatActivity() {
    private lateinit var previewView: PreviewView
    private val cameraExecutor = Executors.newSingleThreadExecutor()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_camera_preview)
        previewView = findViewById(R.id.previewView)

        // 校验相机权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            startCameraPreview()
        } else {
            ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), REQ_CAMERA_PERMISSION)
        }
    }

    private fun startCameraPreview() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener({
            val cameraProvider = cameraProviderFuture.get()
            // 仅配置预览用例
            val preview = Preview.Builder()
                .build()
                .apply {
                    surfaceProvider = previewView.surfaceProvider
                }
            // 选择默认后置摄像头,需要前置可替换为CameraSelector.DEFAULT_FRONT_CAMERA
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                cameraProvider.unbindAll()
                // 核心:仅绑定preview用例,不添加任何拍照、分析相关用例
                cameraProvider.bindToLifecycle(this, cameraSelector, preview)
            } catch (e: Exception) {
                // 处理相机打开失败场景:相机被占用、设备不支持等
                e.printStackTrace()
                Toast.makeText(this, "相机启动失败", Toast.LENGTH_SHORT).show()
            }
        }, ContextCompat.getMainExecutor(this))
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQ_CAMERA_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startCameraPreview()
            } else {
                Toast.makeText(this, "需要相机权限才能使用预览功能", Toast.LENGTH_SHORT).show()
                finish()
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        cameraExecutor.shutdown()
    }

    companion object {
        private const val REQ_CAMERA_PERMISSION = 1001
    }
}

注意事项

  • 不要通过系统相机Intent调用相机,这种方式会跳转到系统自带相机应用,你无法在其界面上添加自定义叠加层。
  • 非必要不直接使用原生Camera2 API开发,Camera2需要自行处理数十种设备兼容问题、预览尺寸匹配、角度旋转、生命周期释放等逻辑,代码量是CameraX的5倍以上,容易出现兼容性bug。
  • 如果需要在叠加层上做自定义绘制(比如人脸框、区域标记),直接自定义View重写onDraw方法放在预览上层即可,不需要修改相机预览逻辑,也不需要获取预览帧数据。
  • 叠加层的触摸事件不会被预览拦截,直接给上层View设置对应监听即可正常响应。
  • PreviewView已经自动处理了横竖屏预览角度适配,你只需要自行处理叠加层在不同屏幕方向的布局适配即可。

内容的提问来源于stack exchange,提问作者Phantom37

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:51:26