Tomar fotos con Kotlin en Android Studio

En esta ocasión aprenderemos a capturar fotos desde la cámara de nuestro dispositivo Android, esto usando el lenguaje Kotlin en Android Studio.

Primeros pasos

Para este ejemplo hemos creado un proyecto vacío en Android Studio, con las siguientes características:

  • Nombre: Kamara
  • Nombre del paquete: com.cdp.kamara
  • Lenguaje: Kotlin
  • SDK mínimo: API 21: Android 5.0 (Lillipop)

Estamos usando el SDK 31 para compilar la aplicación.

Solicitar la función de cámara

Para tomar fotografías con la cámara necesitamos solicitar el permiso en el archivo de manifiesto:

<manifest ... >
        <uses-feature android:name="android.hardware.camera"
                      android:required="true" />
        ...
    </manifest>

Vista

Para la vista agregamos un Button y un ImageView:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnCamara"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:text="Camara"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginStart="5dp"
        android:layout_marginEnd="5dp"
        android:layout_marginBottom="5dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnCamara"
        tools:srcCompat="@tools:sample/avatars"
        android:contentDescription="TODO" />

</androidx.constraintlayout.widget.ConstraintLayout>

Resultado:

Nota: La imagen es solo para representar el elemento ImageView.

Tomar foto

El código kotlin asociado a esta vista se encuentra en el archivo «MainActivity.kt» y es el siguiente:

package com.cdp.kamara

import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

    @RequiresApi(Build.VERSION_CODES.N)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val btnCamara = findViewById<Button>(R.id.btnCamara)

        //Evento al presionar el botón
        btnCamara.setOnClickListener {
            startForResult.launch(Intent(MediaStore.ACTION_IMAGE_CAPTURE))
        }
    }

    //Evento que procesa el resultado de la cámara y envía la vista previa de la foto al ImageView 
    private val startForResult =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
            if (result.resultCode == Activity.RESULT_OK) {
                val intent = result.data
                val imageBitmap = intent?.extras?.get("data") as Bitmap
                val imageView = findViewById<ImageView>(R.id.imageView)
                imageView.setImageBitmap(imageBitmap)
            }
        }
}

Al presionar el botón llama la acción para abrir la cámara, la cual crea el objeto intent e inicia la captura con la cámara.

Después de capturar, Android codifica la foto en el Intent y se entrega al método registerForActivityResult(), lo pasamos como un Bitmap pequeño en la carpeta Extras, en los «data» clave para mostrarlo en el ImageView.

Proyecto en ejecución

En ocasiones la imagen se puede visualizar un poco borrosa, ten en cuenta que esta imagen es una miniatura, para una imagen original requiere un proceso adicional.

Tutorial en vídeo