android - 无法访问类 'com.google.common.util.concurrent.ListenableFuture' 。检查模块类路径是否缺少或冲突的依赖项

标签 android flutter kotlin dart android-camerax

我正在尝试将 CameraX 集成到我的 flutter 应用程序中,但收到错误消息,提示 Cannot access class 'com.google.common.util.concurrent.ListenableFuture'。检查模块类路径是否缺少或冲突的依赖项

enter image description here

错误来自下面一行

val cameraProviderFuture = ProcessCameraProvider.getInstance(context)

下面是我的原生 View

class CealScanQrView(val context: Context, id: Int, creationParams: Map<String?, Any?>?) :
    PlatformView {

    private var mCameraProvider: ProcessCameraProvider? = null
    private var preview: PreviewView
    private var linearLayout: LinearLayout = LinearLayout(context)


    private lateinit var cameraExecutor: ExecutorService
    private lateinit var options: BarcodeScannerOptions
    private lateinit var scanner: BarcodeScanner

    private var analysisUseCase: ImageAnalysis = ImageAnalysis.Builder()
        .build()

    companion object {
        private val REQUIRED_PERMISSIONS = mutableListOf(Manifest.permission.CAMERA).toTypedArray()
    }

    init {

        val linearLayoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )

        linearLayout.layoutParams = linearLayoutParams
        linearLayout.orientation = LinearLayout.VERTICAL
        preview = PreviewView(context)
        preview.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )

        linearLayout.addView(preview)
        setUpCamera()
    }

    private fun setUpCamera(){
        if (allPermissionsGranted()) {
            startCamera()
        }

        cameraExecutor = Executors.newSingleThreadExecutor()

        options = BarcodeScannerOptions.Builder()
            .setBarcodeFormats(
                Barcode.FORMAT_QR_CODE)
            .build()
        scanner = BarcodeScanning.getClient(options)

        analysisUseCase.setAnalyzer(
            // newSingleThreadExecutor() will let us perform analysis on a single worker thread
            Executors.newSingleThreadExecutor()
        ) { imageProxy ->
            processImageProxy(scanner, imageProxy)
        }
    }

    override fun getView(): View {
        return linearLayout
    }

    override fun dispose() {
        cameraExecutor.shutdown()
    }

    @SuppressLint("UnsafeOptInUsageError")
    private fun processImageProxy(
        barcodeScanner: BarcodeScanner,
        imageProxy: ImageProxy
    ) {
        imageProxy.image?.let { image ->
            val inputImage =
                InputImage.fromMediaImage(
                    image,
                    imageProxy.imageInfo.rotationDegrees
                )

            barcodeScanner.process(inputImage)
                .addOnSuccessListener { barcodeList ->
                    val barcode = barcodeList.getOrNull(0)

                    // `rawValue` is the decoded value of the barcode
                    barcode?.rawValue?.let { value ->

                        mCameraProvider?.unbindAll()
                    }
                }
                .addOnFailureListener {
                    // This failure will happen if the barcode scanning model
                    // fails to download from Google Play Services
                }
                .addOnCompleteListener {
                    // When the image is from CameraX analysis use case, must
                    // call image.close() on received images when finished
                    // using them. Otherwise, new images may not be received
                    // or the camera may stall.
                    imageProxy.image?.close()
                    imageProxy.close()
                }
        }
    }

    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
    }

    private fun startCamera() {
        val cameraProviderFuture = ProcessCameraProvider.getInstance(context)

        cameraProviderFuture.addListener({
            // Used to bind the lifecycle of cameras to the lifecycle owner
            val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
            mCameraProvider = cameraProvider
            // Preview
            val surfacePreview = Preview.Builder()
                .build()
                .also {
                    it.setSurfaceProvider(preview.surfaceProvider)
                }

            // Select back camera as a default
            val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

            try {
                // Unbind use cases before rebinding
                cameraProvider.unbindAll()

                // Bind use cases to camera
                cameraProvider.bindToLifecycle(
                    (context as FlutterActivity),
                    cameraSelector,
                    surfacePreview,
                    analysisUseCase,
                )
            } catch (exc: Exception) {
                // Do nothing on exception
            }
        }, ContextCompat.getMainExecutor(context))
    }

}

class CealScanQrViewFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
    override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
        val creationParams = args as Map<String?, Any?>?
        return CealScanQrView(context, viewId, creationParams)
    }
}

最佳答案

将此行添加到您的应用 build.gradle 依赖项中:

implementation 'com.google.guava:guava:29.0-android'

关于android - 无法访问类 'com.google.common.util.concurrent.ListenableFuture' 。检查模块类路径是否缺少或冲突的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74650296/

相关文章:

android - Firebase 推送通知(当我启动应用程序时,服务不会从 list 中调用)

Android:如何为ListView排序数据?

flutter - 无状态小部件列表的常量值无效

flutter - 在 Flutter 后台上传

Kotlin 关于 @ 符号和返回后缀的澄清

android - 如何避免将FragmentX绑定(bind)到Fragment

android - 使用-sdk :minSdkVersion 16 cannot be smaller than version 23 declared in library

java - Android - 架构决策

flutter - 如何用flutter实现拖拽

android - 如何处理来自 ContentResolver.applyBatch 的 "SQLiteException: null"?