Mason
Mason

Reputation: 51

Cannot save captured image to external media directory using CameraX

I was following this code labs example Link on how to use CameraX API on Android, however when I tried to capture and save the image to the external media directory that is created in Oncreate method in the main activity I get an error message saying: Cannot save capture result to specified location

Here is the method that creates the directory, which is called in Oncreate method:

    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())
            { Log.i(TAG, mediaDir.path); mediaDir } else {  filesDir }
        }

from what I read in Android documentation externalMediaDirs creates a folder in external storage, and although my phone doesn't have external storage, the folder was successfully created at this path: /storage/emulated/0/Android/media/com.example.camerax/cameraX

then this method gets called when the take picture image button gets clicked:

private fun takePhoto() {
        // Get a stable reference of the modifiable image capture use case
        val imageCapture = imageCapture ?: return

        // Create time-stamped output file to hold the image
        val photoFile = File(
            outputDirectory,
            SimpleDateFormat(FILENAME_FORMAT, Locale.US
            ).format(System.currentTimeMillis()) + ".jpg")


        // Create output options object which contains file + metadata
        val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()

        // Set up image capture listener, which is triggered after photo has
        // been taken
        imageCapture.takePicture(
            outputOptions,
            ContextCompat.getMainExecutor(this),
            object : ImageCapture.OnImageSavedCallback {
                override fun onError(exc: ImageCaptureException) {
                    Log.e(TAG, "Photo capture failed: ${exc.message}", exc)
                }

                override fun onImageSaved(output: ImageCapture.OutputFileResults) {
                    val savedUri = Uri.fromFile(photoFile)
                    val msg = "Photo capture succeeded: $savedUri"
                    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
                    Log.d(TAG, msg)
                }
            })


    }

However, when I click the button to capture and save the image, I get this error message: ImageCaptureException: "Cannot save capture result to specified location"

What I tried:

I tried to create a folder that is local to the App and save the image there, and it worked fine, I used this method:

private fun takePhoto() {
.
.
.
 folder: File = File(getFilesDir(), "testFolder");
            if (!file.exists()) {
                file.mkdir();
            }
testImage = File(folder, "test.jpg");

val outputOptions = ImageCapture.OutputFileOptions.Builder(testImage).build()
.
.
.
.
.
.



Im not sure what could be the problem, any help is appreciated.

Update: Apparently the problem is due to a bug in CameraX API CameraX 1.0.0-beta09 along with camera-extension 1.0.0-alpha16. when using CameraX 1.0.0-beta08 along with camera-extension 1.0.0-alpha15 its working fine.

Upvotes: 4

Views: 3762

Answers (1)

Saurabh Thorat
Saurabh Thorat

Reputation: 20674

This is a bug in CameraX 1.0.0-beta09. It's been patched and might be available in the next release.

It crashes because the file you're trying to save it to, isn't actually created. As a workaround use File.createTempFile(), which creates an empty file in the directory.

val photoFile = File.createTempFile(
    SimpleDateFormat(FILENAME_FORMAT, Locale.US).format(System.currentTimeMillis()),
    ".jpg",
    outputDirectory
)

Upvotes: 6

Related Questions