Commit 0c0ff41e authored by wanglei's avatar wanglei

...

parent ed761de5
...@@ -112,4 +112,9 @@ dependencies { ...@@ -112,4 +112,9 @@ dependencies {
implementation("com.google.firebase:firebase-analytics") implementation("com.google.firebase:firebase-analytics")
implementation("com.google.firebase:firebase-crashlytics") implementation("com.google.firebase:firebase-crashlytics")
//机器学习二维码扫描
implementation("com.google.mlkit:barcode-scanning:17.3.0")
// Use this dependency to use the dynamically downloaded model in Google Play Services
// implementation ("com.google.android.gms:play-services-mlkit-barcode-scanning:18.3.1")
} }
\ No newline at end of file
package com.base.browserwhite.ui.activity.scanqrc package com.base.browserwhite.ui.activity.scanqrc
import android.Manifest import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Color import android.graphics.Color
import android.hardware.camera2.CameraAccessException import android.hardware.camera2.CameraAccessException
import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager import android.hardware.camera2.CameraManager
import android.util.Log
import androidx.activity.addCallback import androidx.activity.addCallback
import androidx.camera.core.AspectRatio import androidx.camera.core.AspectRatio
import androidx.camera.core.Camera import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageProxy
import androidx.camera.core.Preview import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
...@@ -17,10 +22,18 @@ import androidx.core.view.isVisible ...@@ -17,10 +22,18 @@ import androidx.core.view.isVisible
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import com.base.browserwhite.databinding.ActivityScanQrcBinding import com.base.browserwhite.databinding.ActivityScanQrcBinding
import com.base.browserwhite.ui.activity.BaseActivity import com.base.browserwhite.ui.activity.BaseActivity
import com.base.browserwhite.ui.activity.webbrowser.WebBrowserActivity
import com.base.browserwhite.ui.fragment.HomeFragment.Companion.isMatchesUrl
import com.base.browserwhite.ui.views.DialogViews.showGerPermission import com.base.browserwhite.ui.views.DialogViews.showGerPermission
import com.base.browserwhite.utils.BarUtils import com.base.browserwhite.utils.BarUtils
import com.base.browserwhite.utils.LogEx import com.base.browserwhite.utils.LogEx
import com.base.browserwhite.utils.PermissionHelp.checkCameraPermission import com.base.browserwhite.utils.PermissionHelp.checkCameraPermission
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.barcode.common.Barcode.FORMAT_AZTEC
import com.google.mlkit.vision.barcode.common.Barcode.FORMAT_CODABAR
import com.google.mlkit.vision.common.InputImage
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.math.abs import kotlin.math.abs
...@@ -43,6 +56,7 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() { ...@@ -43,6 +56,7 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {
private var lensFacing: Int = CameraSelector.LENS_FACING_BACK private var lensFacing: Int = CameraSelector.LENS_FACING_BACK
private var cameraProvider: ProcessCameraProvider? = null private var cameraProvider: ProcessCameraProvider? = null
private lateinit var cameraExecutor: ExecutorService private lateinit var cameraExecutor: ExecutorService
private var imageAnalyzer: ImageAnalysis? = null
override fun initView() { override fun initView() {
...@@ -60,7 +74,7 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() { ...@@ -60,7 +74,7 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {
initCamera() initCamera()
} else { } else {
showGerPermission( showGerPermission(
desc = "This feature requires access to your storage to scan your files and clean up junk files and unused APK files. We will not transmit your data to any third-party service. Please grant permission so that we can provide you with better service.", desc = "This feature requires accessing your camera device to scan web QR codes. We will not transfer your data to any third-party services. Please grant permission so that we can provide you with better services",
) { ) {
launcher.launch(arrayOf(Manifest.permission.CAMERA)) { map -> launcher.launch(arrayOf(Manifest.permission.CAMERA)) { map ->
if (map.values.all { it }) { if (map.values.all { it }) {
...@@ -134,16 +148,16 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() { ...@@ -134,16 +148,16 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {
// imageCapture = buildImageCapture(aspectRation, rotation) // imageCapture = buildImageCapture(aspectRation, rotation)
//构建图片分析器 //构建图片分析器
// imageAnalyzer = buildImageAnalysis(aspectRation, rotation) { imageAnalyzer = buildImageAnalysis(aspectRation, rotation) {
// it.setAnalyzer(cameraExecutor, LuminosityAnalyzer()) it.setAnalyzer(cameraExecutor, QRImageAnalyzer())
// } }
//每次绑定需先解绑 //每次绑定需先解绑
cameraProvider?.unbindAll() cameraProvider?.unbindAll()
try { try {
camera = cameraProvider?.bindToLifecycle( camera = cameraProvider?.bindToLifecycle(
this, cameraSelector, preview this, cameraSelector, imageAnalyzer, preview
) )
preview?.setSurfaceProvider(binding.previewView.surfaceProvider) preview?.setSurfaceProvider(binding.previewView.surfaceProvider)
} catch (exc: Exception) { } catch (exc: Exception) {
...@@ -151,6 +165,23 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() { ...@@ -151,6 +165,23 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {
} }
} }
private fun buildImageAnalysis(
aspectRatio: Int,
rotation: Int,
analysisAction: (imageAnalysis: ImageAnalysis) -> Unit
): ImageAnalysis {
return ImageAnalysis.Builder()
.setTargetAspectRatio(aspectRatio)
.setTargetRotation(rotation)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.build()
// The analyzer can then be assigned to the instance
.also {
analysisAction(it)
}
}
/** /**
* 构建横纵比 * 构建横纵比
*/ */
...@@ -213,4 +244,58 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() { ...@@ -213,4 +244,58 @@ class ScanQRCActivity : BaseActivity<ActivityScanQrcBinding>() {
return cameraId ?: "" return cameraId ?: ""
} }
//图形分析器
inner class QRImageAnalyzer : ImageAnalysis.Analyzer {
//如需仅检测 Aztec 码和 QR 码
private val options = BarcodeScannerOptions.Builder().setBarcodeFormats(
Barcode.FORMAT_QR_CODE, Barcode.FORMAT_AZTEC
).build()
//获取解析器
private val detector = BarcodeScanning.getClient(options)
@SuppressLint("UnsafeOptInUsageError")
override fun analyze(imageProxy: ImageProxy) {
val mediaImage = imageProxy.image
if (mediaImage != null) {
val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
detector.process(image).addOnSuccessListener { barcodeList ->
// barcodeList.forEach {
// LogEx.logDebug(TAG, "rawValue=${it.rawValue}")
// }
if (barcodeList.size == 1) {
val barcode = barcodeList[0]
val valueType = barcode.valueType
LogEx.logDebug(TAG, "valueType=$valueType")
when (valueType) {
Barcode.FORMAT_QR_CODE, FORMAT_CODABAR, FORMAT_AZTEC -> {
val qrCodeValue = barcode.rawValue ?: ""
LogEx.logDebug(TAG, "qrCodeValue=${qrCodeValue}")
if (isMatchesUrl(qrCodeValue)) {
binding.root.post {
startActivity(Intent(this@ScanQRCActivity, WebBrowserActivity::class.java).apply {
putExtra("url", qrCodeValue)
})
}
}
}
}
// imageAnalysis.clearAnalyzer()
}
}.addOnFailureListener {
LogEx.logDebug(TAG, "OnFailure")
}.addOnCompleteListener {
LogEx.logDebug(TAG, "OnComplete")
imageProxy.close()
}
} else {
imageProxy.close()
}
}
}
} }
\ No newline at end of file
...@@ -154,7 +154,6 @@ ...@@ -154,7 +154,6 @@
android:layout_margin="10dp" android:layout_margin="10dp"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:padding="5dp" android:padding="5dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment