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

如何在Jetpack Compose中点击按钮时打开相机?

解决点击按钮打开相机预览的问题

1. 配置相机权限

先在AndroidManifest.xml中添加必要权限:

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

2. 布局文件设置

在Activity布局里添加触发按钮和预览容器(推荐用CameraX的PreviewView,兼容性更好):

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/openCameraBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="打开相机"/>

    <androidx.camera.view.PreviewView
        android:id="@+id/previewView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:visibility="gone"/> <!-- 默认隐藏,点击按钮后显示 -->

</LinearLayout>

3. 核心代码实现

在Activity中处理权限申请和按钮点击逻辑,用CameraX初始化并显示预览:

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {
    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
    private val REQUEST_CAMERA_PERMISSION = 100

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        cameraProviderFuture = ProcessCameraProvider.getInstance(this)

        openCameraBtn.setOnClickListener {
            // 先检查相机权限
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(Manifest.permission.CAMERA),
                    REQUEST_CAMERA_PERMISSION
                )
            } else {
                // 权限已通过,启动预览
                startCameraPreview()
            }
        }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startCameraPreview()
            }
        }
    }

    private fun startCameraPreview() {
        previewView.visibility = View.VISIBLE
        cameraProviderFuture.addListener({
            val cameraProvider = cameraProviderFuture.get()
            // 创建预览用例
            val preview = Preview.Builder().build().also {
                it.setSurfaceProvider(previewView.surfaceProvider)
            }
            // 选择后置摄像头
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
            try {
                // 解绑之前的相机用例,避免冲突
                cameraProvider.unbindAll()
                // 将预览用例绑定到Activity生命周期
                cameraProvider.bindToLifecycle(this, cameraSelector, preview)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }, ContextCompat.getMainExecutor(this))
    }
}

关键提示

  • 不要尝试直接在onClick里创建独立的CameraPreviewScreen,而是通过显示隐藏预览容器或者启动包含预览的Fragment/Activity来实现逻辑。
  • CameraX是Google官方推荐的相机库,自动处理生命周期和资源释放,比传统Camera API更省心。
  • 相机权限是危险权限,必须先动态申请,否则相机无法正常启动。

内容的提问来源于stack exchange,提问作者marc vincent ferrer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 18:57:20