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

如何在Android Studio中用CameraView仅识别应用内定义的二维码(无第三方库)

实现仅识别预定义二维码的CameraView扫描功能(无第三方库)

核心思路

用官方Jetpack CameraX的CameraView组件采集画面,搭配Google ML Kit条码扫描(官方组件,非第三方库)识别二维码,仅对预定义内容做响应,直接忽略其他无关二维码。


步骤1:配置权限与布局

  1. 添加相机权限到AndroidManifest.xml:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    
  2. 布局中添加CameraView:

    <androidx.camera.view.CameraView
        android:id="@+id/cameraView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:cameraLensFacing="back" />
    

步骤2:定义有效二维码内容集合

把需要识别的二维码内容存入集合,用于后续校验:

private val VALID_QR_CONTENTS = setOf(
    "MY_APP_VALID_CODE_001",
    "https://myapp.com/verify/123",
    "USER_AUTH_TOKEN_456"
)

步骤3:初始化条码扫描器

仅启用二维码格式识别,避免识别其他条码类型:

private lateinit var barcodeScanner: BarcodeScanner

private fun initBarcodeScanner() {
    val scanOptions = BarcodeScannerOptions.Builder()
        .setBarcodeFormats(Barcode.FORMAT_QR_CODE)
        .build()
    barcodeScanner = BarcodeScanning.getClient(scanOptions)
}

步骤4:创建二维码分析器

实现ImageAnalysis.Analyzer,负责逐帧分析画面、识别并校验二维码:

private val qrAnalyzer = ImageAnalysis.Analyzer { imageProxy ->
    val mediaImage = imageProxy.image ?: run {
        imageProxy.close()
        return@Analyzer
    }

    // 将相机帧转换为ML Kit可处理的输入格式
    val inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)

    barcodeScanner.process(inputImage)
        .addOnSuccessListener { barcodes ->
            barcodes.forEach { barcode ->
                barcode.rawValue?.let { qrContent ->
                    // 校验内容是否在预定义集合中
                    if (VALID_QR_CONTENTS.contains(qrContent)) {
                        // 识别到有效二维码,执行业务逻辑
                        runOnUiThread {
                            Toast.makeText(this, "扫描到有效二维码:$qrContent", Toast.LENGTH_SHORT).show()
                            // 可选:停止扫描,避免重复触发
                            cameraView.stop()
                        }
                    }
                    // 无效内容直接忽略,不做任何响应
                }
            }
        }
        .addOnCompleteListener {
            // 必须关闭imageProxy,否则会阻塞后续帧处理
            imageProxy.close()
        }
}

步骤5:绑定CameraView与分析器

在Activity生命周期中完成权限校验和组件绑定:

private val requestPermissionLauncher = registerForActivityResult(
    ActivityResultContracts.RequestPermission()
) { isGranted ->
    if (isGranted) {
        cameraView.start()
        bindAnalyzerToCamera()
    } else {
        Toast.makeText(this, "需要相机权限才能扫描二维码", Toast.LENGTH_SHORT).show()
    }
}

override fun onStart() {
    super.onStart()
    initBarcodeScanner()

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
        == PackageManager.PERMISSION_GRANTED
    ) {
        cameraView.bindToLifecycle(this)
        bindAnalyzerToCamera()
    } else {
        requestPermissionLauncher.launch(Manifest.permission.CAMERA)
    }
}

private fun bindAnalyzerToCamera() {
    ProcessCameraProvider.getInstance(this).addOnSuccessListener { provider ->
        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
        // 配置分析器,只保留最新帧,避免卡顿
        val imageAnalysis = ImageAnalysis.Builder()
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
        imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(), qrAnalyzer)

        // 绑定生命周期、相机选择器、分析器和预览
        provider.bindToLifecycle(
            this, cameraSelector, imageAnalysis, cameraView.preview
        )
    }
}

步骤6:添加官方依赖

在build.gradle(Module level)中添加CameraX和ML Kit的官方依赖:

dependencies {
    // CameraX 核心组件
    implementation "androidx.camera:camera-core:1.2.3"
    implementation "androidx.camera:camera-lifecycle:1.2.3"
    // CameraView 预览组件
    implementation "androidx.camera:camera-view:1.0.0-alpha34"
    // ML Kit 条码扫描
    implementation "com.google.mlkit:barcode-scanning:17.2.0"
}

关键注意事项

  • 所有UI操作必须切换到主线程执行,避免崩溃。
  • 处理完每一帧后必须调用imageProxy.close(),否则会导致相机帧队列阻塞、出现卡顿。
  • 如果需要持续扫描有效二维码,不要调用cameraView.stop(),可添加防抖逻辑(比如1秒内不重复识别同一内容)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 08:17:48