我的项目中有相机可以用语音拍摄视频并将其保存在设备文件夹中。我正在使用 Dexter 库进行权限检查。相机在高于 api 32 的设备上打开。但低于 api 33 则无法工作。我在调试模式下检查了这一点,无论它是否被授予,它在 Dexter 代码中都不起作用。这是怎么回事?
AndroidManifest.xml
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
<uses-feature android:name="android.hardware.camera.flash" android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
片段.kt
private fun initCamera() {
cameraExecutor = Executors.newSingleThreadExecutor()
requestCameraPermission()
}
private fun requestCameraPermission() {
Dexter.withContext(requireContext())
.withPermissions(
Manifest.permission.RECORD_AUDIO,
Manifest.permission.CAMERA
).withListener(object : MultiplePermissionsListener {
override fun onPermissionsChecked(p0: MultiplePermissionsReport?) {
p0?.let {
if (it.areAllPermissionsGranted()) {
startCamera(CameraSelector.DEFAULT_BACK_CAMERA)
}
}
}
override fun onPermissionRationaleShouldBeShown(
p0: MutableList<PermissionRequest>?,
p1: PermissionToken?
) {
p1?.continuePermissionRequest()
}
}).check()
}
private fun startCamera(cameraSelector: CameraSelector) {
val cameraProviderFuture = ProcessCameraProvider.getInstance(requireContext())
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
cameraProviderFuture.addListener({
// Preview
val preview = Preview.Builder()
.build()
.also {
binding.previewViewTalkerDuelCreateNewDuelTakeVideo.implementationMode =
PreviewView.ImplementationMode.COMPATIBLE
it.setSurfaceProvider(
binding.previewViewTalkerDuelCreateNewDuelTakeVideo.surfaceProvider
)
}
val recorder = Recorder.Builder()
.setQualitySelector(
QualitySelector.from(
Quality.HIGHEST,
FallbackStrategy.higherQualityOrLowerThan(Quality.SD)
)
)
.build()
videoCapture = VideoCapture.withOutput(recorder)
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, cameraSelector, preview, videoCapture
)
} catch (exc: Exception) {
exc.printStackTrace()
}
}, ContextCompat.getMainExecutor(requireContext()))
}
德克斯特版本:
implementation 'com.karumi:dexter:6.2.3'
我检查了你的代码,下面的代码对我来说工作正常:
package com.example.viewbinding
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import com.example.viewbinding.databinding.ActivitySecondBinding
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
class SecondActivity : AppCompatActivity() {
private lateinit var binding: ActivitySecondBinding
private lateinit var cameraExecutor: ExecutorService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
binding = ActivitySecondBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
cameraExecutor = Executors.newSingleThreadExecutor()
requestCameraPermission()
}
private fun requestCameraPermission() {
Dexter.withContext(this)
.withPermissions(
android.Manifest.permission.CAMERA,
android.Manifest.permission.RECORD_AUDIO
).withListener(object : MultiplePermissionsListener {
override fun onPermissionsChecked(p0: MultiplePermissionsReport?) {
p0?.let {
if (it.areAllPermissionsGranted()) {
Log.wtf("Second Activity", "All permission granted")
startCamera(CameraSelector.DEFAULT_BACK_CAMERA)
}
}
}
override fun onPermissionRationaleShouldBeShown(
p0: MutableList<PermissionRequest>?,
p1: PermissionToken?
) {
p1?.continuePermissionRequest()
}
}).check()
}
private fun startCamera(cameraSelector: CameraSelector) {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
cameraProviderFuture.addListener({
// Preview
val preview = Preview.Builder().build()
.also {
it.setSurfaceProvider(binding.viewFinder.surfaceProvider)
}
// val recorder = Recorder.Builder()
// .setQualitySelector(
// QualitySelector.from(
// LocationRequestCompat.Quality.HIGHEST,
// FallbackStrategy.higherQualityOrLowerThan(LocationRequestCompat.Quality.SD)
// )
// )
// .build()
//
// videoCapture = VideoCapture.withOutput(recorder)
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, cameraSelector, preview
)
} catch (exc: Exception) {
exc.printStackTrace()
}
}, ContextCompat.getMainExecutor(this))
}
}
我建议您将日志放在您的代码无法正常工作的地方。我认为您的权限已被授予。可能是这个不起作用
binding.previewViewTalkerDuelCreateNewDuelTakeVideo.implementationMode =
PreviewView.ImplementationMode.COMPATIBLE
it.setSurfaceProvider(
binding.previewViewTalkerDuelCreateNewDuelTakeVideo.surfaceProvider
)
作为参考,您可以浏览他们的官方代码实验室
我为低于 33 的权限 api 添加了这些代码。相机现在可以工作了。所以我只是添加了和我有同样错误的答案。
private fun checkPermissions(permissions: Array<String>): Boolean {
for (permission in permissions) {
if (ContextCompat.checkSelfPermission(requireContext(), permission) != PackageManager.PERMISSION_GRANTED) {
return false
}
}
return true
}
private val requestMultiplePermissions =registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions())
{
permissions ->
permissions.entries.forEach {
it
}
if (permissions[RECORD_AUDIO] == true && permissions[CAMERA] == true) {
startCamera(CameraSelector.DEFAULT_BACK_CAMERA)
}
}