Generation Apps – Día 29 – Usar el Kit de prueba del Windows Phone Store

El kit de prueba del Windows Phone Store provee una suite automatizada, monitoreada, y pruebas manuales que te ayudaran a preparar tu aplicación para ser aceptado en el Windows Phone Store en la primera vez que apliques. Este kit te permitirá identificar y corregir problemas antes de aplicar tu aplicación para su publicación, el cual te ahorra tiempo en el proceso de registro. Puedes utilizar este kit para versiones de Windows Phone 7.1 o posteriores.

Instalación

El kit de prueba de Windows Phone Store es un componente el SDK de Windows Phone, así que si ya instalaste el SDK, ya debes tener el kit de pruebas a tu disposición. En caso contrario, puedes conseguirlo dando clic aquí…

Qué me dirá el kit de prueba?

Ejecutando este kit en tu aplicación te ayudará a determinar si la aplicación podrá aprobar la certificación o no. En caso que falle, el kit te proveerá detalles de lo que necesitas solucionar en la aplicación antes de someterlo en la evaluación del Windows Phone Store.  La siguiente lista te muestra algunas pruebas que incluye el kit de prueba.

  • Si las imágenes especificadas y capturas de pantallas cumplen con los requerimientos de certificación.

  • Si el icono de la aplicación y la imagen de fondo usada cumplen con los requerimientos de certificación.

  • Que capacidades utiliza la aplicación (internet, cámara, GPS, etc.).

  • El archivo .XAP cumple con el rango de tamaño requerido y si el manifiesto de la aplicación es valido.

  • Si la aplicación maneja errores de manera adecuada.

  • Si la aplicación se ejecuta dentro del rango segundos requerido.

  • Si la aplicación excede el uso de memoria máxima. Esto es particularmente importante a considerar cuando desarrollas aplicaciones para teléfonos de 256 MB de memoria.

  • Si el manejo del botón Back es usado de manera correcta.

  • Si la aplicación usa APIs no permitidas en el teléfono.

  • Si la aplicación usa APIs no permitida en agentes de segundo plano.

  • Si hay excepciones no manejadas en tu aplicación y si la aplicación finaliza de manera apropiada.

Uso del kit de prueba de Windows Phone

Si deseas conocer mas detalles de como usar el kit de prueba, da clic al enlace siguiente;

Kit de prueba para el Windows Phone Store

Fuente:
Windows Phone Marketplace Test Kit

Generation Apps – Día 28 – Crear capturas de pantalla para enviar al de Windows Phone

Puedes crear screenshots de tu aplicación Silverlight  o XNA con la herramienta de screenshot del emulador de Windows Phone. Puedes tomar fotos en cualquier instante de tiempo de tu aplicación. Estos generan una imagen de formato PNG de 480 x 800 pixeles.

WP-Screenshots

Para crear un screenshots utilizando el emulador de Windows Phone

  1. Para optimizar la calidad de las capturas de pantalla, ajusta el zoom del emulador al 100%. A mayor  nivel de zoom, mejor será la calidad de las imágenes.

  2. Desactiva los contadores de rendimiento que aparecen en la esquina derecha superior de la pantalla. Puedes ejecutar la aplicación en modo de Debug, y detenerlo, y volverlo a ejecutar sin cerrar el emulador para que no aparezcan los contadores.

  3. En la barra de herramientas del emulador, da clic al botón de expansión para aparezca la ventana de herramientas adicionales

  4. Da clic a la pestaña Screenshot

  5. Cuando tu aplicación esta lista, da clic al botón Capture, y la imagen resultante se mostrara en la ventana

  6. Da clic en Save para que se despliegue la ventana de dialogo «Save as…»

  7. Nombra tu imagen capturada y da clic en Save.

Fuente:
How to: Create Screenshots for Windows Phone Marketplace

Generations Apps – Día 27 – Ajuste de rendimiento de tu aplicación

Puedes utiliza la herramienta de análisis de rendimiento de Windows Phone para mejorar los tiempos de respuesta de tus aplicaciones Windows Phone. Lo puedes lograr recolectando muestras de datos de rendimiento en una sesión de perfil para luego visualizar y analizar los datos. tienes la opción de analizar el rendimiento de ejecución o de uso de memoria de la aplicación en una sesión de perfil. Este tópico describe como capturar este muestre de datos y analizarlos usando el Performance Analysis Tool.

Para capturar los datos de rendimiento

  1. En Visual Studio 2010, abre un proyecto de Windows Phone version 7.1

  2. Compila el proyecto. (Para mejores resultados, deberías crear un compilado tipo Release)

  3. En la barra de herramientas estándar, selecciona el dispositivo objetivo (Se recomienda usar un dispositivo físico)

  4. En el menú Debug, selecciona Start Windows Phone Performance Analysis. Si estas abriendo un proyecto con versión de Windows Phone 7.0, no se desplegará esta opción de menú.Un log de rendimiento en blanco (un archivo .sap) se despliega en una pestaña de Visual Studio. El archivo .sap es nombrado automáticamente usando una combinación del nombre de tu proyecto con un formato de fecha y hora concatenada. Todos estos archivos son guardados a menos que tu los elimines.Este log de rendimiento se despliega con opciones que te permiten seleccionar que opciones de rendimientos deseas analizar.

    La siguiente imagen te muestra un log vacío de rendimiento y las opciones.

    WP-Performance

  5. En los settings, selecciona la opción Execution para analizar el rendimiento del despliegue ítems visuales y las llamadas a métodos en el código.

    -o-

    Selecciona la opción Memory para analizar el comportamiento de la memoria al instanciar objetos y el uso de texturas en la aplicación. Típicamente optarías por la opción Execution a menos que tu aplicación presente problemas de memoria.

  6. Opcionalmente, puedes dar clic en Advanced Settings para mostrar mas opciones para analizar tu aplicación como los detalles de la cache, colectar contadores de rendimientos detallados y analizar el stack de memoria.

  7. Cuando ya hayas terminado de seleccionar las opciones deseadas, da clic en Launch Applicacion para comenzar la sesión de perfil. Tu aplicación se ejecutara en el dispositivo objetivo (emulador o dispositivo físico).

  8. Ahora utiliza y navega en tu aplicación como un usuario común lo haría. Si hay problemas de rendimiento que ya has observado en casos anteriores, como un scrolling entrecortado o una falta de respuesta de la interfaz de usuario, asegúrate de usar esas funcionalidades para que sean analizadas por la sesión de perfil. Incluso puedes utilizar un cronometro para que tomes el tiempo de uso y tomar notas de observaciones encontradas en tu aplicación para analizarlas en el log de rendimiento. La siguiente imagen muestra una sesión de perfil en ejecución.

    WP-Profiling

  9. Cuando ya termines de interactuar con la aplicación, detiene la sesión de perfil dando clic o haciendo un gesto Tap en el botón Back, el cual causa que la aplicación se finalice. También puedes detenerla sesión yendo a la pestana de rendimiento, y dando clic en Stop Profiling.

Para analizar datos de rendimiento

  1. En el Explorador de Solución, da doble clic en el log de rendimiento (.sap) para abrirlo en Visual Studio. Si apenas terminaste la sesión de perfil, este log deberá estar abierto en Visual Studio. El grafico de la sesión es desplegada.

  2. Ahora utiliza el grafico para observar la tasa de imágenes por segundo (o frame rate) durante la sesión de perfil, al igual que el uso del CPU, uso de memoria, storyboards, cargas de imágenes y eventos de garbage collector.

  3. Para identificar problemas específicos con la aplicación, selecciona una región en la línea de tiempo graficada. Se desplegara información detallada de la región seleccionada, con mensajes e alerta, información y errores.

    WP-Graph

  4. En la tabla de análisis de rendimiento, veras tres tipos de entradas junto con los siguientes iconos:

    • Information icon Ítems de Información

    • Warning icon Ítems de alerta

    • Profiler error icon Ítems de Error

  5. Para cada entrada de Información, Alerta y Error, deberías seguir las instrucciones de la columna de Observation Summary para investigar a mayor detalle la fuente del ítem de información, alerta o error. Estas instrucciones te llevaran que selecciones hacer de la barra de navegación Performance Warnings, y que buscar una vez estando ahí. Puedes hacer clic en los hilos de los procesos para ver mas detalles, como se muestra en la imagen:

    WP-Thread

Fuente:
How to: Capture and Analyse Performance Data Using Windows Phone
How to: Identify and Fix Common Performance Issues Using Windows Phone

Generations Apps – Día 26 – Depurar y probar tu aplicación en un dispositivo Windows Phone

Tu puedes utilizar tanto el emulador Windows Phone como el dispositivo para desarrollar y probar tu aplicación.

Sin embargo el emulador de Windows Phone engloba una gran cantidad de escenarios de desarrollo, es importante tener la habilidad de probar tu aplicación en un dispositivo físico. Para instalar la aplicación en un dispositivo Windows Phone para trabajos de desarrollo y pruebas, hay una serie de pasos que debes seguir primero. Este tópico te explica como preparar tu teléfono para trabajo de desarrollo, muchas veces referías como «desbloqueo de tu teléfono».

Pre-Requisitos

Deberás cumplir con los siguientes requisitos para poder instalar una aplicación en un dispositivo físico.

  • El dispositivo Windows Phone debe estar registrado. La siguiente sección te explica como se hace esto.

  • El dispositivo Windows Phone debe estar conectado a la maquina donde estas desarrollando.

  • Los siguientes requerimientos de Zune:

  • El software cliente de Zune debe estar instalado en la computadora de desarrollo. Puedes descargar el software cliente de Zune dando clic aqui…

  • Zune se debe estar ejecutando. Cuando conectas el dispositivo a la computadora, Zune se ejecuta automáticamente. Si no lo hace, ejecútalo manualmente.

  • Zune debe reconocer que el dispositivo esta conectado.

Registrando el dispositivo

  1. Enciende el teléfono y desbloquéalo si esta protegido con clave PIN.

  2. En tu teléfono, asegúrate que la fecha y hora están correctos.

  3. Usando el cable USB con el que vino tu teléfono, conéctalo a tu computadora.

  4. En tu computadora, da clic a Start ->Todos los programas, y luego Windows Phone SDK 7.1

  5. Da clic en Windows Phone Developer Registration. Una vez que la aplicación inicia, se muestra una ventana como la que se muestra a continuación. Verifica que el Status diga “Phone ready. Please enter your Windows Live ID and password and click «Register» to begin.”

    Si el teléfono ya esta registrado, el Status te informara de esto y veras un botón Unregister, para eliminar el registro del teléfono.

  6. Ingresa tu cuenta Microsoft (o conocido formalmente como el Windows Live ID) y la contraseña correspondiente a tu membrecía en el Dev Center.

  7. Da Clic en Register.

Instalando tu aplicación a un dispositivo físico

  1. Asegúrate que el dispositivo este conectado, encendido y desbloqueado.

  2. En Visual Studio, en la barra de herramientas estándar, selecciona Windows Phone Device.

    WP-Device

  3. En el menú Debug, da clic en Start Debugging, o presiona la tecla F5.

Probando APIs multimedia en un dispositivo físico

Cuando ejecutas tu aplicación en un dispositivo, e invocas tareas donde involucre acceder a la librería de música, fotos y videos, te arrojara un error debido a que se esta sincronizando con el cliente de Zune en la pc. Sigue estos pasos para ejecutar tu aplicación sin usar el cliente de Zune, a modo que puedas probar las tareas multimedia.

  1. Conecta tu Windows Phone a la computadora. El cliente de zune se ejecuta automáticamente. En caso contrario, ejecútalo manualmente.

  2. Verifica que el software de Zune le reconozca el telefono conectado.

  3. Después que el teléfono este conectado, cierra el software de Zune.

  4. Abre una consola de línea de comando y navega al directorio WPConnect, puedes conseguirlo en alguna de las siguientes URL:

    Program Files\Microsoft SDKs\Windows Phone\v7.1\Tools\WPConnect

    Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Tools\WPConnect

  5. Navega al subdirectorio x86 o x64 apropiado.

  6. Ahora en la consola de comando, ingresa el comando: WPConnect.exe
    Recibirás una confirmación que tu dispositivo esta conectado. Ahora puedes ejecutar tu aplicación sin tener el software de Zune en ejecución.

Fuente:
Deploying and Testing on Your Windows Phone

Generations Apps – Día 25 – Agregando publicidad a tu aplicación

El SDK de Microsoft Advertising para Windows Phone te permite desplegar publicidad en tu aplicación. Cuando Microsoft Advertising Mobile Ads están integradas en tu aplicación, la red de Microsoft Advertising le entregará las publicidades a tus usuarios – y te pagará una cantidad de los ingresos.

Para hacer que tu aplicación reciba publicidades móviles, primero deberás crear una cuenta en el Microsoft pubCenter. Utilizarás pubCenter para crear AdUnits y registras tus aplicaciones para que se enlacen a tu cuenta con un ApplicationId.

pubCenter gestiona el ingreso que tus aplicaciones generan, y te paga tu porcentaje correspondiente. Una vez que crees la cuenta, registra tu aplicación, y asegúrate que incluya el identificador único que se le genera automáticamente al momento que creaste la aplicación para Windows Phone (lleva el nombre de ApplicationId). El ApplicationId enlaza tu cuenta con los ingresos generados por la publicidad de tus aplicaciones.

Cuando usas un AdUnit en tu aplicación, estas creando un espacio en la pantalla del teléfono para mostrar publicidad. Luego es que puedes configurar un AdUnit en el pubCenter. La configuración de un AdUnit define como una publicidad es desplegada en tu aplicación, y el tipo de publicación que el usuario verá. Después de configurar el AdUnit en el pubCenter, le es asignado un identificador único denominado AdUnitId.

Tu código debe incluir el ApplicationId y el AdUnitId para que tu aplicación Windows Phone pueda solicitar las publicidades a los servidores de Microsoft Advertising. Estos identificadores son usados para identificar el AdUnit que mostrara la aplicación y la cuenta en la que va a recibir el ingreso.

Solo toma unos cuantos pasos sencillos para registrarse en el pubCenter, gestionar tus ingresos, e integrar las publicidades móviles de Microsoft Advertising a tu aplicación. Para mayor información de integración, puedes dar clic aquí…

Fuente:
Advertising in Windows Phone Applications

Generation Apps – Día 24 – Crear aplicaciones de prueba para Windows Phone

El Windows Phone Store te permite diseñar en implementar modos de prueba de tu aplicación. La experiencia muestra que usuarios disfrutan probar una aplicación mas limitada antes de comprarla.

La plataforma Windows Phone Application te facilita la capacidad de proveer versiones de prueba y completas dentro de un mismo contenedor XAP. Usuarios deseando comprar una aplicación que están probando pueden hacerlo con una experiencia muy similar al Windows Phone Store.

No hay restricciones acerca de como tu diseñes la experiencia de prueba de tu aplicación. Puedes determinar el grado de funcionalidad que le quieres exponer al usuario, ya sea el modo de prueba tenga una duración limitada, o como quieres alentar al usuario a comprar tu aplicación. También puedes determinar si los datos y estados de la aplicación son mantenibles si un usuario desea descargar la versión de prueba de la aplicación.

Cuando quieras publicar un modo de prueba de aplicación al Windows Phone Store, marca el check box de Trial Application y el cliente del Windows Phone Store mostrará un botón Try para descargar la aplicación en modo de prueba.

Visión General de Modo de Prueba

Para implementar un modo de prueba de tu aplicación, debes definir e implementar como el comportamiento de prueba difiere del comportamiento de la versión completa de la aplicación. Para ejecutar la aplicación en el modo correcto cuando es ejecutado por el usuario, tu código debe determinar si la aplicación se esta ejecutando en versión de prueba o completa. Para proveer una ruta de compra tu código debe ejecutar el cliente del Windows Phone Store.

El estado de prueba/full de la ejecución de derechos del usuario para una aplicación son mantenidos en una licencia. Cuando el usuario prueba un aplicación, Licencias de prueba no expiran pero cuando el usuario compra la versión completa, se descarga la licencia completa de la aplicación.

Para determinar si la licencia en la aplicación instalada en un Windows Phone es modo Prueba o Completa, Windows Phone 7 provee  métodos que pueden retornar TRUE si la aplicación esta ejecutándose bajo la licencia de prueba y FALSE si la aplicación se esta ejecutando bajo una licencia completa.

Para permitir a un usuario corriendo una aplicación de prueba y desea comprar la versión completa, Windows Phone 7 provee métodos para iniciar la aplicación cliente de Windows Phone  Store en la pagina de compra de la aplicación.

Desarrolladores del Framework XNA deberán usar la clase GamerServices.Guide para crear la experiencia de prueba y compra. Utiliza la propiedad Guide.IsTrialMode para obtener el tipo de licencia actual y el método Guide.ShowMarketplace para iniciar la experiencia de compra del videojuego.

Aplicaciones de Silverlight pueden usar métodos del Framework XNA ya descritos en el párrafo anterior o usando el método IsTrial() para obtener el tipo de licencia actual directamente, y el método Show() de la clase MarketplaceDetailTask para iniciar la experiencia de compra.

Implementando el modo de prueba

Determinando el estado de modo prueba y navegación hacia el Windows Phone Store para la compra de la aplicación debe ser simulada por tu código cuando estas probando o depurando tu aplicación. Métodos para esta funcionalidad no funcionan en modos de debug o testing ya que al requerir la licencia de la aplicación debe estar completa y publicada en el Store.

Aplicaciones que usan el Framework XNA deberían siempre usar la clase GamerServices.Guide para usar esta funciones. Esta clase posee funcionalidades de simulación de  modos de prueba y compra.

Aplicaciones de Silverlight pueden utilizar la misma clase GamerServices.Guide o implementar su propio comportamiento personalizado. Usando llamadas de GamerServices.Guide en una aplicación Silverlight puede ahorrarte trabajo simulando el estado de licencia de prueba durante el momento de depuración y testing. Usando métodos como LicenceInformation.IsTrial y MarketplaceDetailTask.Show permiten mas oportunidades para personalizar tus métodos de depuración y testing.

Buenas practicas para Modos de Prueba

  • Aplicaciones XNA deberían siempre utilizar la clase GamerServices.Guide para implementar modos de prueba.

  • Al asignar la bandera Guide.SimulateTrialMode a TRUE, siempre enciérralos en un bloque #if DEBUG / #endif

  • Revisar el estado IsTrial() siempre cuando la aplicación cargue o resuma su ejecución.

  • No dependas de modos de prueba de tiempo limitado para proteger el valor de tu aplicación. Si no se valida esto correctamente, el usuario puede simplemente re-instalar tu aplicación para utilizar nuevamente todas las funcionalidades que ofrece.
  • Provee una forma fácil a los usuarios para comprar la aplicación una vez instalada en modo de prueba.

  • Informa al usuario el por que deberían comprar la aplicación completa. Típicamente en el caso de los juegos, la aplicación muestra screenshots de mas niveles, ítems y puntos que pueden alcanzar si compran la versión completa.

Fuente:
Creating Trial Applications Overview for Windows Phone

Generation Apps – Día 23 – Localizar tu aplicación

Este tópico describe como separar recursos localizables del código creando archivos de recursos idioma-específicos. Visual Studio utiliza estos archivos para crear ensamblados que le permitirán a tu aplicación soportar múltiples lenguajes.

Agregando un archivo de recurso a un proyectos y habilitando el soporte de localización

  1. Agrega un archivo de recurso para el lenguaje por defecto en tu aplicación

    • Abre el proyecto en Visual Studio

    • Agrega un archivo de recurso. En el Solution Explorer, clic derecho al nombre del proyecto, da clic en Add -> New Item

    • En la ventana de dialogo de New Item, selecciona Resources File y renombra el archivo a como lo desees (Ej: AppResources.resx). Este archivo contendrá los recursos para el lenguaje por defecto de la aplicación.

    • Identifica strings en tu aplicación y agrégalas al archivo de recurso. Puedes colocar un nombre, un valor y un comentario opcional por cada string. NOTA: El nombre debe ser único; hazlo lo mas descriptivo posible. El valor es el string que se mostrara en la interfaz al usuario final. Los comentarios son opcionales, sin embargo, son útiles en caso que se trabaje con grandes volúmenes de strings.

  2. Ahora agrega archivos de recursos adicionales por cada lenguaje que tu aplicación va a soportar. Cada archivo agregado deberá ser nombrado en el nombre correcto de cultura/lenguaje. Por ejemplo: para la cultura español de España, usa AppResources.es-ES.resx; para el lenguaje alemán de Alemania, usa AppResources.de-DE.resx.

  3. Define la cultura por defecto soportado por tu aplicación.

    • En el Solution Explorer, da clic derecho a tu proyecto, y selecciona Properties

    • Debajo de la pestaña Application, da clic al botón Assembly Information

    • En la lista de Neutral Language, selecciona default culture. Esto identifica el lenguaje de los strings en el archivo de recursos por defecto. Por Ejemplo, si el archivo de recurso por defecto es nombrado AppResources.resx, y los strings en el archivo están en ingles (United States), deberás seleccionar English (United States) como el lenguaje neutral del proyecto.

  4. Cierra el proyecto y abre el archivo de proyecto (<proyecto-nombre>.csproj) en un editor de texto. Localiza la etiqueta <SupportedCultures> y agrega los nombres de cada cultura adicional (lenguaje) que tu aplicación puede soportar. Deberás declarar tantas culturas como archivos .resx presentes en tu aplicación. Separa los nombres de lenguajes por un ‘;’. No debes agregar el idioma por defecto. Si tu aplicación tambien soporta aleman y español. La etiqueta quedaría:
    <SupportedCultures>de-DE;es-ES;</SupportedCultures>

Reemplazando strings dentro-del-código con astringes en un archivo de recurso

  1. En el Solution Explorer, abre un archivo de recurso y selecciona Public de la lista AccessModifier, en el tope del panel. Repite este paso por cada archivo de recurso en tu proyecto.

  2. Define una clase con la propiedad que apunta a los recursos. En el siguiente ejemplo, la clase LocalizesStrings contiene una propiedad que apunta al recurso AppResources en el namespace sdkGlobalizationCS:

    public class LocalizedStrings
    {
        public LocalizedStrings()
        {
        }
    
        private static sdkGlobalizationCS.AppResources localizedResources = new sdkGlobalizationCS.AppResources();
    
        public sdkGlobalizationCS.AppResources LocalizedResources { get { return localizedResources; } }
    }

    Si hay archivos de recursos adicionales en tu proyecto, puedes tener una clase LocalizedStrings con multiples propiedades, el cual cada uno retorna un recurso particular

  3. Abre el archivo App.xaml y agrega el siguiente código XAML a la sección <Application.Resources>

    <Application.Resources>
        <local:LocalizedStrings xmlns:local="clr-namespace:sdkGlobalizationCS" x:Key="LocalizedStrings" />
    </Application.Resources>
  4. Reemplaza aquellos valores de strings dentro del código con el siguiente código XAML:

    «{Binding Path=resourceFile.resourceName, Source={StaticResource LocalizedStrings}}»

    Donde resourceName es el nombre del recurso localizable, resourceFile es el nombre del apuntador que contiene el resourceName, y LocalizedStrings es el nombre asignado a una instancia de la clase que retorna el recurso.

    El siguiente XAML del ejemplo Globalization Sample se enlaza con el control ListBoxItem cn el string LangRegionNameFrFR retornado de la instancia de la clase LocalizedStrings.

    <ListBoxItem Content="{Binding Path=LocalizedResources.LangRegionNameFrFR, Source={StaticResource LocalizedStrings}}" />
  5. Repite el paso previo por cada string que quieres hacer localizable, en cada archivo XAML en tu aplicación que contiene contenido localizable.

  6. Compila tu aplicación – Y compilara una aplicación multilenguaje y mostrara al usuario una interfaz acorde a la configuración de idioma en su teléfono.

Localización para la barra de aplicación

En Windows Phone, se puede agregar una barra de aplicación en tu aplicación ya sea vía XAML o C#. Sin Embargo, en vista que la barra de aplicación no es un control de silverlight, no soporta el data binding dinámico para actualizar los textos debajo de los botones acorde al idioma de la aplicación. Por esta razón, si quieres localizar estos strings, debes crear y actualizar la barra de aplicación al momento de ejecución. El siguiente código de ejemplo muestra una función que despliega la barra de aplicación haciendo uso de los recursos de localización que provee los valores de los strings. Este ejemplo asume que ya creaste una librería DLL de recursos de localización con entradas de strings llamadas «ButtonText» y «MenuItemText.»

// Helper function to build a localized ApplicationBar
private void BuildApplicationBar()
{     
    // Set the page's ApplicationBar to a new instance of ApplicationBar.     
    ApplicationBar = new ApplicationBar();     

    // Create a new button and set the text value to the localized string from AppResources.          
    ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("ApplicationIcon.png",UriKind.Relative));     
    appBarButton.Text = AppResources.ButtonText;     
    ApplicationBar.Buttons.Add(appBarButton);     

    // Create a new menu item with the localized string from AppResources.     
    ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.MenuItemText);         
    ApplicationBar.MenuItems.Add(appBarMenuItem);
}

Fuente:
How to: Build a Localized Application for Windows Phone

Generation Apps – Día 22 – Implementar agentes de segundo plano en tu aplicación

Los agentes de segundo plano y las tareas programadas realizan tareas en segundo plano, aun si la aplicación de primer plano no esta abierta. Los diferentes tipos de tareas programadas están diseñadas para los diferentes tipos de situaciones de proceso de segundo plano y por eso tienen diferentes comportamientos y restricciones. Aprende como implementar una aplicación que usa una tarea programada para registrar un agente de segundo plano. También entenderás la programación, duración y limitaciones de las tareas programadas.

Creando una aplicación que usa Tareas Programadas

Para crear una aplicación que usa tareas programadas, debes seguir los siguientes pasos:

  1. En Visual Studio, crea un nuevo proyecto Aplicación Windows Phone. Esta plantilla se encuentra en la categoría de Silverlight para Windows pone

  2. Ahora, agrega un proyecto de tipo Tarea Programada a tu solución. Del menú Archivo, selecciona Agregar -> Nuevo Proyecto. En la ventana de dialogo de Agregar Nuevo proyecto, selecciona Agente de Tareas Programadas Windows Phone. Deja el nombre por defecto, ScheduledTaskAgent1, y da clic a OK.

  3. En tu proyecto de primario, debes agregar una referencia hacia el proyecto tipo Agente. En el explorador de soluciones, realiza un clic derecho sobre el proyecto principal, y da clic a «Agregar Referencia…» y en la ventana de dialogo de Agregar Referencias, selecciona la pestana de Proyectos. Selecciona el proyecto tipo Agente, ScheduledTaskAgent1, y da clic a OK.

  4. En el explorador de soluciones, da doble clic a ScheduledAgent.cs del proyecto ScheduledTaskAgent1 para abrir el archivo. Veras que este archivo contiene la definición de una clase ScheduledAgent, el cual hereda la clase base ScheduledTaskAgent. Para este ejemplo, agrega la siguiente directiva para el namespace Shell y Sistema al tope del archivo.

    using Microsoft.Phone.Scheduler;
    using Microsoft.Phone.Shell;
    using System;
  5. Hay un método implementado en la clase, OnInvoke(ScheduledTask). Este método es invocado por el sistema operativo cuando la Tarea Programada es ejecutada. Aquí es donde deberías implementar el código que desees que se ejecute cuando el agente de segundo plano se ejecute. Cada aplicacion puede tener un solo ScheduledTaskAgent registrado a la vez, pero puedes programar este agente como un tipo de agente recurso-intensivo y periódico. Si tu aplicación usa ambas tareas ResourceIntensiveTask y PeriodicTask, puedes verificar que tipo de objetoScheduledTask que es pasado al método OnInvoke para determinar cual tarea el agente esta siendo invocado y ramificar tu ejecución de código como desees. Si utilizas un solo tipo de agente, no necesitaras revisar el tipo de objeto ScheduledTask. En este ejemplo, el agente ejecuta un objeto ShellToast desde OnInvoke, indicando el tipo de rarea programada para al agente que fue llamado. Este Toast te mostrara cual agente se esta ejecutando. Sin embargo, no se mostrara mientras que la aplicación se encuentre en modo foreground. Cuando el código de la tarea programada se haya completado, deberás invocar NotifyComplete()para informarle al sistema operativo que ya no necesitas seguir ejecutándolo. Esto permite al sistema operativo lograr gestionar otros agentes programados.

    protected override void OnInvoke(ScheduledTask task)
    {
      //TODO: Add code to perform your task in background
      string toastMessage = "";
    
      // If your application uses both PeriodicTask and ResourceIntensiveTask
      // you can branch your application code here. Otherwise, you don't need to.
      if (task is PeriodicTask)
      {
        // Execute periodic task actions here.
        toastMessage = "Periodic task running.";
      }
      else
      {
        // Execute resource-intensive task actions here.
        toastMessage = "Resource-intensive task running.";
      }
    
      // Launch a toast to show that the agent is running.
      // The toast will not be shown if the foreground application is running.
      ShellToast toast = new ShellToast();
      toast.Title = "Background Agent Sample";
      toast.Content = toastMessage;
      toast.Show();
    
      // If debugging is enabled, launch the agent again in one minute.
    #if DEBUG_AGENT
      ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(60));
    #endif
    
      // Call NotifyComplete to let the system know the agent is done working.
      NotifyComplete();
    }
  6. Ahora en los siguientes pasos, la aplicación de primer plano es modificada para permitir a los usuarios para habilitar y deshabilitar los agentes periódicos y recurso-intensivos. Primero abre el archivo MainPage.xamly pega el siguiente código XAML dentro del Grid «ContentPanel»

    Este código agrega dos conjuntos de controles, uno para cada tipo de agente. La mayoría de los controles son text blocks que estarán enlazados con los objetos ScheduledTask que representan los agentes de segundo plano, permitiéndote observar las propiedades de estos objetos. Además, un check box es agregado por cada tipo de agente que muestra y permite que el usuario habilite o deshabilite el estado de cada agente. Manejadores de eventos Checked y Unchecked, los cuales son utilizados para apagar y prender los agentes.

  7. En MainPage.xaml.cs, agrega la siguiente directiva en el tope de la pagina:

    using Microsoft.Phone.Scheduler;
  8. Crea dos variables que representaran cada tipo de agente. Estos serán objetos que estarán enlazados a la interfaz de usuario. El servicio de acción programada identifica únicamente tareas programadas por su propiedad Name (Nombre). Crea dos variables conteniendo los nombres que se usaran para los agentes.  Crea una variable booleana para usar como determinar si algún agente de segundo plano haya sido deshabilitado por el usuario final. Agrega las siguiente líneas de código dentro de la definición de la clase:

    public partial class MainPage : PhoneApplicationPage
    {
      PeriodicTask periodicTask;
      ResourceIntensiveTask resourceIntensiveTask;
    
      string periodicTaskName = "PeriodicAgent";
      string resourceIntensiveTaskName = "ResourceIntensiveAgent";
      public bool agentsAreEnabled = true;
  9. Ahora, implementa un método helper llamado StartPeriodicAgent. Este método primero usa un método Find(String) para obtener la referencia de la tarea periódica con el nombre especificado. Si el objeto de tarea programada no es null, entonces podrás invocar Remove(String) para excluir el registro del sistema. No puedes actualizar agentes directamente. Deberás remover y luego agregar. Luego, crea un nuevo objeto PeriodicTask y asignar su nombre en el constructor.

    Ahora establece la propiedad Descripción. Esta propiedad es requerida para agentes periódicos y es usado para describir el agente al usuario en la pagina de configuración de tareas de segundo plano en el dispositivo. Luego, invoca Add(ScheduledAction) para registrar el agente periódico  en el sistema. Una excepción InvalidaOperationException  es lanzado cuando Add es invocado si el usuario ha deshabilitado agentes de segundo plano por la aplicación, por ende es importante utilizar un bloque try. Si la llamada es exitosa, establece el contexto de datos del elemento de la interfaz de usuario asociada y mostrar las propiedades del objeto al usuario. Si la llamada lanza una excepción, verifica el mensaje de la excepción. Si el mensaje dice «BNS Error: The action is disabled», entonces deberías alertar al usuario que los agentes de segundo plano están deshabilitados.El método LaunchForTest(String, TimeSpan) es incluido para ejecutar el agente un minuto después que este método es invocado.  Antes de la llamada anterior a este método, se coloca un bloque #If para permitir que la aplicación se intercambie fácilmente entre modos de depuración y producción. Para habilitar este método, incluye la siguiente línea al tope de MainPage.xaml.cs:

    #define DEBUG_AGENT

    Ahora pega el siguiente método en la definición de la clase MainPage

    private void StartPeriodicAgent()
    {
      // Variable for tracking enabled status of background agents for this app.
      agentsAreEnabled = true;
    
      // Obtain a reference to the period task, if one exists
      periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
    
      // If the task already exists and background agents are enabled for the
      // application, you must remove the task and then add it again to update 
      // the schedule
      if (periodicTask != null)
      {
        RemoveAgent(periodicTaskName);
      }
    
      periodicTask = new PeriodicTask(periodicTaskName);
    
      // The description is required for periodic agents. This is the string that the user
      // will see in the background services Settings page on the device.
      periodicTask.Description = "This demonstrates a periodic task.";
    
      // Place the call to Add in a try block in case the user has disabled agents.
      try
      {
        ScheduledActionService.Add(periodicTask);
        PeriodicStackPanel.DataContext = periodicTask;
    
        // If debugging is enabled, use LaunchForTest to launch the agent in one minute.
    #if(DEBUG_AGENT)
        ScheduledActionService.LaunchForTest(periodicTaskName, TimeSpan.FromSeconds(60));
    #endif
      }
      catch (InvalidOperationException exception)
      {
        if (exception.Message.Contains("BNS Error: The action is disabled"))
        {
          MessageBox.Show("Background agents for this application have been disabled by the user.");
          agentsAreEnabled = false;
          PeriodicCheckBox.IsChecked = false;
        }
    
        if (exception.Message.Contains("BNS Error: The maximum number of ScheduledActions of this type have already been added."))
        {
          // No user action required. The system prompts the user when the hard limit of periodic tasks has been reached.
    
        }
        PeriodicCheckBox.IsChecked = false;
      }
      catch (SchedulerServiceException)
      {
        // No user action required.
        PeriodicCheckBox.IsChecked = false;
      }
    }

    NOTA: Agentes de segundo plano no son soportados en dispositivos de 256-MB de memoria RAM. Al intentar  trabajar con agentes en estos dispositivos arrojaran una excepción InvalidaOperationException. En lugar de manejar esta excepción en un bloque catch, tu aplicación debería verificar si se esta ejecutando en un dispositivo 256-MB antes de agregar un agente.

  10. Ahora implementaremos el método helper para la tarea tipo recurso-intensivo. Este método es idéntico al método para el agente periódico a excepción que este utiliza la clase ResoucerIntensiveTaskpara programar el agente y otro nombre es utilizado.

    private void StartResourceIntensiveAgent()
    {
      // Variable for tracking enabled status of background agents for this app.
      agentsAreEnabled = true;
    
      resourceIntensiveTask = ScheduledActionService.Find(resourceIntensiveTaskName) as ResourceIntensiveTask;
    
      // If the task already exists and background agents are enabled for the
      // application, you must remove the task and then add it again to update 
      // the schedule.
      if (resourceIntensiveTask != null)
      {
        RemoveAgent(resourceIntensiveTaskName);
      }
    
      resourceIntensiveTask = new ResourceIntensiveTask(resourceIntensiveTaskName);
    
      // The description is required for periodic agents. This is the string that the user
      // will see in the background services Settings page on the device.
      resourceIntensiveTask.Description = "This demonstrates a resource-intensive task.";
    
      // Place the call to Add in a try block in case the user has disabled agents.
      try
      {
        ScheduledActionService.Add(resourceIntensiveTask);
        ResourceIntensiveStackPanel.DataContext = resourceIntensiveTask;
    
        // If debugging is enabled, use LaunchForTest to launch the agent in one minute.
    #if(DEBUG_AGENT)
        ScheduledActionService.LaunchForTest(resourceIntensiveTaskName, TimeSpan.FromSeconds(60));
    #endif
      }
      catch (InvalidOperationException exception)
      {
        if (exception.Message.Contains("BNS Error: The action is disabled"))
        {
          MessageBox.Show("Background agents for this application have been disabled by the user.");
          agentsAreEnabled = false;
    
        }
        ResourceIntensiveCheckBox.IsChecked = false;
      }
      catch (SchedulerServiceException)
      {
        // No user action required.
        ResourceIntensiveCheckBox.IsChecked = false;
      }
    }
  11. Agrega una variable booleana a la clase, ignoreCheckBoxEvents. Esta variable será utilizada para habilitar o deshabilitar los eventos de CheckBox al inicializar la pagina.

    bool ignoreCheckBoxEvents = false;
  12. Ahora, agrega manejadores de eventos Checked y Unchecked para los controles CheckBox. Estos manejadores invocan los métodos Start y Stop previamente implementados, para ejecutar y detener los agentes. Si ignoreCheckBoxEvents esta en verdadero, los manejadores de eventos serán retornados sin realizar ninguna función.

    private void PeriodicCheckBox_Checked(object sender, RoutedEventArgs e)
    {
      if (ignoreCheckBoxEvents) 
        return;
      StartPeriodicAgent();
    }
    private void PeriodicCheckBox_Unchecked(object sender, RoutedEventArgs e)
    {
      if (ignoreCheckBoxEvents)
       return;
      RemoveAgent(periodicTaskName);
    }
    private void ResourceIntensiveCheckBox_Checked(object sender, RoutedEventArgs e)
    {
      if (ignoreCheckBoxEvents)
        return;
      StartResourceIntensiveAgent();
    }
    private void ResourceIntensiveCheckBox_Unchecked(object sender, RoutedEventArgs e)
    {
      if (ignoreCheckBoxEvents)
        return;
      RemoveAgent(resourceIntensiveTaskName);
    }
  13. El método RemoveAgent simplemente invoca Remove(String) dentro de un bloque Try para evitar que alguna excepción altere el comportamiento de la aplicación.

    private void RemoveAgent(string name)
    {
      try
      {
        ScheduledActionService.Remove(name);
      }
      catch (Exception)
      {
      }
    }
  14. El paso final es hacer override el método OnNavigatedTo(NavigationEventArgs) de la clase PhoneApplicationPage. Este método es invocado cada vez que el usuario navega a esta pagina. Ahora debes asignar la variable booleana ignoreCheckBoxEvents

    a verdadero para que los manejadores de eventos de los CheckBox estén esencialmente deshabilitados. Luego, usa el método Find(string) para verificar por agentes tipo periódico o recurso-intensivo registrados en el sistema y actualizar los controles CheckBox para reflejar el estado actual de la aplicación. Finalmente, asigna el valor de la variable ignoreCheckBoxEventsa falso.

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
      ignoreCheckBoxEvents = true;
    
      periodicTask = ScheduledActionService.Find(periodicTaskName) as PeriodicTask;
    
      if (periodicTask != null)
      {
        PeriodicStackPanel.DataContext = periodicTask;
      }
    
      resourceIntensiveTask = ScheduledActionService.Find(resourceIntensiveTaskName) as ResourceIntensiveTask;
      if (resourceIntensiveTask != null)
      {
        ResourceIntensiveStackPanel.DataContext = resourceIntensiveTask;
      }
    
      ignoreCheckBoxEvents = false;
    }

Fuente:
How to: Implement Background Agents for Windows Phone

Generation Apps – Día 21 – Acceder a la secuencia de imágenes de la cámara

Tu puedes crear una aplicación de cámara usando el API de la cámara para captura fotografías. En la lección del día de hoy te mostrare como desplegar el viewfinder de la cámara, disparar la cámara programáticamente, y salvar una fotografía tomada a la librería multimedia y en el almacenamiento aislado. Una vez que comprendas como crear una aplicación relacionada con la cámara, fácilmente estarás encaminado a implementar el flash y enfoque, cambiando la resolución de captura, y usando el botón físico de capturar imágenes.

Creando la interfaz de usuario de la cámara

En esta sección, crearemos una interfaz de usuario para la cámara que consiste en la región Viewfinder para desplegar las imágenes capturadas, y un botón disparador para capturar una imagen.

Creación del proyecto

  1. En Visual Studio 2010 Express para Windows Phone, crea un nuevo proyecto dando clic en Archivo –> Nuevo Proyecto

  2. En la ventana de nuevo proyecto. Expande las plantillas de Visual C#, y selecciona la plantilla Silverlight For Windows Phone

  3. Selecciona la plantilla Windows Phone Application. Coloca el nombre que desees para tu proyecto.

  4. Dale clic a OK. La pantalla de una Nueva aplicación para Windows Phone es desplegada

  5. Al momento de escoger la versión del S.O., asegúrate escoger la versión Windows Phone 7.1
  6. Da clic en OK. El nuevo proyecto es creado, y el archivo MainPage.xaml es abierto en el diseñado de Visual Studio

  7. Del menú de Proyecto, selecciona Add Reference. En la pestana de .NET, escoge Microsoft.XNA.Framework y luego da clic a OK.

  8. En MainPage.xaml, actualiza el elemento phone:PhoneApplicationPage con el siguiente código:

    SupportedOrientations="Landscape" Orientation="LandscapeLeft"
        shell:SystemTray.IsVisible="False"

    Esto configura la pagina para soportar la orientación horizontal y esconder la bandeja del sistema.

  9. Ahora en MainPage.xaml, reemplaza el Grid nombrado LayoutRootcon el siguiente código:

    <!--LayoutRoot is the root grid where all page content is placed-->
        <Grid x:Name="LayoutRoot" Background="Transparent">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="640" />
                <ColumnDefinition Width="160" />
            </Grid.ColumnDefinitions>
    
            <Canvas x:Name="viewfinderCanvas" Width="640" Height="480" 
                       HorizontalAlignment="Left" >
    
                <!--Camera viewfinder -->
                <Canvas.Background>
                    <VideoBrush x:Name="viewfinderBrush" />
                </Canvas.Background>
             </Canvas>
    
            <!--Button StackPanel to the right of viewfinder>-->
            <StackPanel Grid.Column="1" >
                <Button x:Name="ShutterButton" Content="SH" 
                 Click="ShutterButton_Click" FontSize="26" 
                 FontWeight="ExtraBold" Height="75" />
            </StackPanel>
    
            <!--Used for debugging >-->
            <TextBlock Height="40" HorizontalAlignment="Left" Margin="8,428,0,0" 
             Name="txtDebug" VerticalAlignment="Top" Width="626" FontSize="24" 
             FontWeight="ExtraBold" />
        </Grid>

    Este código crea una región Viewfinder de 640 x 480 pixeles con un control StackPanel que contiene un botón disparador. Ahora Implementaremos el evento ShutterButtonClick en los siguientes pasos.

  10. Dirígete al código C# MainPage.xaml.cs y agrega las siguientes directivas en la parte superior de la pagina:

    // Directives
    using Microsoft.Devices;
    using System.IO;
    using System.IO.IsolatedStorage;
    using Microsoft.Xna.Framework.Media;
  11. Ahora en la clase MainPage, declara los siguientes atributos arriba del constructor:

    // Variables
    private int savedCounter = 0;
    PhotoCamera cam;
    MediaLibrary library = new MediaLibrary();
  12. Para crear la aplicación de cámara, la capacidad de la cámara tiene que ser declarado en el archivo de manifesto del aplicación. Abre el archivo WMAppManifest.xmly confirma el siguiente elemento se encuentra presente:

    <Capability Name="ID_CAP_ISV_CAMERA"/>
  13. (Opcional) Si quieres que tu aplicación utilice cámara frontal, adicionalmente se debe agregar la siguiente capacidad en los elementos Capabilities en el archivo de manifesto de la aplicación:

    <Capability Name="ID_HW_FRONTCAMERA"/>

Implementando Viewfinder y eventos de la cámara

Para implementar el viewfinder, deberás establecer la fuente ViewfinderBrush en la cámara del Windows Phone. Además de esto implementaremos varios eventos relacionados de la cámara como la inicialización, captura completada, y disponibilidad de imagen.

Para implementar los eventos de cámara

  1. En MainPage.xaml.cs, agrega el siguiente código a la clase MainPage:

    //Code for initialization, capture completed, image availability events; also setting the source for the viewfinder.
    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
    {
       // Check to see if the camera is available on the device.
       if ((PhotoCamera.IsCameraTypeSupported(CameraType.Primary) == true) ||
          (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing) == true))
       {
          // Initialize the camera, when available.
          if (PhotoCamera.IsCameraTypeSupported(CameraType.FrontFacing))
          {
             // Use front-facing camera if available.
             cam = new Microsoft.Devices.PhotoCamera(CameraType.FrontFacing);
          }
          else
          {
             // Otherwise, use standard camera on back of device.
             cam = new Microsoft.Devices.PhotoCamera(CameraType.Primary);
          }
    
          // Event is fired when the PhotoCamera object has been initialized.
          cam.Initialized += new EventHandler<Microsoft.Devices.CameraOperationCompletedEventArgs>(cam_Initialized);
    
          // Event is fired when the capture sequence is complete.
          cam.CaptureCompleted += new EventHandler<CameraOperationCompletedEventArgs>(cam_CaptureCompleted);
    
          // Event is fired when the capture sequence is complete and an image is available.
          cam.CaptureImageAvailable += new EventHandler<Microsoft.Devices.ContentReadyEventArgs>(cam_CaptureImageAvailable);
    
          // Event is fired when the capture sequence is complete and a thumbnail image is available.
          cam.CaptureThumbnailAvailable += new EventHandler<ContentReadyEventArgs>(cam_CaptureThumbnailAvailable);
    
          //Set the VideoBrush source to the camera.
          viewfinderBrush.SetSource(cam);
       }
       else
       {
          // The camera is not supported on the device.
          this.Dispatcher.BeginInvoke(delegate()
          {
          // Write message.
          txtDebug.Text = "A Camera is not available on this device.";
          });
    
          // Disable UI.
          ShutterButton.IsEnabled = false;
       }
    }
    protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
    {
       if (cam != null)
       {
          // Dispose camera to minimize power consumption and to expedite shutdown.
          cam.Dispose();
    
          // Release memory, ensure garbage collection.
          cam.Initialized -= cam_Initialized;
          cam.CaptureCompleted -= cam_CaptureCompleted;
          cam.CaptureImageAvailable -= cam_CaptureImageAvailable;
          cam.CaptureThumbnailAvailable -= cam_CaptureThumbnailAvailable;
       }
    }
  2. En MainPage.xaml.cs, agrega el siguiente código a la clase MainPage:
    // Update the UI if initialization succeeds.
    void cam_Initialized(object sender, Microsoft.Devices.CameraOperationCompletedEventArgs e)
    {
       if (e.Succeeded)
       {
          this.Dispatcher.BeginInvoke(delegate()
          {
             // Write message.
             txtDebug.Text = "Camera initialized.";
          });
       }
    }

    Este código utiliza el evento de la cámara Initialize, y actualiza el TextBlock nombrado txtDebug. El método BeginInvoke es requerido para actualiza el estado porque la interfaz de la aplicación se ejecuta en otro hilo de proceso diferente.

  3. En MainPage.xaml.cs, agrega el siguiente código a la clase MainPage:
    // Ensure that the viewfinder is upright in LandscapeRight.
    protected override void OnOrientationChanged(OrientationChangedEventArgs e)
    {
         if (cam != null)
         {
              // LandscapeRight rotation when camera is on back of device.
              int landscapeRightRotation = 180;
    
              // Change LandscapeRight rotation for front-facing camera.
              if (cam.CameraType == CameraType.FrontFacing) landscapeRightRotation = -180;
    
              // Rotate video brush from camera.
              if (e.Orientation == PageOrientation.LandscapeRight)
              {
                   // Rotate for LandscapeRight orientation.
                   viewfinderBrush.RelativeTransform = new CompositeTransform() 
                   { CenterX = 0.5, CenterY = 0.5, Rotation = landscapeRightRotation };
              }
              else
              {
                   // Rotate for standard landscape orientation.
                   viewfinderBrush.RelativeTransform = new CompositeTransform() 
                   { CenterX = 0.5, CenterY = 0.5, Rotation = 0 };
              }
         }
    
         base.OnOrientationChanged(e);
    }

    Este código asegura que el viewfinder, viewFinderBrush esta orientado de la manera correcta en la manera en que el usuario este sosteniendo el Windows Phone. Si la cámara frontal esta siendo utilizada, el brush correspondiente debe ser rotada a la dirección opuesta como si se encontrara en la parte trasera del dispositivo.

  4. En MainPage.xaml.cs, agrega el siguiente código a la clase MainPage:

    private void ShutterButton_Click(object sender, RoutedEventArgs e)
    {    if (cam != null)    {       try       {          // Start image capture.          cam.CaptureImage();       }       catch (Exception ex)       {          this.Dispatcher.BeginInvoke(delegate()             {             // Cannot capture an image until the previous capture has completed.             txtDebug.Text = ex.Message;             });       }    }
    }
    void cam_CaptureCompleted(object sender, CameraOperationCompletedEventArgs e)
    {    // Increments the savedCounter variable used for generating JPEG file names.    savedCounter++;
    }

    Este código implementa los eventos del botón disparador y captura completada. El botón disparador es el elemento que agregamos en el código XAML para capturar fotografías con la cámara. El evento de captura completada es utilizado en este proyecto para incrementar la variable contador savedCounter. Es utilizado para la siguiente sección para nombrar las imágenes JPEG guardadas.

Guardando fotografías a la galería multimedia

Para una aplicación de cámara para Windows Phone 7.1, dos imágenes son capturadas cuando una foto es tomada. Una es la imagen con la resolución máxima, y la segunda es una imagen thumbnail usados para mostrar una versión mas reducida para mostrar en la galería de imágenes. Esta sección explica como guardar la imagen con resolución máxima en la librería multimedia del dispositivo. También aprenderá como salvar una imagen con resolución máxima y la imagen thumbnail en el almacenamiento aislado.

Para guardar la imagen en la librería multimedia y almacenamiento aislado

  1. En MainPage.xaml.cs, agrega el siguiente código a la clase MainPage:

    // Informs when full resolution picture has been taken, saves to local media library and isolated storage.
    void cam_CaptureImageAvailable(object sender, Microsoft.Devices.ContentReadyEventArgs e)
    {
       string fileName = savedCounter + ".jpg";
    
       try
       {   // Write message to the UI thread.
          Deployment.Current.Dispatcher.BeginInvoke(delegate()
          {
          txtDebug.Text = "Captured image available, saving picture.";
          });
    
          // Save picture to the library camera roll.
          library.SavePictureToCameraRoll(fileName, e.ImageStream);
    
          // Write message to the UI thread.
          Deployment.Current.Dispatcher.BeginInvoke(delegate()
          {
          txtDebug.Text = "Picture has been saved to camera roll.";
          });
    
          // Set the position of the stream back to start
          e.ImageStream.Seek(0, SeekOrigin.Begin);
    
          // Save picture as JPEG to isolated storage.
          using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
          {
             using (IsolatedStorageFileStream targetStream = isStore.OpenFile(fileName, FileMode.Create, FileAccess.Write))
             {
                // Initialize the buffer for 4KB disk pages.
                byte[] readBuffer = new byte[4096];
                int bytesRead = -1;
    
                // Copy the image to isolated storage. 
                while ((bytesRead = e.ImageStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
                {
                   targetStream.Write(readBuffer, 0, bytesRead);
                }
             }
          }
    
          // Write message to the UI thread.
          Deployment.Current.Dispatcher.BeginInvoke(delegate()
          {
             txtDebug.Text = "Picture has been saved to isolated storage.";
          });
       }
       finally
       {
          // Close image stream
          e.ImageStream.Close();
       }
    }
    
    // Informs when thumbnail picture has been taken, saves to isolated storage
    // User will select this image in the pictures application to bring up the full-resolution picture. 
    public void cam_CaptureThumbnailAvailable(object sender, ContentReadyEventArgs e)
    {
       string fileName = savedCounter + "_th.jpg";
    
       try
       {
          // Write message to UI thread.
          Deployment.Current.Dispatcher.BeginInvoke(delegate()
          {
          txtDebug.Text = "Captured image available, saving thumbnail.";
          });
    
          // Save thumbnail as JPEG to isolated storage.
          using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
          {
             using (IsolatedStorageFileStream targetStream = isStore.OpenFile(fileName, FileMode.Create, FileAccess.Write))
             {
                // Initialize the buffer for 4KB disk pages.
                byte[] readBuffer = new byte[4096];
                int bytesRead = -1;
    
                // Copy the thumbnail to isolated storage. 
                while ((bytesRead = e.ImageStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
                {
                   targetStream.Write(readBuffer, 0, bytesRead);
                }
             }
          }
    
          // Write message to UI thread.
          Deployment.Current.Dispatcher.BeginInvoke(delegate()
          {
             txtDebug.Text = "Thumbnail has been saved to isolated storage.";
          });
       }
       finally
       {
          // Close image stream
          e.ImageStream.Close();
       }
    }

    Este código implementa los eventos CaptureImageAvailable y CaptureThumbnailAvailable. El primer método guarda la imagen con resolución máxima en la librería multimedia y en almacenamiento aislado. El segundo método te muestra como se guarda una imagen thumbnail en almacenamiento aislado.

  2. En el dispositivo, ejecuta la aplicación seleccionando el comando de menú Debug|Start Debugging. Presiona el botón SH. El textblock txtDebug te indicara el estado de las operaciones para guardar las imágenes en almacenamiento aislado. Después de cerrar la aplicación, puedes encontrar las fotos que tomaste con tu aplicación la carpeta camera roll en el hub de fotos. En la siguiente imagen te ilustra como debería aparecer la interfaz grafica en este punto.

    En este ejemplo. el botón disparador SH, es mostrado en la esquina superior derecha de la interfaz. Una imagen de mangos es mostrado en el control Canvas nombrado viewFinderCanvas.

Cabe mencionar que estos ejemplos es solo una introducción a lo que se puede implementar usando la cámara. Existen mas funcionalidades útiles que involucran la cámara como usar el Flash, el enfoque, la resolución de la imagen capturada, etc.

Fuente:
How to: Create a Base Camera Application for Windows Phone

Generation Apps – Día 20 – Agregando Notificaciones Push a tu aplicación

El servicio de Microsoft Notificación Push ofrece  a desarrolladores hacer un canal robusto, dedicado y persistente para enviar datos de una aplicación Windows Phone de un servicio web de una manera eficiente y efectiva

Cómo funciona

El siguiente diagrama muestra como una aplicación cliente ejecutándose en un Windows Phone puede solicitar un URL de notificación Push desde el servicio cliente Push (1). El Cliente de servicio Push negocia con el servicio de Microsoft de Notificaciones Push (MNPS por sus siglas en ingles) y retorna una URI de notificación a tu aplicación cliente (2 y 3). Tu aplicación cliente puede entonces enviar la IRI a tu servicio en la nube (4). Cuando tu servicio web tiene información para enviar hacia tu aplicación cliente, utiliza la URI para enviar una notificación Push al MNPS (5), el cual en su turno envía la notificación Push a la aplicación cliente que se este ejecutando en un dispositivo Windows Phone.

Tipos de notificación Push

Existen tres tipos de notificación Push que un servicio web puede utiliza cuando se envié información a una aplicación: Toast, Tile (o mosaico) y notificaciones Raw.

Notificación Toast

Una notificación Toast es mostrado en la parte superior de la pantalla para notificar al usuario de alguna eventualidad, como una noticia, novedad climática, tweet, mensaje instantáneo, etc. El Toast aparece por un periodo alrededor de 10 segundos, a menos que el usuario le realice un gesto Flick hacia la derecha para retirarlo de la pantalla. Si el usuario realice un gesto Tap sobre el, la aplicación que disparo la notificación se ejecutará.

Los elementos de una notificación Toast son:

  • Title: o titulo, es un texto en negrita que se muestra justo a la derecha del icono de la aplicación. Este texto esta definido como la propiedad Text1 en el esquema XML

  • Content: o contenido, es un texto corto que se muestra inmediatamente después del titulo. Esta propiedad esta definida como Text2 en el esquema XML

  • Parameter: o parámetro, es un valor que no es mostrado pero pasado a tu aplicación si el usuario realiza un gesto Tap sobre la notificación Toast. Este parámetro puede indicar en que pagina dela aplicación se debería cargar. También puede contener pares nombre-valor para pasar a la aplicación. Esto se define como la propiedad Param en el esquema XML

La cantidad de texto que puede ser mostrado depende de los caracteres utilizados en la notificación y la longitud del Title, el cual se encuentra en negrilla, mientras que el Content se encuentra con formato normal. Si el titulo lleva como valor Title, se podría mostrar alrededor de 40 caracteres antes que el mensaje sea truncado.

Windows Phone además, despliega una versión pequeña del icono de tu aplicación a la izquierda del titulo de tu aplicación. Bien es cierto que puedes definir que icono esta asociado a tu aplicación, no es posible pasar diferentes iconos para las notificación toast.

Notificación Tile (o Mosaico)

Una notificación Tile (o Mosaico) puede ser utilizado para actualizar el mosaico de tu aplicación que se encuentra en la pantalla inicio de Windows Phone. Estas propiedades del frente de un mosaico pueden ser actualizadas utilizando una notificación mosaico:

  • Title: un string indicando el nombre de la aplicación. El titulo debe ser lo suficientemente corto para que se mantenga dentro del espacio del mosaico.

  • Background: una imagen desplegada al centro del mosaico. Recomiendo que siempre uses una imagen simple y minimalista.

  • Count: un entero no negativo que va de 1 hasta 99. Si el valor de Count no esta inicializado, o tiene valor 0, la imagen del circulo no será visible.

Estas propiedades de la parte trasera del mosaico puedes ser actualizadas usando la notificación Tile.

  • BackTitle: Un texto corto es mostrado en la parte inferior del mosaico. Debe caber dentro de una sola línea, y no puede ser tan largo que el ancho del mismo mosaico. El titulo puede ser hasta 15 caracteres de largo antes que sea truncado.

  • BackgroundImage: Una imagen que se muestra en el mosaico.

  • BackContent: Un string desplegado en esta cara del mosaico. El texto no puede sobrepasar los 40 caracteres aproximadamente antes que sea truncado.

Algunos puntos a considerar para las imágenes BackgroundImage y el BackBackgroundImage son las siguientes:

  • Las imágenes pueden ser .jpg o .png

  • Por razones de rendimientos y disponibilidad de red, considera usar recursos locales para las imágenes

  • Usando imágenes .png te permitirá utilizar transparencia, que podrías aprovechar para obtener el color del tema del SO.

  • Los mosaicos deben ser 173 x 173 pixeles, en caso que no lo sea, la imagen será escalada para alcanzar esta dimensión.

  • Puedes utilizar recursos locales o remotos para la imagen. Si lo usas como un recurso local, deberás instalarlo como parte del paquete .XAP

  • Si el usuario desactiva las notificaciones tipo Tile, el mosaico debería mostrar información genérica.
  • Https no soporta imágenes remotas.

  • Imágenes remotas deberán pesar menos de 80KB. Si sobrepasan este limite, no serán descargadas.

  • Imágenes remotas tienen que descargarse en menos de 30 segundos, de lo contrario no se descargaran.

  • Si las imágenes BackgroundImage y BackBackgroundImage no se cargan por alguna razón, ninguna de las demás propiedades de actualización serán cambiadas tampoco.

Notificaciones Raw

Puedes utilizar notificaciones Raw (o crudas) para enviar información a tu aplicación. Si tu aplicación no se esta ejecutando, la notificación Raw será descartada en el MPNS y no es enviado al dispositivo.

Fuente:
Push notifications for Windows Phone

Diseña un sitio como este con WordPress.com
Comenzar