0

我正在尝试读取 QR 码,当我在与我授予权限的运行不同的运行中加载此逻辑时,一切都很好

但是,当我想在权限运行期间执行此操作时,预览不会加载。我发现一些 SO 帖子说在您获得许可后加载 ui,但这也不起作用。

private fun startCamera() {
    val previewConfig = PreviewConfig.Builder()
        // We want to show input from back camera of the device
        .setLensFacing(CameraX.LensFacing.BACK).build()

    val preview = Preview(previewConfig)

    preview.setOnPreviewOutputUpdateListener { previewOutput ->
        textureView.surfaceTexture = previewOutput.surfaceTexture
    }

    val imageAnalysisConfig = ImageAnalysisConfig.Builder().build()
    val imageAnalysis = ImageAnalysis(imageAnalysisConfig)

    val qrCodeAnalyzer = QRCodeAnalyzer { qrCodes ->
        qrCodes.forEach {
            if (!TextUtils.isEmpty(it.rawValue)) {
                previewAction?.onQRCodeResult(it.rawValue)
            }
        }
    }

    context?.let {
        imageAnalysis.setAnalyzer(it.getExecutor(), qrCodeAnalyzer)
    }

    // We need to bind preview and imageAnalysis use cases
    CameraX.bindToLifecycle(this as LifecycleOwner, preview, imageAnalysis)
}

  override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        startCamera()
    }

我错过了什么?

4

1 回答 1

0

下面是我的工作代码,您可以参考

fragment_camera.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <TextureView
            android:id="@+id/camera_preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab_capture_photo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="16dp"
            android:src="@drawable/ic_camera"
            app:fabSize="auto"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:tint="@android:color/white" />

</androidx.constraintlayout.widget.ConstraintLayout>

相机片段.kt

package com.hardik.demos


import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Matrix
import android.os.Bundle
import android.util.DisplayMetrics
import android.util.Rational
import android.util.Size
import android.view.*
import android.widget.Toast
import androidx.camera.core.*
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_camera.*
import java.io.File

/**
 * A simple [Fragment] subclass.
 */
private const val REQUEST_CODE_CAMERA_PERMISSION = 101
private val PERMISSION_LIST = arrayOf(Manifest.permission.CAMERA)

class CameraFragment : Fragment() {


    private lateinit var cameraPreview: TextureView

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_camera, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        cameraPreview = view.findViewById(R.id.camera_preview)
    }

    override fun onResume() {
        super.onResume()
        initCamera()
    }

    private fun initCamera() {
        if (isAllPermissionGranted()) {
            cameraPreview.post { startCamera() }
        } else {
            ActivityCompat.requestPermissions(
                requireActivity(), PERMISSION_LIST,
                REQUEST_CODE_CAMERA_PERMISSION
            )
        }
    }

    private fun startCamera() {
        cameraPreview.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ -> updateCameraBuffer() }

        val metrics = DisplayMetrics().also { cameraPreview.display.getRealMetrics(it) }
        val screenSize = Size(metrics.widthPixels, metrics.heightPixels)
        val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)

        //Setup preview config
        val previewConfig = PreviewConfig.Builder().apply {
            setLensFacing(CameraX.LensFacing.FRONT)
            setTargetResolution(screenSize)
            setTargetAspectRatio(screenAspectRatio)
            setTargetRotation(requireActivity().windowManager.defaultDisplay.rotation)
            setTargetRotation(cameraPreview.display.rotation)
        }.build()

        val preview = Preview(previewConfig)

        //Update Preview as per config
        preview.setOnPreviewOutputUpdateListener {
            cameraPreview.surfaceTexture = it.surfaceTexture
            updateCameraBuffer()
        }


        //Setup camera photo capture
        val imageConfig = ImageCaptureConfig.Builder().apply {
            setLensFacing(CameraX.LensFacing.FRONT)
            setTargetAspectRatio(screenAspectRatio)
            setTargetRotation(cameraPreview.display.rotation)
            setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
        }.build()

        val imageCapture = ImageCapture(imageConfig)

        fab_capture_photo.setOnClickListener {
            val imageFile = File(
                requireContext().getExternalFilesDir(null),
                "${System.currentTimeMillis()}.jpg"
            )
            imageCapture.takePicture(imageFile,
                object : ImageCapture.OnImageSavedListener {
                    override fun onImageSaved(file: File) {
                        val msg = "Photo capture Success"
                        Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show()
                    }

                    override fun onError(
                        imageCaptureError: ImageCapture.ImageCaptureError,
                        message: String,
                        cause: Throwable?
                    ) {
                        val msg = "Photo capture failed: $message"
                        Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show()
                    }

                })
        }

        CameraX.bindToLifecycle(viewLifecycleOwner, preview, imageCapture)
    }

    private fun updateCameraBuffer() {
        val matrix = Matrix()

        //find camera center
        val centerX = cameraPreview.width / 2f
        val centerY = cameraPreview.height / 2f

        //Correct orientation
        val rotateAt = when (cameraPreview.display.rotation) {
            Surface.ROTATION_0 -> 0
            Surface.ROTATION_90 -> 90
            Surface.ROTATION_180 -> 180
            Surface.ROTATION_270 -> 270
            else -> return
        }
        matrix.postRotate(-rotateAt.toFloat(), centerX, centerY)
        cameraPreview.setTransform(matrix)
    }

    private fun isAllPermissionGranted() = PERMISSION_LIST.all {
        ContextCompat.checkSelfPermission(requireContext(), it) == PackageManager.PERMISSION_GRANTED
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        if (requestCode == REQUEST_CODE_CAMERA_PERMISSION) {
            if (isAllPermissionGranted()) {
                initCamera()
            } else {
                Toast.makeText(
                    requireContext(),
                    "Permissions not granted by the user.",
                    Toast.LENGTH_LONG
                ).show()
            }
        }
    }
}

让我知道寻求帮助

于 2019-11-15T09:15:25.650 回答