[Windows Phone Tango] Actualización del SDK: 7.1.1 CTP

Hola a todos!

Este lunes 27 Microsoft lanzó al público una nueva versión del SDK de Windows Phone, la 7.1.1, dirigida a dispositivos equipados con la nueva versión del sistema operativo: Windows Phone Tango. Esto coincidió con el lanzamiento en el Mobile World Congress de los primeros dispositivos equipados con esta nueva revisión del sistema, como el Nokia Lumia 610 o el ZTE Tania.

Lumia_610zte-tania

Las principales características de estos terminales son su bajo precio, el Nokia Lumia 610 estará disponible libre por unos 180 €, su RAM reducida (256 Mb en vez de 512 Mb) y su procesador (800Mhz frente a 1Ghz). He tenido la oportunidad de jugar con ambos terminales en el Mobile World Congress y la verdad es que sorprende que aún con este recorte de prestaciones el sistema operativo se comporte tan bien como lo hace.

La principal incidencia de estas características la vamos a sufrir los desarrolladores: En Windows Phone 7.5 (Mango) el límite de consumo de memoria de las aplicaciones se situaba en 90Mb, en Windows Phone Tango, este límite se baja hasta los 60Mb. También tendremos la restricción de no poder acceder a tareas en background en estos dispositivos. Microsoft afirma que cerca del 90% de las aplicaciones del marketplace podrán funcionar en Windows Phone Tango. Vamos a ver las novedades específicas que trae esta versión del kit de desarrollo.

Nuevos Emuladores

Si queremos que nuestra aplicación esté disponible para los dispositivos con Windows Phone Tango, lo que teniendo en cuenta que están dirigidos a mercados emergentes sería muy deseable, debemos respetar los límites de consumo de memoria. Para ayudarnos en esta tarea, Microsoft ha creado un emulador con solo 256Mb de Ram y otro con 512Mb, el cual podremos elegir antes de ejecutar nuestra aplicación desde Visual Studio 2010:

newemulators

De esta forma podremos analizar nuestra aplicación en un emulador con las capacidades de Tango o en uno normal, con las mismas capacidades que un dispositivo Mango (7.5). 

Por lo demás el emulador incluye una nueva aplicación llamada Help + How to, como en los nuevos teléfonos y en los Settings tenemos el menú de aplicaciones SIM. La build del sistema que ejecutan es la 8731. Aparte de esto, todo se mantiene igual en el emulador.

Cambios en el WMAppManifest.xml

Aunque resulten interesante los mercados emergentes, puede que por la naturaleza de nuestra aplicación no podamos conformarnos con 60Mb de consumo y necesitemos acceder a más memoria. Para estos casos necesitaremos incluir una nueva sección en el WMAppManifest.xml:

    <Requirements>
      <Requirement Name="ID_REQ_MEMORY_90"/>
    </Requirements>

Esto no evitará que despleguemos la aplicación en el emulador de 256Mb, solo servirá para que nuestra aplicación no aparezca en las búsquedas del marketplace de los dispositivos equipados con Tango.

Nuevas Propiedades

La clase DeviceExtendedProperties expone ahora una nueva propiedad llamada ApplicationWorkingSetLimit que nos devolverá el WorkingSet que tenemos disponible. Si estamos trabajando con un dispositivo Tango devolverá un máximo de 60Mb, en otros casos devolverá 90Mb. Al acceder a esta propiedad deberemos usarla dentro de un bloque try/catch pues se puede dar el caso de que el dispositivo no esté actualizado y no disponga de ella, caso en el que se lanzará un ArgumentOutOfRangeException, que nos indicará que nos encontramos en un dispositivo sin actualizar y por lo tanto, con 512Mb de RAM.

try
{
    long result = (long)DeviceExtendedProperties.GetValue("ApplicationWorkingSetLimit");
}
catch (ArgumentOutOfRangeException argOutEx) 
{ 
            
}

Conclusión

Como podéis ver las novedades se centran en la gestión de memoria que realice nuestra aplicación. Algo a tener en cuenta con este SDK es que no tiene licencia “GO LIVE” por lo que las aplicaciones que compilemos con el no podrán ser publicadas en el marketplace. Si aun así deseas probarlo e ir preparándote para Windows Phone Tango, que está muy cerca, puedes descargar esta CTP 7.1.1 aquí donde también encontrarás las notas del producto que incluyen como desinstalarlo para volver a la versión anterior.

¿Qué te parecen las novedades de Tango? ¿Millones de usuarios potenciales en mercados emergentes valen la pena a esta “fragmentación” del sistema operativo? ¿Qué te parece como está resuelta? Déjame tu opinión y harás feliz a un pequeño blogger!!

Un saludo y Happy Coding!

[Windows Phone 7.5] Materiales de mi Webcast en MSDN Latam

Este pasado viernes 24 de Febrero MSDN Latam me dio la oportunidad de realizar un Webcast sobre desarrollo para Windows Phone 7.5.

En el pudimos dar un vistazo a los principales conceptos necesarios para desarrollar para esta plataforma, de forma introductoria:

  • Introducción a Windows Phone 7.5: Metro, filosofía, capacidades…
  • Patrón MVVM.
  • Localización de aplicaciones.
  • Lanzadores & Selectores, interactuando con el sistema.
  • Asegurando nuestra calidad: Pruebas unitarias.

Podéis ver el evento grabado siguiendo el siguiente enlace: https://www137.livemeeting.com/cc/MSEvents/view?cn=guest&id=1032503686&pw=1AB0969A

He colgado la presentación en SlideShare para que sea más cómodo poder verla (en breve colgaré todas las que he realizado hasta ahora):

También os dejo a continuación la presentación y los ejemplos para que podáis descargarlos aquí.

Espero que todos hayáis disfrutado tanto en el webcast como yo. Un saludo y Happy Coding!

[Windows Phone 7.5] Podcast en español WPControla, episodio 2

wpcontrola_tile

Hola a todos!

Debido a la buena acogida general que ha tenido, aquí estamos con el segundo capítulo del podcast sobre desarrollo para Windows Phone que hago con Rafael Serna.

En este segundo capítulo entrevistamos a Camilo Galiana, encargado del soporte a desarrolladores de Windows Phone en Microsoft Ibérica y publicador de juegos en el marketplace para que nos hable de sus experiencias como desarrollador y cómo desde Microsoft ayudan a la comunidad. También desgranamos las últimas noticias y hablamos sobre el acceso al API de XBox Live y como localizar tus aplicaciones.

Tienes un resumen completo y los enlaces del podcast aquí.

Espero que disfrutéis tanto escuchándolo como yo haciéndolo.

Un saludo y Happy Coding!

[MSDN Latam] Webcast: Desarrollo de aplicaciones Windows Phone 7.5

msdn_wp75

Hola a todos!

El próximo viernes 24 de Febrero estaré con MSDN Latam haciendo un webcast de 1 hora sobre desarrollo de aplicaciones para Windows Phone 7.5, podremos ver los siguientes temas, desde un punto de vista introductorio:

  • Introducción a Windows Phone 7.5: Metro, filosofía, capacidades…
  • Patrón MVVM.
  • Localización de aplicaciones.
  • Lanzadores & Selectores, interactuando con el sistema.
  • Asegurando nuestra calidad: Pruebas unitarias.

Si estás interesado en acudir, puedes registrarte y obtener la fecha y horas exactas aquí

Un saludo a todos y Happy Coding!

[Windows Phone 7.5] Acceso a la Cámara (II)

Hola a todos!

En el anterior artículo vimos que Windows Phone 7.5 soporta dos apis distintas para trabajar con la cámara del dispositivo. Vimos a fondo como usar el api nativa de Windows Phone para sacar fotos con gran resolución, manejar el flash o el auto enfoque e incluso como usar los botones físicos de disparo del teléfono para sacar nuestra foto.

Pero no solo de imágenes estáticas se vive, también es interesante poder grabar videos (que incluyan audio) con nuestra aplicación. En Windows Phone esto lo conseguimos usando el api de webcam de Silverlight 4. Esto significa que si alguna vez has usado este api en la versión de escritorio de Silverlight, ya sabes usarla en Windows Phone y además el código te servirá sin ningún problema.

Grabando video y audio

En primer lugar vamos a crear una página con un layout básico que nos permita mostrar el video de la cámara, grabar, parar y reproducir:

<Grid>
    <Grid.Background>
        <VideoBrush x:Name="video"></VideoBrush>
    </Grid.Background>
        
    <StackPanel Orientation="Horizontal" Height="100" 
                HorizontalAlignment="Center"
                VerticalAlignment="Bottom"
                Margin="10" Background="#55CCCCCC">
        <Button Name="btnRec" Content="Rec" Width="150">
        </Button>
        <Button Name="btnStop" Content="Stop" Width="150">
        </Button>
        <Button Name="btnPlay" Content="Play" Width="150">
        </Button>
    </StackPanel>
</Grid>

Como podemos ver, vuelve a hacer acto de presencia el VideoBrush, que nos permitirá mostrar como background de la Grid el vídeo que capturemos de la cámara. En cuanto a diseño hemos terminado con nuestra aplicación. Vamos a ver el código que necesitamos ahora para aportarle la funcionalidad deseada.

Para comenzar vamos a crear una instancia del objeto CaptureSource, localizado en el namespace System.Windows.Media, que será el encargado de ofrecernos las fuentes de audio / video a utilizar y del objeto FileSink, del mismo namespace, encargado de ir guardando el video que grabemos en un archivo:

public partial class MainPage : PhoneApplicationPage
{
    CaptureSource source = new CaptureSource();
    FileSink file = new FileSink();
    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }
}

A continuación tenemos que inicializar los dispositivos de audio y video que deseamos utilizar y establecer la fuente de video de nuestra VideoBrush:

void InitializeVideo()
{
    file = new FileSink();
    source = new CaptureSource();

    source.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
    source.AudioCaptureDevice = CaptureDeviceConfiguration.GetDefaultAudioCaptureDevice();

    video.Stretch = Stretch.Uniform;
    video.SetSource(source);
}

Lo más importante de este método es la clase CaptureDeviceConfiguration. Nos ofrece dos métodos para audio y video: GetDefaultAudioCaptureDevice / GetDefaultVideoCaptureDevice, que usamos en este ejemplo para obtener los dispositivos de audio y video por defecto y GetAvailableAudioCaptureDevices y GetAvailableVideoCaptureDevices, que nos ofrecen todos los dispositivos de grabación que tenemos en el sistema para que podamos ofrecerlos al usuario. Esto es muy importante en el caso del video, pues ya empiezan a aparecer los primeros terminales Windows Phone con cámara frontal, por lo que podríamos ofrecer al usuario el uso de la cámara frontal o la cámara trasera y que el decida cual quiere asignar a la captura de video.

Ya solo nos queda llamar al método InitializeVideo desde el constructor de nuestra página, o desde el método OnNavigatedTo (Ten en cuenta que el constructor no se ejecuta cuando vuelves a una página desde el Tombstoning o el FAS, el OnNavigatedTo si lo hace), llamar al método Start() de nuestra instancia de CaptureSource e iniciar la aplicación en un terminal para obtener el primer resultado de nuestra nueva grabadora de video:

Screen Capture (12)

Ya tenemos gran parte del trabajo hecho. Un detalle que observaremos es que la fluidez del video que vemos en pantalla es mucho mayor que la obtenida con el método del primer artículo. Esto se debe principalmente a la calidad exigida a la cámara, que en este caso es mucho menor y nos ofrece entre 24 y 30 frames por segundo, dependiendo del modelo de teléfono que tengamos.

Ahora vamos a empezar a grabar cuando el usuario presione el botón “Rec”:

private void btnRec_Click(object sender, RoutedEventArgs e)
{
    source.Stop();
    file = new FileSink();
    file.CaptureSource = source;
    file.IsolatedStorageFileName = "video.mp4";
    source.Start();
}

En primer lugar paramos nuestra fuente de video usando el método Stop() del CaptureSource. Esto nos permite cambiar los parámetros de la instancia de FileSkink, al cual debemos asignar el CaptureSource a usar y el nombre de archivo para nuestro video (Es obligatorio usar la extensión MP4, de lo contrario obtendremos una preciosa InvalidOperationException al intentar asignar el nombre de archivo). Por último solo tenemos que volver a iniciar nuestra instancia de CaptureSource.

Para detener la grabación, simplemente llamamos al método InitializeVideo, que resetea el FileSink a una instancia nueva y por lo tanto deja de grabar:

private void btnStop_Click(object sender, RoutedEventArgs e)
{
    source.Stop();
    InitializeVideo();
    source.Start();
}

Algo que siempre hacemos es llamar al método Stop() del CaptureSource antes de cambiar propiedades, de lo contrario tendríamos problemas (de nuevo nuestra amiga InvalidOperationException) al intentar modificar el FileSkink, pues solo se permite su modificación cuando el CaptureSource está detenido.

Y ahora que hemos grabado un vídeo, podemos reproducirlo llamando al MediaPlayerLauncher:

private void btnPlay_Click(object sender, RoutedEventArgs e)
{
    MediaPlayerLauncher mplayer = new MediaPlayerLauncher();
    mplayer.Location = MediaLocationType.Data;
    mplayer.Media = new Uri("video.mp4", UriKind.Relative);
    mplayer.Show();
}

Y el resultado es que podremos ver nuestros videos directamente en el teléfono:

Screen Capture

 

Ya tenemos nuestra grabadora de vídeo terminada, no haremos la competencia a Red, pero ¿Y lo bien que nos lo hemos pasado?.

Algo que sería muy útil, pero que desgraciadamente no está soportado, es poder guardar estos vídeos en la librería multimedia o la galería del teléfono. Lamentablemente solo podemos guardar/obtener imágenes de ella así que la única opción para poder enviar estos vídeos fuera de nuestra aplicación pasa por subirlos a Skydrive u otro servicio de almacenamiento o crear un servicio web en el pc que sea capaz de recibir los vídeos. Tirón de orejas a los chicos de Windows Phone! Esperemos que en próximas versiones podamos guardar nuestros fantásticos vídeos caseros!

Conclusión

Y con esto terminamos nuestra mini serie de dos artículos. Como siempre, aquí tienes el código del ejemplo usado en el artículo. Espero que disfrutéis tanto leyéndolo como yo escribiéndolo y….

Happy Coding!

[Windows Phone 7.5] Acceso a la Cámara (I)

Hola a todos!

Hoy vamos a hacer un alto en nuestra series de artículos sobre Expression Blend 4 para ver como, con Windows Phone 7.5, podemos tener acceso a la cámara de nuestro dispositivo de dos modos distintos. Veremos como sacar fotos, ajustar parámetros de la cámara y como grabar vídeos.

Dos apis, un hardware

En Windows Phone 7.5 tenemos acceso a la cámara de nuestro dispositivo a través de dos apis diferentes: La api de cámara de Windows Phone y la api de webcam de Silverlight 4. Esto se debe a que internamente en nuestra aplicación usamos Silverlight 4 para desarrollar y este ya incluye soporte para acceso a cámaras. De esta forma, usaremos la api propia de Windows Phone para obtener capturas, fotos, de la cámara y podremos usar la api de webcam para grabar vídeos.

¿Cuando usar una u otra? Las diferencias entre ambas vienen marcadas por la calidad con la que accederemos a las imágenes en vivo. La api de Windows Phone nos ofrecerá imágenes en mayor resolución (tanta como soporte nuestra cámara), podremos acceder al botón de disparo físico del dispositivo, controlar el flash, el zoom o el foco. Sin embargo el api de webcam de Silverlight 4 nos ofrecerá video en una resolución más baja, pero con mayor ratio de cuadros por segundo por lo que podremos grabar videos más fluidos que incluyan audio.

Api de cámara de Windows Phone

El uso del api nativa de Windows Phone para acceder a la cámara es realmente sencillo. Disponemos de un nuevo tipo de brocha que podemos aplicar como “color” a nuestros elementos, por ejemplo al foreground de un textblock se trata del VideoBrush:

<TextBlock Text="Camara"
            VerticalAlignment="Center"
            HorizontalAlignment="Center"
            FontSize="190">
    <TextBlock.Foreground>
        <VideoBrush x:Name="videoBrush"></VideoBrush>
    </TextBlock.Foreground>
</TextBlock>

O al Background de una Grid:

<Grid>
    <Grid.Background>
        <VideoBrush x:Name="videoBrush"></VideoBrush>
    </Grid.Background>
</Grid>

De esta forma, podemos obtener la fuente de imágenes de la cámara. Ahora solo necesitamos inicializar nuestra cámara, usando el objeto PhotoCamera localizado en el namespace Microsoft.Devices y establecerla en la fuente de nuestra VideoBrush:

public MainPage()
{
    InitializeComponent();

    PhotoCamera camara = new PhotoCamera();
    videoBrush.SetSource(camara);
}

Como se puede ver, el código necesario para hacer funcionar la cámara es realmente sencillo y el resultado espectacular:

image

Si os estáis preguntando como he capturado las imágenes de la cámara funcionando, he usado una herramienta llamada Screen Capture v3 que podéis encontrar en los foros de XDA Developers, exactamente aquí. El único requisito de esta aplicación es que tengáis vuestro dispositivo desbloqueado para desarrollo y os permitirá obtener capturas de pantalla usando el botón de disparo de la cámara.

Ya podemos mostrar la cámara en nuestra aplicación, ¿Que hacemos ahora con ella? Pues lo más sencillo que podemos hacer: sacar una fotografía. En esta acción interviene un evento, el cual nos indicará que tenemos una foto disponible, llamado CaptureImageAvailable y el método CaptureImage del objeto PhotoCamera que llamaremos desde un botón colocado en la interface de usuario:

public partial class MainPage : PhoneApplicationPage
{
    PhotoCamera camara;

    public MainPage()
    {
        InitializeComponent();

        camara = new PhotoCamera();
        camara.CaptureImageAvailable += new EventHandler<ContentReadyEventArgs>(camara_CaptureImageAvailable);
        videoBrush.SetSource(camara);
    }

    void camara_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
    {
        var photo = e.ImageStream;
    }

    private void saveButton_Click(object sender, RoutedEventArgs e)
    {
        camara.CaptureImage();
    }
}

Como podéis ver el código es realmente sencillo: Manejamos el evento CaptureImageAvailable y en el botón saveButton llamamos al método CaptureImage, lo que hace saltar el evento CaptureImageAvailable que nos da un Stream con la fotografía que hemos obtenido. Pero… ¿Y ahora que hacemos con  esta foto? Bien, por defecto Silverlight no incluye métodos para guardar fotografías en la librería multimedia, podríamos usar el almacenamiento aislado para guardar la imagen, pero normalmente querremos que el usuario la tenga accesible desde su galería de imágenes. Para esto, vamos a apoyarnos en él namespace Media de XNA, Microsoft.Xna.Framework.Media, que nos permitirá trabajar con la galería de imágenes del dispositivo:

void camara_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
{
    string photoName = string.Format(@"{0}.jpg", DateTime.Now.Ticks.ToString());

    Dispatcher.BeginInvoke(() =>
    {
        MediaLibrary library = new MediaLibrary();
        library.SavePicture(photoName, e.ImageStream);
    });
}

En este método, podéis ver lo sencillo que es usar el objeto MediaLibrary de XNA para guardar una foto. También hay dos curiosidades: por defecto le he puesto como extensión jpg, esto se debe a que es el formato usado por la cámara para darnos las fotografías. La segunda curiosidad es que estoy usando un Dispatcher para acceder a la librería… esto es así porque el evento CaptureImageAvailable se lanza desde un hilo distinto al de interface de usuario, que es el que usa la MediaLibrary para trabajar, de esta forma tenemos que usar el método SavePicture dentro del Dispatcher para que se ejecute en el hilo de interface de usuario.

Si iniciamos la aplicación y sacamos una foto, podremos ir inmediatamente a verla a la galería de imágenes de Windows Phone. Por defecto, veremos que el resultado no es demasiado espectacular. Es muy posible que la foto salga desenfocada y con poca luz. Es hora de controlar el foco, el flash y la resolución de la cámara.

Esto es algo realmente simple. En el caso del Flash, tenemos una propiedad en el objeto PhotoCamera llamada FlashMode a la que podemos asignar alguno de estos valores:

Valor Modo
On Encendido
Off Apagado
Auto Automático
RedEyeReduction Reducción de ojos rojos (si no está disponible, se usa el Flash normal)

Para establecer el Flash, deberemos tener la cámara totalmente inicializada, para estar seguros de que se ha completado la inicialización, podemos controlar el evento Initialized del objeto PhotoCamera:

public MainPage()
{
    InitializeComponent();
    camara = new PhotoCamera();
    camara.Initialized += new EventHandler<CameraOperationCompletedEventArgs>(camara_Initialized);
    camara.CaptureImageAvailable += new EventHandler<ContentReadyEventArgs>(camara_CaptureImageAvailable);
    videoBrush.SetSource(camara);
}

void camara_Initialized(object sender, CameraOperationCompletedEventArgs e)
{
    camara.FlashMode = FlashMode.On;
}

Una vez hecho esto, siempre que disparemos la cámara el Flash se comportará acorde con lo que hayamos indicado.

El enfoque de cámara es también muy simple. Tenemos un evento AutoFocusCompleted que se lanzará cuando se haya terminado de enfocar y un método Focus() que inicia el enfoque. Vamos a modificar nuestro código para que el botón de disparo llame al método Focus() y en el evento AutoFocusCompleted se realice la captura de pantalla:

public partial class MainPage : PhoneApplicationPage
{
    PhotoCamera camara;

    public MainPage()
    {
        InitializeComponent();
        camara = new PhotoCamera();
        camara.Initialized += new EventHandler<CameraOperationCompletedEventArgs>(camara_Initialized);
        camara.CaptureImageAvailable += new EventHandler<ContentReadyEventArgs>(camara_CaptureImageAvailable);
        camara.AutoFocusCompleted += new EventHandler<CameraOperationCompletedEventArgs>(camara_AutoFocusCompleted);
        videoBrush.SetSource(camara);
    }

    void camara_Initialized(object sender, CameraOperationCompletedEventArgs e)
    {
        camara.FlashMode = FlashMode.On;
    }

    void camara_AutoFocusCompleted(object sender, CameraOperationCompletedEventArgs e)
    {
        camara.CaptureImage();
    }

    void camara_CaptureImageAvailable(object sender, ContentReadyEventArgs e)
    {
        string photoName = string.Format(@"{0}.jpg", DateTime.Now.Ticks.ToString());

        Dispatcher.BeginInvoke(() =>
        {
            MediaLibrary library = new MediaLibrary();
            library.SavePicture(photoName, e.ImageStream);
        });
    }

    private void saveButton_Click(object sender, RoutedEventArgs e)
    {
        camara.Focus();
    }
}

Con este código, la calidad de nuestras fotos es mucho mayor:

image

Ya hemos visto como controlar el Focus y el Flash. Un detalle que nos queda por ver en cuanto a la calidad de las fotos tomadas es la resolución a usar. Esto lo realizaremos mediante dos propiedades: AvailableResolutions, que contiene todas las resoluciones que soporta nuestra cámara, y Resolution, que contiene la resolución activa. Vamos a colocar un listbox en nuestra aplicación que liste todas las resoluciones disponibles y al seleccionar una la activaremos:

void camara_Initialized(object sender, CameraOperationCompletedEventArgs e)
{
    camara.FlashMode = FlashMode.On;
    Dispatcher.BeginInvoke(() =>
    {
        lstResolutions.ItemsSource = camara.AvailableResolutions;
    });
}

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    camara.Resolution = (Size)lstResolutions.SelectedItem;
}

Y el resultado final es el siguiente:

Screen Capture (11)

Al seleccionar cualquier resolución de la lista, automáticamente veremos como la cámara realiza un pequeño parpadeo y se aplica la nueva resolución. Ahora ya tenemos una aplicación que nos permite sacar fotos con autofocus, flash y diferentes resoluciones. ¿Que más nos falta para desbancar a Nikon del trono de las cámaras digitales? Pues algo muy simple: Poder utilizar el botón físico de disparo que incorporan todos los Windows Phone. Después de todo… para algo está!!

Para hacer esto, tenemos a nuestra disposición en el namespace Microsoft.Devices un objeto llamado CameraButtons que expone tres eventos: ShutterKeyHalfPressed, ShutterKeyPressed y ShutterKeyReleased. Solo necesitamos controlar estos eventos y ejecutar en cada caso el código necesario:

public MainPage()
{
    InitializeComponent();

    CameraButtons.ShutterKeyHalfPressed += new EventHandler(CameraButtons_ShutterKeyHalfPressed);
    CameraButtons.ShutterKeyPressed += new EventHandler(CameraButtons_ShutterKeyPressed);
    CameraButtons.ShutterKeyReleased += new EventHandler(CameraButtons_ShutterKeyReleased);
    camara = new PhotoCamera();
    camara.Initialized += new EventHandler<CameraOperationCompletedEventArgs>(camara_Initialized);
    camara.CaptureImageAvailable += new EventHandler<ContentReadyEventArgs>(camara_CaptureImageAvailable);
    camara.AutoFocusCompleted += new EventHandler<CameraOperationCompletedEventArgs>(camara_AutoFocusCompleted);            
    videoBrush.SetSource(camara);
}

void CameraButtons_ShutterKeyReleased(object sender, EventArgs e)
{
    camara.CancelFocus();
}

void CameraButtons_ShutterKeyPressed(object sender, EventArgs e)
{
    camara.CaptureImage();
}

void CameraButtons_ShutterKeyHalfPressed(object sender, EventArgs e)
{
    camara.Focus();
}

Y con este sencillo código tenemos lista nuestra aplicación para usar el botón físico del teléfono.

Algo más a tener en cuenta antes de terminar: En las especificaciones actuales de Windows Phone no es obligatorio que la cámara tenga autofocus. Para evitar problemas al acceder al método Focus() es conveniente usar la propiedad IsFocusSupported del objeto PhotoCamera primero, y solo llamar a Focus() si está soportado.

Conclusión

En este primer artículo hemos visto como usar el api de cámara propia de Windows Phone, como controlar el comportamiento de la cámara y como usar el botón físico de disparo. Puedes descargarte el código de ejemplo usado en el artículo aquí.

En el próximo artículo veremos como usar el api de webcam de Silverlight 4 desde nuestro dispositivo para grabar audio y video.

Hasta la próxima y Happy Coding!