在 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.** { *; }
常见问题
-
扫描界面不启动
- 检查相机权限是否授予。
- 确保设备支持相机功能。
-
无法识别二维码
- 确认二维码清晰且未被遮挡。
- 检查是否指定了正确的格式(如
BarcodeFormat.QR_CODE
)。
-
依赖冲突
- 如果与其他库冲突,尝试排除重复依赖:
implementation ('com.journeyapps:zxing-android-embedded:4.3.0') { exclude group: 'com.google.zxing' }
- 如果与其他库冲突,尝试排除重复依赖:
通过以上步骤,即可快速集成 ZXing 实现二维码扫描功能。如果需要更多定制(如界面样式、扫描动画),可参考 zxing-android-embedded 官方文档。