diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4ac8850..480638a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -129,6 +129,10 @@ android:name=".ui.activity.QrCodeActivity" android:exported="false" android:screenOrientation="portrait" /> + , Int, Int) -> Unit) : @@ -23,7 +23,7 @@ class QRCodeAnalyser(private val listener: (List, Int, Int) -> Unit) : //获取解析器 private val detector = BarcodeScanning.getClient(options) - @SuppressLint("UnsafeExperimentalUsageError", "UnsafeOptInUsageError") + @SuppressLint("UnsafeOptInUsageError") override fun analyze(imageProxy: ImageProxy) { val mediaImage = imageProxy.image ?: kotlin.run { imageProxy.close() @@ -32,8 +32,8 @@ class QRCodeAnalyser(private val listener: (List, Int, Int) -> Unit) : val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees) detector.process(image) .addOnSuccessListener { barCodes -> - Log.i("app", "barCodes: ${barCodes.size}") if (barCodes.size > 0) { + Log.i("app", "barCodes: ${barCodes.size}") listener.invoke(barCodes, imageProxy.width, imageProxy.height) //接收到结果后,就关闭解析 detector.close() diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/QrCodeActivity.kt b/app/src/main/java/com/rehome/dywoa/ui/activity/QrCodeActivity.kt index 5296ec7..74594ec 100644 --- a/app/src/main/java/com/rehome/dywoa/ui/activity/QrCodeActivity.kt +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/QrCodeActivity.kt @@ -20,6 +20,7 @@ import com.rehome.dywoa.base.BaseActivityOaToolbarViewBinding import java.util.concurrent.ExecutorService import java.util.concurrent.Executors + /** * date:2025/02/13 10:05:28 * author:HuangWenfei @@ -31,12 +32,6 @@ class QrCodeActivity : BaseActivityOaToolbarViewBinding() private lateinit var cameraExecutor: ExecutorService private val CAMERA_REQUEST_CAMERA_SCAN: Int = 88 //请求码 -// override fun onCreate(savedInstanceState: Bundle?) { -// super.onCreate(savedInstanceState) -// binding = ActivityQrCodeBinding.inflate(layoutInflater) -// setContentView(binding.root) -// initController() -// } override fun getViewBinding() = ActivityQrCodeBinding.inflate(layoutInflater) @@ -127,12 +122,6 @@ class QrCodeActivity : BaseActivityOaToolbarViewBinding() barcode.boundingBox?.let { rect -> val translateRect = translateRect(rect) list.add(translateRect) -// Log.e( -// "ztzt", "left:${translateRect.left} +" + -// " top:${translateRect.top} + right:${translateRect.right}" + -// " + bottom:${translateRect.bottom}" -// ) -// Log.e("ztzt", "barcode.rawValue:${barcode.rawValue}") strList.add(barcode.rawValue ?: "No Value") } } diff --git a/app/src/main/java/com/rehome/dywoa/ui/activity/QrCodeNewActivity.kt b/app/src/main/java/com/rehome/dywoa/ui/activity/QrCodeNewActivity.kt new file mode 100644 index 0000000..4bdffa8 --- /dev/null +++ b/app/src/main/java/com/rehome/dywoa/ui/activity/QrCodeNewActivity.kt @@ -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() { + + 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(Manifest.permission.CAMERA), + CAMERA_REQUEST_CAMERA_SCAN + ) + } else { + //已授权,打开摄像头扫描 + initController() + } + } + + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + 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() + val strList = ArrayList() + + 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) { + 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() + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_qr_code_new.xml b/app/src/main/res/layout/activity_qr_code_new.xml new file mode 100644 index 0000000..0b0b99c --- /dev/null +++ b/app/src/main/res/layout/activity_qr_code_new.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 183fc6d..6c7d74d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -33,7 +33,8 @@ recyclerview = "1.4.0" retrofit = "2.9.0" smarttable = "2.2.0" squareupPicasso = "2.5.2" -barcodeScanning = "16.1.1" +barcodeScanning = "17.3.0" +facedetection = "16.1.7" supportV4 = "28.0.0" xui = "1.2.1" @@ -52,7 +53,8 @@ bcprov-jdk15on = { module = "org.bouncycastle:bcprov-jdk15on", version.ref = "bc camerax = { module = "io.github.lucksiege:camerax", version.ref = "pictureselector" } circleimageview = { module = "de.hdodenhof:circleimageview", version.ref = "circleimageview" } cn-hutool-all = { module = "cn.hutool:hutool-all", version.ref = "hutoolAllVersion" } -com-google-mlkit-face-detection2 = { module = "com.google.mlkit:face-detection", version.ref = "barcodeScanning" } +com-google-mlkit-face-detection2 = { module = "com.google.mlkit:face-detection", version.ref = "facedetection" } +barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "barcodeScanning" } com-squareup-picasso-picasso = { module = "com.squareup.picasso:picasso", version.ref = "squareupPicasso" } com-squareup-retrofit2-converter-gson5 = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" } commons-codec-commons-codec4 = { module = "commons-codec:commons-codec", version.ref = "commonsCodecCommonsCodec2" } @@ -70,7 +72,6 @@ logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", ver material = { group = "com.google.android.material", name = "material", version.ref = "material" } androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } -barcode-scanning = { module = "com.google.mlkit:barcode-scanning", version.ref = "barcodeScanning" } paho-org-eclipse-paho-android-service = { module = "org.eclipse.paho:org.eclipse.paho.android.service", version.ref = "orgEclipsePahoAndroidServiceVersion" } paho-org-eclipse-paho-client-mqttv3 = { module = "org.eclipse.paho:org.eclipse.paho.client.mqttv3", version.ref = "orgEclipsePahoClientMqttv3Version" } photoviewer = { module = "com.github.wanglu1209:PhotoViewer", version.ref = "photoviewer" }