szaske
szaske

Reputation: 2027

Why doesn't the ACTION_IMAGE_CAPTURE Intent return the URI for the saved image?

I'm trying to follow the logic in the Android code here, which explains how to accomplish a "Get Image from Camera" intent. I'm hoping one of you smart people of SO can help me understand WHY Google developed the intent this way. First the function that kicks off the Intent:

val REQUEST_TAKE_PHOTO = 1

private fun dispatchTakePictureIntent() {
    Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
        // Ensure that there's a camera activity to handle the intent
        takePictureIntent.resolveActivity(packageManager)?.also {
            // Create the File where the photo should go
            val photoFile: File? = try {
                createImageFile()
            } catch (ex: IOException) {
                // Error occurred while creating the File
                ...
                null
            }
            // Continue only if the File was successfully created
            photoFile?.also {
                val photoURI: Uri = FileProvider.getUriForFile(
                        this,
                        "com.example.android.fileprovider",
                        it
                )
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO)
            }
        }
    }
}

Notice that this code refers to another function, one that creates a file and filename:

var currentPhotoPath: String

@Throws(IOException::class)
private fun createImageFile(): File {
    // Create an image file name
    val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
    val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
    return File.createTempFile(
            "JPEG_${timeStamp}_", /* prefix */
            ".jpg", /* suffix */
            storageDir /* directory */
    ).apply {
        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = absolutePath
    }
}

Finally if you have an intent and have done Android development before you know you need a OnActivityResult function, so here's one:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        val imageBitmap = data.extras.get("data") as Bitmap
        imageView.setImageBitmap(imageBitmap)
    }
}

So if you run this code it will fail which is the genesis for my question and I'm hoping someone, perhaps someone on the Android dev team can explain to me why this popular intent returns null data.

The apparent logic flow for this is the following:

  1. Kick off the ACTION_IMAGE_CAPTURE intent
  2. Create a file to save the image into
  3. Save that file URI to your own variable, because you'll need it later
  4. Add the file name as an extra to the intent
  5. Start the intent
  6. Intent callback OnActivityResult returns but has NULL data passed back with it.
  7. Remember that URI you saved off earlier, just use that as your return data.

It just seems strange that the callback data is null and I found it really confusing. Is there another intent I'm should be using? Why isn't the intent returning me some useful data, like the URI for the file it just created?

Upvotes: 1

Views: 627

Answers (1)

Ramindu Weeraman
Ramindu Weeraman

Reputation: 354

If you specified MediaStore.EXTRA_OUTPUT, the image taken will be written to that path, and no data will given to onActivityResult. You can read the image from what you specified.

Also pls check your permissions.

Upvotes: 2

Related Questions