为什么我的 CameraX CameraView 显示黑屏?

Jer*_*emy 0 camera android kotlin android-camerax

我一直在为我的应用程序实现 CameraView,几周前它可以正常工作,但现在它只是显示黑屏,这意味着不显示预览。结果,似乎正在录制的视频也没有被保存。

有人可以纠正我的代码吗?

显现:

<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)

构建.gradle(应用程序)

 def camerax_version = "1.0.0-beta07"
    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-alpha14"
Run Code Online (Sandbox Code Playgroud)

XML

<androidx.camera.view.CameraView
        android:id="@+id/CameraView_cameraPreview"
        android:layout_width="match_parent"
        android:layout_height="500dp"
        app:captureMode="mixed"
        app:flash="auto"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.4"
        app:lensFacing="back"
        app:pinchToZoomEnabled="true"
        app:scaleType="fitCenter" />

**p.s: I have implemented this button in build.gradle**
<com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/Button_cameraRecord"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/camera_record_vector"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/CameraView_cameraPreview"
        app:layout_constraintVertical_bias="0.5" />
Run Code Online (Sandbox Code Playgroud)

Kotlin 活动

package com.example.iambeta.camera

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.os.SystemClock
import android.util.Log
import android.view.View
import android.widget.SeekBar
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.VideoCapture
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.iambeta.R
import com.example.iambeta.storage.UploadActivity
import kotlinx.android.synthetic.main.activity_camera.*
import java.io.File

//variables for requesting permission
private const val REQUEST_CODE_PERMISSION = 101
var CAMERA_PERMISSION = Manifest.permission.CAMERA
var RECORD_AUDIO_PERMISSION = Manifest.permission.RECORD_AUDIO
private val REQUIRED_PERMISSION = arrayOf(CAMERA_PERMISSION, RECORD_AUDIO_PERMISSION)
val TAG = Camera::class.java.simpleName

class Camera : AppCompatActivity() {

    //declaring variables for camera
    private var recordingStatus: recordingState? = null

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_camera)

        //initializing variables for camera
        recordingStatus = recordingState.NOTRECORDING

        //if record button is clicked
        Button_cameraRecord.setOnClickListener{
            if(recordingStatus == recordingState.NOTRECORDING) {
                recordingStatus = recordingState.RECORDING
                startRecord()
            }else if(recordingStatus == recordingState.RECORDING){
                recordingStatus = recordingState.NOTRECORDING
                stopRecord()
            }
        }

    }

    //start recording
    fun startRecord(){
        //variable for storing the video/recording
        val fileStorage = "${System.currentTimeMillis()}.mp4"

        CameraView_cameraPreview.startRecording(File(externalMediaDirs.first(), fileStorage), ContextCompat.getMainExecutor(this), object: VideoCapture.OnVideoSavedCallback {
            override fun onVideoSaved(file: File) {
                Log.d(TAG, "onVideoSaved $fileStorage")
            }

            override fun onError(videoCaptureError: Int, message: String, cause: Throwable?) {
                Toast.makeText(applicationContext, "Recording Failed", Toast.LENGTH_SHORT).show()
                Log.e(TAG, "onError $videoCaptureError $message")
            }
        })
    }

    //stop recording
    fun stopRecord(){
        CameraView_cameraPreview.stopRecording()
        Toast.makeText(this, "Saved to /internalstorage/Android/media/...", Toast.LENGTH_SHORT).show()
        Log.i(TAG, "Video File Stopped")
    }

    //returns the result of requesting permission (i.e. failed obtaining permission)
    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_CODE_PERMISSION) {
            if (allPermissionsGranted()) {
                openCamera()
            } else {
                Toast.makeText(this, "Permissions not granted by the user.", Toast.LENGTH_SHORT)
                    .show()
                finish()
            }
        }
    }

    //checking if all permissions are granted
    private fun allPermissionsGranted(): Boolean {
        for (permission in REQUIRED_PERMISSION) {
            if (ContextCompat.checkSelfPermission(
                    this,
                    permission
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                return false
            }
        }
        return true
    }

    //starting camera
    private fun openCamera(){
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            CameraView_cameraPreview.bindToLifecycle(this)
        }
    }

    //Enum class to see if the record button is recording or not
    enum class recordingState{
        RECORDING, NOTRECORDING
    }

    override fun onStart() {
        super.onStart()
        //check if all permission has been give, else request permission
        if(allPermissionsGranted()){
            openCamera()
        }else{
            ActivityCompat.requestPermissions(this, REQUIRED_PERMISSION, REQUEST_CODE_PERMISSION)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jer*_*emy 6

更新:我已使用以下解决方案修复了此问题

在我的函数中,openCamera()我这样做是为了如果我正在检查的权限不等于授予的权限,它将绑定预览。但是,我可以将其设置为相等,以便一旦被授予,它就可以绑定。因此,代码不是这样的:

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            CameraView_cameraPreview.bindToLifecycle(this)
        }

Run Code Online (Sandbox Code Playgroud)

它应该看起来像:

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            CameraView_cameraPreview.bindToLifecycle(this)
        }

Run Code Online (Sandbox Code Playgroud)