二维码扫描库更新到最新版本
parent
5f1cb6ea91
commit
2d8c5e5f55
@ -0,0 +1,201 @@
|
|||||||
|
package com.rehome.dywoa.ui.activity
|
||||||
|
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.graphics.RectF
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.camera.core.ImageCapture
|
||||||
|
import androidx.camera.view.LifecycleCameraController
|
||||||
|
import androidx.core.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.google.mlkit.vision.barcode.BarcodeScannerOptions
|
||||||
|
import com.google.mlkit.vision.barcode.BarcodeScanning
|
||||||
|
import com.google.mlkit.vision.barcode.common.Barcode
|
||||||
|
import com.google.mlkit.vision.common.InputImage
|
||||||
|
import com.rehome.dywoa.base.BaseActivityOaToolbarViewBinding
|
||||||
|
import com.rehome.dywoa.databinding.ActivityQrCodeNewBinding
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
|
/**
|
||||||
|
* date:2025/02/25 14:05:28
|
||||||
|
* author:HuangWenfei
|
||||||
|
* description:二维码扫描
|
||||||
|
*/
|
||||||
|
class QrCodeNewActivity : BaseActivityOaToolbarViewBinding<ActivityQrCodeNewBinding>() {
|
||||||
|
|
||||||
|
private lateinit var lifecycleCameraController: LifecycleCameraController
|
||||||
|
private lateinit var cameraExecutor: ExecutorService
|
||||||
|
private val CAMERA_REQUEST_CAMERA_SCAN: Int = 88 //请求码
|
||||||
|
|
||||||
|
|
||||||
|
override fun getViewBinding() = ActivityQrCodeNewBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun getToolbar() = binding.toolbarView.toolbar
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
initToolbar("二维码/条码扫描")
|
||||||
|
setLeftOnClickListener { finish() }
|
||||||
|
checkPermission()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkPermission() {
|
||||||
|
//检测摄像头权限
|
||||||
|
if (!context.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
|
||||||
|
binding.frCamera.visibility = View.GONE
|
||||||
|
Toast.makeText(
|
||||||
|
context,
|
||||||
|
"权限拒绝,请手动设置开启APP访问摄像头权限",
|
||||||
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//动态权限申请
|
||||||
|
if (ContextCompat.checkSelfPermission(
|
||||||
|
context,
|
||||||
|
Manifest.permission.CAMERA
|
||||||
|
) != PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
binding.frCamera.visibility = View.GONE
|
||||||
|
//权限请求
|
||||||
|
ActivityCompat.requestPermissions(
|
||||||
|
this,
|
||||||
|
arrayOf<String>(Manifest.permission.CAMERA),
|
||||||
|
CAMERA_REQUEST_CAMERA_SCAN
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
//已授权,打开摄像头扫描
|
||||||
|
initController()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRequestPermissionsResult(
|
||||||
|
requestCode: Int,
|
||||||
|
permissions: Array<String>,
|
||||||
|
grantResults: IntArray
|
||||||
|
) {
|
||||||
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
|
if (CAMERA_REQUEST_CAMERA_SCAN == requestCode) {
|
||||||
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
binding.frCamera.visibility = View.VISIBLE
|
||||||
|
//已授权,打开摄像头扫描
|
||||||
|
initController()
|
||||||
|
} else {
|
||||||
|
binding.frCamera.visibility = View.GONE
|
||||||
|
//权限拒绝
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
"权限拒绝,请手动设置开启APP访问摄像头权限",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("UnsafeOptInUsageError")
|
||||||
|
private fun initController() {
|
||||||
|
|
||||||
|
//配置当前扫码格式
|
||||||
|
val options = BarcodeScannerOptions.Builder()
|
||||||
|
.setBarcodeFormats(
|
||||||
|
Barcode.FORMAT_QR_CODE,
|
||||||
|
Barcode.FORMAT_AZTEC
|
||||||
|
).build()
|
||||||
|
|
||||||
|
|
||||||
|
//获取解析器
|
||||||
|
val detector = BarcodeScanning.getClient(options)
|
||||||
|
|
||||||
|
cameraExecutor = Executors.newSingleThreadExecutor()
|
||||||
|
lifecycleCameraController = LifecycleCameraController(this)
|
||||||
|
lifecycleCameraController.bindToLifecycle(this)
|
||||||
|
lifecycleCameraController.imageCaptureFlashMode = ImageCapture.FLASH_MODE_AUTO
|
||||||
|
lifecycleCameraController.setImageAnalysisAnalyzer(
|
||||||
|
cameraExecutor
|
||||||
|
) { imageProxy ->
|
||||||
|
val mediaImage = imageProxy.image
|
||||||
|
if (mediaImage != null) {
|
||||||
|
val image = InputImage.fromMediaImage(
|
||||||
|
mediaImage,
|
||||||
|
imageProxy.imageInfo.rotationDegrees
|
||||||
|
)
|
||||||
|
detector.process(image)
|
||||||
|
.addOnSuccessListener { barCodes ->
|
||||||
|
if (barCodes.size > 0) {
|
||||||
|
showLog("barCodes: ${barCodes.size}")
|
||||||
|
//接收到结果后,就关闭解析
|
||||||
|
detector.close()
|
||||||
|
initScale(image.width, image.height)
|
||||||
|
val list = ArrayList<RectF>()
|
||||||
|
val strList = ArrayList<String>()
|
||||||
|
|
||||||
|
barCodes.forEach { barcode ->
|
||||||
|
barcode.boundingBox?.let { rect ->
|
||||||
|
val translateRect = translateRect(rect)
|
||||||
|
list.add(translateRect)
|
||||||
|
strList.add(barcode.rawValue ?: "No Value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.scanView.setRectList(list)
|
||||||
|
judgeIntent(strList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.addOnFailureListener {
|
||||||
|
showLog("Error: ${it.message}")
|
||||||
|
}
|
||||||
|
.addOnCompleteListener {
|
||||||
|
imageProxy.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.previewView.controller = lifecycleCameraController
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun judgeIntent(list: ArrayList<String>) {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
list.forEach {
|
||||||
|
sb.append(it)
|
||||||
|
}
|
||||||
|
intentToResult(sb.toString().trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun intentToResult(result: String) {
|
||||||
|
val resultIntent = Intent()
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.putString("code", result)
|
||||||
|
resultIntent.putExtras(bundle)
|
||||||
|
setResult(RESULT_OK, resultIntent)
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
private var scaleX = 0f
|
||||||
|
private var scaleY = 0f
|
||||||
|
|
||||||
|
private fun translateX(x: Float): Float = x * scaleX
|
||||||
|
private fun translateY(y: Float): Float = y * scaleY
|
||||||
|
|
||||||
|
//将扫描的矩形换算为当前屏幕大小
|
||||||
|
private fun translateRect(rect: Rect) = RectF(
|
||||||
|
translateX(rect.left.toFloat()),
|
||||||
|
translateY(rect.top.toFloat()),
|
||||||
|
translateX(rect.right.toFloat()),
|
||||||
|
translateY(rect.bottom.toFloat())
|
||||||
|
)
|
||||||
|
|
||||||
|
//初始化缩放比例
|
||||||
|
private fun initScale(imageWidth: Int, imageHeight: Int) {
|
||||||
|
scaleY = binding.scanView.height.toFloat() / imageWidth.toFloat()
|
||||||
|
scaleX = binding.scanView.width.toFloat() / imageHeight.toFloat()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".ui.activity.QrCodeNewActivity">
|
||||||
|
|
||||||
|
<include
|
||||||
|
android:id="@+id/toolbarView"
|
||||||
|
layout="@layout/layout_base" />
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/fr_camera"
|
||||||
|
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" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/scan_bg"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<com.rehome.dywoa.weiget.ScanView
|
||||||
|
android:id="@+id/scanView"
|
||||||
|
android:layout_width="250dp"
|
||||||
|
android:layout_height="250dp"
|
||||||
|
android:background="@android:color/transparent" />
|
||||||
|
</LinearLayout>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textColor="#666666"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:text="@string/scan_text"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
Loading…
Reference in New Issue