【问题标题】:Issues with the latest CameraX and Barcode Scanning on some devices某些设备上最新的 CameraX 和条形码扫描的问题
【发布时间】:2020-11-10 07:16:20
【问题描述】:

所以我正在开发一个需要 QR 扫描仪作为主要功能的应用程序。之前我使用的是带有 Firebase ML vision 24.0.3 的 camerax-alpha06,它们工作了好几个月,没有客户抱怨扫描问题。

然后大约两周前,我不得不将 Firebase ML vision 更改为 MLKit 条形码扫描(与 Crashlytics 迁移有关 - 超出主题),现在一些可以在以前版本中扫描的用户现在不能。一些示例设备是 Samsung Tab A7 (Android 5.1.1) 和 Vivo 1919 (Android 10)

这是我的 build.gradle 部分,涉及到这个功能

 def camerax_version = "1.0.0-beta11"
    implementation "androidx.camera:camera-core:${camerax_version}"
    implementation "androidx.camera:camera-camera2:${camerax_version}"
    implementation "androidx.camera:camera-lifecycle:${camerax_version}"
    implementation "androidx.camera:camera-view:1.0.0-alpha18"
    implementation "androidx.camera:camera-extensions:1.0.0-alpha18"
    implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.2'

这是我的相机处理程序文件

class ScanQRCameraViewHandler(
    private val fragment: ScanQRDialogFragment,
    private val previewView: PreviewView
) {
    private val displayLayout get() = previewView
    companion object {
        private const val RATIO_4_3_VALUE = 4.0 / 3.0
        private const val RATIO_16_9_VALUE = 16.0 / 9.0
    }

    private val analyzer = GMSMLKitAnalyzer(onFoundQR = { extractedString ->
        fragment.verifyExtractedString(extractedString)
    }, onNotFoundQR = {
        resetStateToAllowNewImageStream()
    })
    private var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>? = null
    private var camera: Camera? = null
    private var isAnalyzing = false

    internal fun resetStateToAllowNewImageStream() {
        isAnalyzing = false
    }

    internal fun setTorceEnable(isEnabled: Boolean) {
        camera?.cameraControl?.enableTorch(isEnabled)
    }

    internal fun initCameraProviderIfHasNot() {
        if (cameraProviderFuture == null) {
            fragment.context?.let {
                cameraProviderFuture = ProcessCameraProvider.getInstance(it)
                val executor = ContextCompat.getMainExecutor(it)
                cameraProviderFuture?.addListener({
                    bindPreview(cameraProviderFuture?.get(), executor)
                }, executor)
            }
        }
    }

    private fun bindPreview(cameraProvider: ProcessCameraProvider?, executor: Executor) {
        val metrics = DisplayMetrics().also { displayLayout.display.getRealMetrics(it) }
        val screenAspectRatio = aspectRatio(metrics.widthPixels, metrics.heightPixels)

        val preview = initPreview(screenAspectRatio)
        val imageAnalyzer = createImageAnalyzer()
        val imageAnalysis = createImageAnalysis(executor, imageAnalyzer, screenAspectRatio)
        val cameraSelector = createCameraSelector()

        cameraProvider?.unbindAll()
        camera = cameraProvider?.bindToLifecycle(
            fragment as LifecycleOwner,
            cameraSelector, imageAnalysis, preview
        )
    }

    private fun createCameraSelector(): CameraSelector {
        return CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()
    }

    private fun createImageAnalysis(
        executor: Executor, imageAnalyzer: ImageAnalysis.Analyzer, screenAspectRatio: Int
    ): ImageAnalysis {
        val rotation = displayLayout.rotation
        val imageAnalysis = ImageAnalysis.Builder()
//            .setTargetRotation(rotation.toInt())
//            .setTargetAspectRatio(screenAspectRatio)
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()

        imageAnalysis.setAnalyzer(executor, imageAnalyzer)
        return imageAnalysis
    }

    private fun createImageAnalyzer(): ImageAnalysis.Analyzer {
        return ImageAnalysis.Analyzer {
            isAnalyzing = true
            analyzer.analyze(it)
        }
    }

    private fun initPreview(screenAspectRatio: Int): Preview {

        val preview: Preview = Preview.Builder()
            //.setTargetResolution(Size(840, 840))
          //  .setTargetAspectRatio(screenAspectRatio)
          //  .setTargetRotation(displayLayout.rotation.toInt())
            .build()
        preview.setSurfaceProvider(previewView.surfaceProvider)
        return preview
    }

    fun unbindAll() {
        cameraProviderFuture?.get()?.unbindAll()
    }


    private fun aspectRatio(width: Int, height: Int): Int {
        val previewRatio = width.coerceAtLeast(height).toDouble() / width.coerceAtMost(height)
        if (kotlin.math.abs(previewRatio - RATIO_4_3_VALUE) <= kotlin.math.abs(previewRatio - RATIO_16_9_VALUE)) {
            return AspectRatio.RATIO_4_3
        }
        return AspectRatio.RATIO_16_9
    }
}

还有我的分析仪

internal class GMSMLKitAnalyzer(
    private val onFoundQR: (String) -> Unit,
    private val onNotFoundQR: () -> Unit
) :
    ImageAnalysis.Analyzer {

    private val options = BarcodeScannerOptions.Builder()
        .setBarcodeFormats(Barcode.FORMAT_QR_CODE).build()

    @SuppressLint("UnsafeExperimentalUsageError")
    override fun analyze(imageProxy: ImageProxy) {
        imageProxy.image?.let { mediaImage ->
            val image = InputImage.fromMediaImage(mediaImage, imageProxy.imageInfo.rotationDegrees)
            val scanner = BarcodeScanning.getClient(options)
            CoroutineScope(Dispatchers.Main).launch {
                val result = scanner.process(image).await()
                result.result?.let { barcodes ->
                    barcodes.find { it.rawValue != null }?.rawValue?.let {
                        onFoundQR(it)
                    } ?: run { onNotFoundQR() }
                }
                imageProxy.close()
            }
        } ?: imageProxy.close()

    }
}

注释掉的行是我尝试添加但没有帮助的内容,有些甚至在其他(曾经工作的)设备上引起了问题。

我不确定我是否配置错误,所以我想要任何可以帮助我找到解决方案的建议。

谢谢

附:这是我的第一篇文章,如果我做错了什么或遗漏了什么,请指教。

【问题讨论】:

    标签: android android-camerax google-mlkit


    【解决方案1】:

    BarcodeScanning 不适用于运行 camera-camera2:1.0.0-beta08 或更高版本的某些设备。您可以使用较早版本的 camera-camera2 来绕过此问题。例如:

    见:https://developers.google.com/ml-kit/known-issues 我们正在为下一个 SDK 版本在 MLKit 中进行内部修复。

    【讨论】:

    • 感谢您澄清这个@chenxi。您是否有大概的修复发布时间?所以我可以看看我是应该回滚还是等待新的。
    • 我们计划在 2020 年 12 月中旬发布新的 sdk。请注意,这是计划中的,但尚未落地:)
    • 嗨!仅供参考,我已更改为 beta07 并且对于几个设备(曾经可以工作)仍然存在相同的问题。我想我将不得不等待你提到的新 sdk。
    【解决方案2】:

    16.1.1

    上更新您的 ML 条码扫描插件

    此问题已在 'com.google.mlkit:barcode-scanning:16.1.1' 中修复

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-11
      • 2021-01-01
      • 2014-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      相关资源
      最近更新 更多