Mobile Apps

Windows Phone 8.1 | Usar el flash de la cámara ¿Torch o Flash?

posterMientras desarrollaba la aplicación Torch8 me encontré con estas dos formas de controlar el flash de la cámara pero, ¿cuál es la adecuada para qué momento y cómo debo usarla?

Si vamos a la documentación podemos observar que la ayuda para tomar esta decisión es mínima y que depende en gran medida de la interpretación que hagamos sobre la descripción.

  • TorchControl : Provides functionality for controlling the torch LED settings on a capture device.
  • FlashControl : Provides functionality for controlling the flash settings on a capture device.

Y os preguntaréis… WTF!! Pero si es análogo!! Pues no exactamente. Digamos que la diferencia es que Torch está pensado simplemente para alumbrar porque sí y Flash está pensando para realizar la acción de flash durante una captura de una foto o un vídeo aunque en definitiva, sea prácticamente lo mismo. De hecho, FlashControl contiene alguans propiedades más como RedEyeReduction y RedEyeReductionSupported que nos dan esa misma idea.

Sea cual sea lo que decidamos usar y que vaya acorde con nuestra aplicación, su uso es muy similar, necesitando únicamente una instancia de MediaCapture desde la que obtener el acceso al controlador tal y como muestro en los ejemplos

TorchControl

public void TurnTorch(bool on)
{
if (mediaCapture.VideoDeviceController.TorchControl.Supported)
{
if (on)
{
if (mediaCapture.VideoDeviceController.TorchControl.PowerSupported)
mediaCapture.VideoDeviceController.TorchControl.PowerPercent = 100;
mediaCapture.VideoDeviceController.TorchControl.Enabled = true;
}
else
mediaCapture.VideoDeviceController.TorchControl.Enabled = false;
}
}

FlashControl

        public void TurnFlash(bool on)
{
var flashControl = mediaCapture.VideoDeviceController.FlashControl;

            if (flashControl.Supported)
{
if (on)
{
if (flashControl.PowerSupported)
flashControl.PowerPercent = 100;
#if WINDOWS_PHONE_APP
if (flashControl.AssistantLightSupported)
flashControl.AssistantLightEnabled = true;
#endif
if (flashControl.RedEyeReductionSupported)
{
flashControl.RedEyeReduction = true;
}
flashControl.Enabled = true;
}
else
flashControl.Enabled = false;
}
}

 

Como podéis observar, con el control del flash se pueden realizar más tareas que sólo tienen sentido en la captura de una imagen pero, que en el caso de mi aplicación de linterna no tendrían razón de ser, por eso, debéis usar la que se adapte mejor a vuestra aplicación en cada momento.

Notas importantes

Como siempre, recordad liberar los recursos de la cámara como os indiqué en el artículo anterior y, como apunte a este artículo, no os asustéis si el led no se enciende cuando estéis desarrollando, simplemente, tened en cuenta que si el dispositivo está conectado al PC (o a la corriente) el led no se activará con este código

 

Espero que os sea de ayuda. Enjoy coding!!

Windows Phone 8.1 | Iniciar cámara para previsualización

posterSupongamos que estamos realizando una aplicació y necesitamos ver lo que estamos enfocando con la cámara ya sea para iniciar una grabación, tomar una foto o simplemente, como en mi caso para hacer una linterna con cámara (Torch8). Dado que ya tenemos disponible el desarrollo para Windows 10 (desktop y mobile) la información escasea acerca de esta temática para la plataforma Windows Phone 8.1 y Windows 8.1, así que he recopilado lo que he encontrado al respecto y os lo condensaré en este artículo.

Seleccionar cámara

Para empezar, debemos seleccionar la cámara del dispositivo dado que podemos tener delantera, trasera o las dos.

// Get all the cameras
DeviceInformationCollection cameras = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

// Selecting frotal camera
DeviceInformation frontCam = (from webcam in cameras
                              where webcam.EnclosureLocation != null
                              && webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front
                              select webcam).FirstOrDefault();

// Selecting rear camera
DeviceInformation rearCam = (from webcam in cameras
                                where webcam.EnclosureLocation != null
                                && webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back
                                select webcam).FirstOrDefault();

 

Inicializar parámetros de captura

Una vez tengamos la cámara deseada, tendremos que inicializar la captura de vídeo con los parámetros que necesitemos como por ejemplo el código que muestro a continuación

// Initialize MediaCapture parameters
await mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings
{
    VideoDeviceId = rearCam.Id, // Using rear camera
    AudioDeviceId = "", // Don’t capture audio
    StreamingCaptureMode = StreamingCaptureMode.Video, // We want to capture video
    PhotoCaptureSource = PhotoCaptureSource.VideoPreview // Capture mode (Auto | Photo | VideoPreview)

});

Comenzar a obtener visualización de la cámara

Llegados a este punto, ya podemos visualizar lo que enfoquemos con la cámara en nuestro dispositivo y, para ello necesitamos tener preparado el control en la vista XAML y referenciarlo desde el código C#

XAML

<CaptureElement Name="PreviewControl"
                Stretch="UniformToFill"
                />

C#

// Set primary use as Video.

mediaCapture.VideoDeviceController.PrimaryUse = Windows.Media.Devices.CaptureUse.Video;

// Set the source of the CaptureElement to your MediaCapture
PreviewControl.Source = mediaCapture;

// Start Preview of Video.

await mediaCapture.StartPreviewAsync();

Más información

Toda esta información y podéis encontrarla con mayor profundidad en este enlace de MSDN 

Nota Importante

Debeis recordar que es absolutamente necesario liberar los recursos de la cámara al cerrar/suspender la aplicación ya que si no, puede haber conflictos con otras aplicaciones e incluso la nuestra no funcionará como esperamos, para ello, en el enlace que os he puesto tenéis a vuestra dispocisión una muestra de código para limpiar los recursos

public async Task CleanupCaptureResources()
{
    if (IsRecording && MediaCapture != null)
    {
        await MediaCapture.StopRecordAsync();
        IsRecording = false;
    }
    if (IsPreviewing && MediaCapture != null)
    {
        await MediaCapture.StopPreviewAsync();
        IsPreviewing = false;
    }

    if (MediaCapture != null)
    {
        if (PreviewElement != null)
        {
            PreviewElement.Source = null;
        }
        MediaCapture.Dispose();
    }
}

Esta limpieza debéis llevarla a cabo al menos al suspender la aplicación tal y como os copio y pego de la documentación

private async void OnSuspending(object sender, SuspendingEventArgs e)
{
    var deferral = e.SuspendingOperation.GetDeferral();

    //cleanup camera resources
    await CleanupCaptureResources();

    deferral.Complete();
}

No obstante debéis consultar en profundidad la documentación acerca de los estados y el ciclo de vida de las aplicaciones Windows Phone 8.1 o incluso estudiar la posibilidad de manejar la suspensión en la vista tal y como se explica en este artículo de MSDN.

 

Espero que os sea de ayuda. Enjoy coding!!!

Xamarin.Forms | Ocultar la barra de navegación en Android e iOS

posterPara hoy traigo un “workaround” sobre cómo ocultar la barra de navegación en Android cuando estamos trabajando con Xamarin.Forms.

Problema

Cuando creamos una aplicación Xamarin.Forms, por defecto, en Android aparecerá la barra de navegación al hacer uso de NavigationPage. Si no queremos mostrar esta barra de navegación porque hacemos uso de navegación por contenidos y con el botón “back” del propio sistema no es una tarea trivial hasta donde he indagado. Por favor, si tenéis alguna solución más elegante, sencilla y efectiva, compartidla conmigo.

 

Solución

He encontrado varias soluciones para lograr el resultado deseado pero algunas me han parecido más complejas de lo necesario como por ejemplo, sobreescribir el “Tema” Theme.Holo.Light, cosa que sólo funcionaría en Android y habría que buscar la solución para iOS. Pero la que mejor me ha encajado tampoco es muy elegante que digamos (siempre desde mi punto de vista).

Lo que debemos hacer es poner una simple línea de texto en cada una de las páginas

   1: NavigationPage.SetHasNavigationBar(this, false);

 

Con esto ya tendríamos oculta la barra de navegación de iOS y Android, aunque como he comentado, hay que hacerlo página por página siendo algo “latoso” y poco elegante cuando podría haber una solución más simple

 

Referencias

http://developer.xamarin.com/recipes/ios/content_controls/navigation_controller/make_the_nav_bar_disappear/