Android 收到相机许可后未显示预览

Android 收到相机许可后未显示预览,android,firebase,android-camerax,Android,Firebase,Android Camerax,我正在尝试读取二维码,当我将此逻辑加载到与我授予权限的运行不同的运行时,一切正常 但是,如果我想在权限运行期间执行此操作,则不会加载预览。 我发现一些SO帖子说,在收到许可后加载ui,但这也不起作用 private fun startCamera() { val previewConfig = PreviewConfig.Builder() // We want to show input from back camera of the device .s

我正在尝试读取二维码,当我将此逻辑加载到与我授予权限的运行不同的运行时,一切正常

但是,如果我想在权限运行期间执行此操作,则不会加载预览。 我发现一些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()
    }
private fun startCamera(){
val previewConfig=previewConfig.Builder()
//我们想显示设备背面摄像头的输入
.setLensFacing(CameraX.LensFacing.BACK).build()
val preview=预览(预览配置)
preview.SetonPreviewOutUpdateListener{PreviewOut->
textureView.surfaceTexture=previewOutput.surfaceTexture
}
val imageAnalysisConfig=imageAnalysisConfig.Builder().build()
val imageAnalysis=imageAnalysis(imageAnalysisConfig)
val qrCodeAnalyzer=qrCodeAnalyzer{qrCodes->
qrCodes.forEach{
如果(!TextUtils.isEmpty(it.rawValue)){
previewAction?.onQRCodeResult(it.rawValue)
}
}
}
上下文?让我们来看看{
imageAnalysis.setAnalyzer(it.getExecutor(),qrCodeAnalyzer)
}
//我们需要绑定preview和imageAnalysis用例
CameraX.bindToLifecycle(作为生命周期所有者、预览、图像分析)
}
重写onRequestPermissionsResult(请求代码:Int,权限:Array,GrantResult:IntArray){
super.onRequestPermissionsResult(请求代码、权限、GrantResult)
startCamera()
}

我缺少什么?

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

fragment\u 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>

CameraFragment.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()
            }
        }
    }
}
package com.hardik.demos
导入android.Manifest
导入android.content.pm.PackageManager
导入android.graphics.Matrix
导入android.os.Bundle
导入android.util.DisplayMetrics
导入android.util.Rational
导入android.util.Size
导入android.view*
导入android.widget.Toast
导入androidx.camera.core*
导入androidx.core.app.ActivityCompat
导入androidx.core.content.ContextCompat
导入androidx.fragment.app.fragment
导入kotlinx.android.synthetic.main.fragment\u摄像头*
导入java.io.xml文件
/**
*一个简单的[片段]子类。
*/
私人const val请求\代码\摄像头\权限=101
private val PERMISSION_LIST=arrayOf(Manifest.PERMISSION.CAMERA)
类CameraFragment:Fragment(){
私有lateinit var cameraPreview:TextureView
覆盖创建视图(
充气器:布局充气器,容器:视图组?,
savedInstanceState:捆绑?
):查看{
//为该碎片膨胀布局
返回充气机。充气(R.layout.fragment_摄像头,容器,假)
}
覆盖已创建的视图(视图:视图,保存状态:捆绑?){
super.onViewCreated(视图,savedInstanceState)
cameraPreview=view.findViewById(R.id.camera\U预览)
}
重写onResume(){
super.onResume()
initCamera()
}
私人摄像机(){
如果(IsAllPermissionGrated()){
cameraPreview.post{startCamera()}
}否则{
ActivityCompat.requestPermissions(
require(),权限列表,
请求\u代码\u摄像头\u权限
)
}
}
私人娱乐星空(){
cameraPreview.addOnLayoutChangeListener{{{uu,{uu,},{uu,{uu,},{uu,},{uu,{uu,{uu,}->updateCameraBuffer()}
val metrics=DisplayMetrics()。也是{cameraPreview.display.getRealMetrics(it)}
val screenSize=大小(metrics.widthPixels,metrics.heightPixels)
val screenspectratio=Rational(metrics.widthPixels,metrics.heightPixels)
//设置预览配置
val previewConfig=previewConfig.Builder().apply{
设置透镜面(摄像机镜头透镜面前)
setTargetResolution(屏幕大小)
SetTargetSpectratio(屏幕显示)
setTargetRotation(require().windowManager.defaultDisplay.rotation)
setTargetRotation(cameraPreview.display.rotation)
}.build()
val preview=预览(预览配置)
//根据配置更新预览
preview.SetonPreviewOutUpdateListener{
cameraPreview.surfaceTexture=it.surfaceTexture
updateCameraBuffer()
}
//设置相机照片捕获
val imageConfig=ImageCaptureConfig.Builder().apply{
设置透镜面(摄像机镜头透镜面前)
SetTargetSpectratio(屏幕显示)
setTargetRotation(cameraPreview.display.rotation)
setCaptureMode(ImageCapture.CaptureMode.MIN_延迟)
}.build()
val imageCapture=imageCapture(imageConfig)
fab_capture_photo.setOnClickListener{
val imageFile=File(
requireContext().getExternalFilesDir(null),
“${System.currentTimeMillis()}.jpg”
)
imageCapture.takePicture(图像文件,
对象:ImageCapture.OnImageSavedListener{
覆盖已保存的图像(文件:file){
val msg=“照片捕获成功”
Toast.makeText(requireContext(),msg,Toast.LENGTH\u SHORT.show())
}
忽略错误(
imageCaptureError:ImageCapture.imageCaptureError,
消息:String,
原因:可丢弃?
) {
val msg=“照片捕获失败:$message”
Toast.makeText(requireContext(),msg,Toast.LENGTH\u SHORT.show())
}
})
}
CameraX.bindToLifecycle(viewLifecycleOwner、预览、图像捕获)
}
私人娱乐更新{
val矩阵=矩阵()
//查找摄影机中心
瓦尔中心酒店=