I am using the starter code for CameraX Api from here
but it is giving following error.
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.googlecamerax, PID: 27995 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:502) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935) Caused by: java.util.concurrent.ExecutionException: androidx.camera.core.InitializationException: java.lang.IllegalArgumentException: Requested zoomRatio 1.0 is not within valid range [1.0 , 0.0] at androidx.concurrent.futures.AbstractResolvableFuture.getDoneValue(AbstractResolvableFuture.java:518) at androidx.concurrent.futures.AbstractResolvableFuture.get(AbstractResolvableFuture.java:475) at androidx.concurrent.futures.CallbackToFutureAdapter$SafeFuture.get(CallbackToFutureAdapter.java:199) at androidx.camera.core.impl.utils.futures.FutureChain.get(FutureChain.java:155) at androidx.camera.core.impl.utils.futures.ChainingListenableFuture.get(ChainingListenableFuture.java:105) at com.example.googlecamerax.MainActivity$startCamera$1.run(MainActivity.kt:58) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7397) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935) Caused by: androidx.camera.core.InitializationException: java.lang.IllegalArgumentException: Requested zoomRatio 1.0 is not within valid range [1.0 , 0.0] at androidx.camera.core.CameraX.lambda$initInternal$7$CameraX(CameraX.java:638) at androidx.camera.core.-$$Lambda$CameraX$PC4SOFGjuqUVT4bexY644vLmWFE.run(Unknown Source:8) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:919) Caused by: java.lang.IllegalArgumentException: Requested zoomRatio 1.0 is not within valid range [1.0 , 0.0] at androidx.camera.camera2.internal.ZoomStateImpl.setZoomRatio(ZoomStateImpl.java:40) at androidx.camera.camera2.internal.ZoomControl.(ZoomControl.java:98) at androidx.camera.camera2.internal.Camera2CameraControl.(Camera2CameraControl.java:125) at androidx.camera.camera2.internal.Camera2CameraImpl.(Camera2CameraImpl.java:200) at androidx.camera.camera2.internal.Camera2CameraFactory.getCamera(Camera2CameraFactory.java:61) at androidx.camera.core.impl.CameraRepository.init(CameraRepository.java:64) at androidx.camera.core.CameraX.lambda$initInternal$7$CameraX(CameraX.java:632)
Here is my code
typealias LumaListener = (luma: Double) -> Unit
class MainActivity : AppCompatActivity() {
private var imageCapture: ImageCapture? = null
private lateinit var outputDirectory: File
private lateinit var cameraExecutor: ExecutorService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Request camera permissions
if (allPermissionsGranted()) {
startCamera()
} else {
ActivityCompat.requestPermissions(
this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS
)
}
// Set up the listener for take photo button
camera_capture_button.setOnClickListener { takePhoto() }
outputDirectory = getOutputDirectory()
cameraExecutor = Executors.newSingleThreadExecutor()
}
private fun takePhoto() {}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener(Runnable {
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
val preview = Preview.Builder()
.build()
.also {
it.setSurfaceProvider(viewFinder.createSurfaceProvider())
}
// 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(
this, cameraSelector, preview)
} catch(exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(this))
}
private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
ContextCompat.checkSelfPermission(
baseContext, it
) == PackageManager.PERMISSION_GRANTED
}
private fun getOutputDirectory(): File {
val mediaDir = externalMediaDirs.firstOrNull()?.let {
File(it, resources.getString(R.string.app_name)).apply { mkdirs() }
}
return if (mediaDir != null && mediaDir.exists())
mediaDir else filesDir
}
override fun onDestroy() {
super.onDestroy()
cameraExecutor.shutdown()
}
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<String>, grantResults:
IntArray
) {
if (requestCode == REQUEST_CODE_PERMISSIONS) {
if (allPermissionsGranted()) {
startCamera()
} else {
Toast.makeText(
this,
"Permissions not granted by the user.",
Toast.LENGTH_SHORT
).show()
finish()
}
}
}
companion object {
private const val TAG = "CameraXBasic"
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private const val REQUEST_CODE_PERMISSIONS = 10
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA)
}
}
It is giving error on this line in startCamera() function
var cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
This is a bug in some OEM camera implementations.
Google added a workaround in CameraX starting from
1.0.0-rc04
or1.1.0-alpha03
. Just update to one of those versions or above.You can find more info here: https://issuetracker.google.com/issues/170578169 and the added workaround here