Android平台使用Zxing的步骤

1 阅读2分钟

在 Android 平台使用 ZXing (Zebra Crossing) 实现二维码扫描,可以通过直接集成核心库或使用简化后的封装库(如 zxing-android-embedded)。以下是详细步骤:


1. 添加依赖

ZXing 的官方库较为底层,推荐使用 zxing-android-embedded 简化集成:

// build.gradle (Module)
dependencies {
    implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
    implementation 'androidx.appcompat:appcompat:1.6.1'  // 依赖 AppCompat
}

2. 配置相机权限

AndroidManifest.xml 中添加相机权限:

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

3. 动态申请权限

在 Activity 中动态请求相机权限(针对 Android 6.0+):

private val CAMERA_PERMISSION_REQUEST_CODE = 100

private fun checkCameraPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) 
        != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.CAMERA),
            CAMERA_PERMISSION_REQUEST_CODE
        )
    } else {
        startScan() // 已授权,启动扫描
    }
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
        if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            startScan()
        } else {
            Toast.makeText(this, "需要相机权限", Toast.LENGTH_SHORT).show()
        }
    }
}

4. 启动扫描界面

方式一:直接调用默认扫描界面

private fun startScan() {
    val integrator = IntentIntegrator(this)
    integrator.setOrientationLocked(false) // 允许旋转
    integrator.setPrompt("将二维码放入框内") // 提示文字
    integrator.setBeepEnabled(true)       // 扫描成功声音提示
    integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE) // 指定二维码类型
    integrator.initiateScan()
}

方式二:自定义扫描界面(嵌入到当前 Activity)

// 在布局文件中添加一个容器(如 FrameLayout)
<FrameLayout
    android:id="@+id/scanner_container"
    android:layout_width="match_parent"
    android:layout_height="300dp" />

// 在代码中初始化扫描器
private var barcodeView: DecoratedBarcodeView? = null

private fun setupScanner() {
    barcodeView = DecoratedBarcodeView(this).apply {
        val formats = listOf(BarcodeFormat.QR_CODE) // 指定格式
        decoderFactory = DefaultDecoderFactory(formats)
        setStatusText("扫描二维码")
    }

    scanner_container.addView(barcodeView)
    barcodeView?.decodeSingle(object : BarcodeCallback {
        override fun barcodeResult(result: BarcodeResult?) {
            result?.text?.let { qrContent ->
                // 处理扫描结果
                Toast.makeText(this@MainActivity, "扫描结果: $qrContent", Toast.LENGTH_SHORT).show()
            }
        }
    })
}

override fun onResume() {
    super.onResume()
    barcodeView?.resume()
}

override fun onPause() {
    super.onPause()
    barcodeView?.pause()
}

5. 处理扫描结果

onActivityResult 中接收扫描结果:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
    if (result != null) {
        if (result.contents == null) {
            Toast.makeText(this, "扫描取消", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this, "扫描结果: ${result.contents}", Toast.LENGTH_LONG).show()
            // 处理扫描结果(如跳转页面、解析数据等)
        }
    }
}

6. 混淆配置(ProGuard)

proguard-rules.pro 中添加:

-keep class com.journeyapps.barcodescanner.** { *; }
-keep class com.google.zxing.** { *; }

常见问题

  1. 扫描界面不启动

    • 检查相机权限是否授予。
    • 确保设备支持相机功能。
  2. 无法识别二维码

    • 确认二维码清晰且未被遮挡。
    • 检查是否指定了正确的格式(如 BarcodeFormat.QR_CODE)。
  3. 依赖冲突

    • 如果与其他库冲突,尝试排除重复依赖:
      implementation ('com.journeyapps:zxing-android-embedded:4.3.0') {
          exclude group: 'com.google.zxing'
      }
      

通过以上步骤,即可快速集成 ZXing 实现二维码扫描功能。如果需要更多定制(如界面样式、扫描动画),可参考 zxing-android-embedded 官方文档