Xamarin Forms: Funcionalidades Nativas - La Cámara

En este artículo, aprenderás a integrar la cámara en una aplicación Xamarin Forms para Android, accediendo a las funcionalidades nativas del sistema operativo. Exploraremos cómo tomar una foto y mostrarla en la interfaz de usuario, desarrollando paso a paso un proyecto que se puede reproducir en Visual Studio.

 

¿Por Qué Integrar la Cámara en Android?

La cámara es uno de los componentes más utilizados en aplicaciones móviles. Desde capturar una imagen para perfiles hasta realizar un escaneo de documentos, su integración es esencial en una variedad de aplicaciones. Xamarin Forms nos permite acceder a la cámara nativa de Android mediante la implementación de funcionalidades específicas del sistema operativo.

 

Requisitos Previos

Antes de comenzar, asegúrate de cumplir con los siguientes requisitos:

  • Visual Studio con la carga de trabajo de Xamarin instalada.
  • Un dispositivo físico o un emulador con soporte de cámara.
  • Conocimientos básicos de Xamarin Forms y C#.

 

Configuración del Proyecto en Visual Studio

  1. Abre Visual Studio.
  2. Selecciona Crear un nuevo proyecto y escoge Aplicación móvil (Xamarin.Forms).
  3. Asigna un nombre al proyecto, por ejemplo, CameraApp.
  4. Elige la plantilla en blanco y selecciona Android como una de las plataformas de destino.

 

Implementación de la Cámara en Android

Vamos a usar la API de cámara nativa de Android para capturar una imagen. Para hacerlo, utilizaremos DependencyService, que nos permite acceder a funcionalidades nativas desde el código compartido en Xamarin Forms.

Paso 1. Crear la Interfaz para la Cámara en el Proyecto Compartido

Primero, definimos una interfaz en el proyecto compartido que describa la funcionalidad de la cámara, es decir, capturar una foto.

  1. En el proyecto compartido, crea una carpeta llamada Services.
  2. Dentro de esa carpeta, crea un archivo llamado ICameraService.cs con el siguiente contenido:
namespace CameraApp.Services
{
    // Interfaz que define la funcionalidad de capturar una foto
    public interface ICameraService
    {
        // Método que abrirá la cámara y devolverá la ruta de la imagen capturada
        Task<string> CapturePhotoAsync();
    }
}
  • Interfaz ICameraService: Esta interfaz define el contrato para cualquier clase que implemente el servicio de la cámara. El método CapturePhotoAsync será responsable de abrir la cámara y devolver la ruta de la imagen capturada.

Paso 2. Implementar la Funcionalidad de la Cámara en Android

En el proyecto Android, implementaremos el acceso a la cámara nativa mediante la API de Intent.

  1. Dirígete al proyecto Android (termina en .Droid).
  2. Crea una carpeta llamada Services y dentro de ella, un archivo llamado CameraService.cs.

Aquí implementamos la interfaz que creamos en el proyecto compartido:

using Android.App;
using Android.Content;
using Android.Provider;
using CameraApp.Services;
using System.IO;
using System.Threading.Tasks;
using Xamarin.Forms;
using Environment = Android.OS.Environment;
using Uri = Android.Net.Uri;

[assembly: Dependency(typeof(CameraApp.Droid.Services.CameraService))]
namespace CameraApp.Droid.Services
{
    // Clase que implementa la interfaz ICameraService para capturar una foto en Android
    public class CameraService : ICameraService
    {
        // Ruta donde se almacenará la foto capturada
        private string _filePath;

        public Task<string> CapturePhotoAsync()
        {
            // Creamos una tarea de tipo TaskCompletionSource para capturar la foto de forma asincrónica
            var taskCompletionSource = new TaskCompletionSource<string>();

            // Creamos un Intent para abrir la cámara
            var intent = new Intent(MediaStore.ActionImageCapture);

            // Creamos un archivo temporal donde se guardará la imagen capturada
            var file = new Java.IO.File(Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures), $"photo_{System.Guid.NewGuid()}.jpg");
            _filePath = file.AbsolutePath;

            // Asignamos la ruta del archivo como el destino de la imagen
            intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(file));

            // Verificamos si hay alguna aplicación de cámara disponible para manejar el intent
            if (intent.ResolveActivity(Android.App.Application.Context.PackageManager) != null)
            {
                // Iniciamos la cámara y esperamos el resultado
                MainActivity.Instance.StartActivityForResult(intent, MainActivity.CameraRequestCode);
            }

            // Cuando se complete la captura, devolvemos la ruta del archivo
            MainActivity.Instance.PhotoCaptured += (sender, path) =>
            {
                taskCompletionSource.SetResult(path);
            };

            return taskCompletionSource.Task;
        }
    }
}
  • CapturePhotoAsync: Este método abre la cámara utilizando un Intent para capturar una imagen. La imagen se guarda en un archivo temporal en el directorio público de imágenes del dispositivo.
  • TaskCompletionSource<string>: Esto nos permite capturar la foto de forma asincrónica y esperar a que la cámara devuelva la imagen.
  • MainActivity.Instance.StartActivityForResult: Inicia la actividad de la cámara y espera el resultado.
  • MainActivity.Instance.PhotoCaptured: Es un evento que se dispara cuando la imagen ha sido capturada. El archivo se guarda y su ruta se devuelve como resultado.

Paso 3. Modificar MainActivity en el Proyecto Android

Para que la captura de la foto funcione correctamente, necesitamos manejar el resultado de la actividad de la cámara en el archivo MainActivity.cs.

Abre el archivo MainActivity.cs y modifica su contenido para manejar el resultado de la cámara:

using Android.App;
using Android.Content;
using Android.OS;
using Xamarin.Forms;
using Uri = Android.Net.Uri;

namespace CameraApp.Droid
{
    [Activity(Label = "CameraApp", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        public static MainActivity Instance { get; private set; }
        public const int CameraRequestCode = 1001;

        // Evento que se dispara cuando la foto ha sido capturada
        public event EventHandler<string> PhotoCaptured;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            Instance = this;

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }

        // Sobrescribimos el método para manejar el resultado de la cámara
        protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);

            if (requestCode == CameraRequestCode && resultCode == Result.Ok)
            {
                // Disparamos el evento con la ruta de la imagen capturada
                PhotoCaptured?.Invoke(this, CameraService.Instance._filePath);
            }
        }
    }
}
  • MainActivity: Maneja el resultado de la cámara en el método OnActivityResult. Si la captura de la imagen es exitosa, se dispara el evento PhotoCaptured con la ruta de la imagen.
  • CameraRequestCode: Es el código que utilizamos para identificar la solicitud de la cámara.

Paso 4. Acceder a la Funcionalidad de la Cámara desde el Proyecto Compartido

Ahora que hemos implementado la funcionalidad de la cámara en Android, vamos a consumirla desde la capa compartida en Xamarin Forms.

  1. Abre el archivo MainPage.xaml.cs en el proyecto compartido.
  2. Modifica el código para capturar y mostrar la foto en la interfaz:
using System;
using Xamarin.Forms;
using CameraApp.Services;

namespace CameraApp
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        // Método que se ejecuta cuando el usuario presiona el botón para capturar la foto
        private async void OnCapturePhotoClicked(object sender, EventArgs e)
        {
            // Usamos DependencyService para obtener el servicio de la cámara
            var cameraService = DependencyService.Get<ICameraService>();

            if (cameraService != null)
            {
                // Capturamos la foto de manera asincrónica
                var photoPath = await cameraService.CapturePhotoAsync();

                // Si se capturó la foto, la mostramos en la interfaz
                if (!string.IsNullOrEmpty(photoPath))
                {
                    PhotoImage.Source = ImageSource.FromFile(photoPath);
                }
                else
                {
                    await DisplayAlert("Error", "No se pudo capturar la foto", "OK");
                }
            }
        }
    }
}
  • OnCapturePhotoClicked: Este método se ejecuta cuando el usuario presiona el botón para capturar una foto. Utilizamos DependencyService para obtener una instancia de ICameraService y capturar la foto.
  • PhotoImage.Source: Una vez que la foto ha sido capturada, se muestra en la interfaz de usuario.

Paso 5. Crear la Interfaz de Usuario para Capturar y Mostrar la Imagen

Finalmente, vamos a crear la interfaz de usuario en XAML para que el usuario pueda capturar la foto y verla en pantalla.

  1. Abre el archivo MainPage.xaml en el proyecto compartido.
  2. Define la interfaz de usuario de la siguiente manera:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CameraApp.MainPage">

    <StackLayout Padding="20">

        <!-- Título -->
        <Label Text="Capturar Foto" 
               FontSize="Large" 
               HorizontalOptions="Center" />

        <!-- Botón para capturar foto -->
        <Button Text="Capturar Foto"
                Clicked="OnCapturePhotoClicked"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand" />

        <!-- Imagen donde se mostrará la foto capturada -->
        <Image x:Name="PhotoImage"
               WidthRequest="300"
               HeightRequest="300"
               HorizontalOptions="Center"
               VerticalOptions="CenterAndExpand" />

    </StackLayout>

</ContentPage>
  • Button: El botón que dispara el evento para capturar la foto. Al hacer clic, se ejecuta el método OnCapturePhotoClicked.
  • Image: Control para mostrar la imagen capturada. Se actualiza con la ruta de la foto tomada.

 

Probar la Aplicación en un Dispositivo Android

Ahora que has completado la implementación, puedes probar la aplicación en un dispositivo o emulador Android.

  1. Conecta tu dispositivo físico o abre un emulador con soporte para cámara.
  2. Establece el proyecto Android como proyecto de inicio.
  3. Haz clic en Iniciar para compilar y ejecutar la aplicación.
  4. Al presionar el botón "Capturar Foto", se abrirá la cámara, podrás tomar una foto y esta se mostrará en la pantalla.

 

Conclusión

Has aprendido a integrar la cámara en una aplicación Xamarin Forms para Android utilizando la API nativa de Android. Este artículo te ha guiado paso a paso en la creación de una aplicación que captura fotos y las muestra en pantalla, detallando cada parte del código. Con esta base, puedes seguir extendiendo la funcionalidad para enriquecer tus aplicaciones, como agregar opciones para compartir o almacenar imágenes en la nube.

 

   EtiquetasXamarin C# Android

  Compartir


  Nuevo comentario

El campo Comentario es obligatorio.
El campo Nombre es obligatorio.

  Comentarios

No hay comentarios para este Post.



Utilizamos cookies propias y de terceros para mejorar nuestros servicios y ofrecerle una mejor experiencia de navegación. Si continúa navegando consideramos que acepta su uso. Más información   Acepto