[Windows Phone 8] NFC y Bluetooth (1 de N)

Hoy vamos a ver una de las novedades incluidas en Windows Phone 8 que tenía pendiente de diseccionar en el blog: NFC.

nfc-logo

Siglas de Near Field Communications. Esta tecnología nos permite interconectar dos dispositivos tan solo con hacer que se toquen entre sí. De esta forma, no tenemos que introducir claves para emparejar dos dispositivos, ni debemos preocuparnos por que cualquiera que esté cerca de nuestro dispositivo pueda acceder a él, la comunicación solo se establece entre dos dispositivos a una distancia máxima de 4cm. Por esto es por lo que se considera una tecnología de contacto. A diferencia del bluetooth, que permite distancias mucho mayores.

NFC permite transferir a datos a una velocidad de hasta 424Kbps, con lo que intentar traspasar grandes cantidades de información puede ser muy costoso. Por esto, se puede usar en conjunción con otras tecnologías como el Bluetooth. En Windows Phone 8 podemos emparejar dos dispositivos mediante NFC y automáticamente enlazar sus respectivos bluetooths para usarlos como canal de transferencia de datos más pesados, como por ejemplo imágenes. De la misma forma, mediante NFC podemos acceder a datos almacenados en tarjetas, etiquetas o stickers NFC sin energía.

Windows Phone 8 nos aporta dos clases principales para trabajar con NFC: PeerFinder y Proximity Device. Cada una de ellas está especializada en un tipo de comunicación.

PeerFinder

PeerFinder nos permite descubrir otras instancias de nuestra aplicación en un dispositivo cercano y crear una conexión entre ambas instancias usando el gesto de tocar los dispositivos entre ellos o mediante browsing. Si el dispositivo con el que nos emparejamos no dispone de nuestra aplicación, el propio sistema le ofrecerá obtenerla de la tienda, con lo que puede ser una gran forma de que un usuario contento le pase nuestra app a otro. Si por el contrario la aplicación está instalada pero no iniciada, el sistema la iniciará automáticamente. Para realizar esto, solo deberemos llamar al método Start de la clase PeerFinder:

   1: public void FindPeerApp()

   2: {

   3:     Windows.Networking.Proximity.PeerFinder.Start();

   4: }

Realmente fácil!! Si unimos dos dispositivos y en uno de ellos ejecutamos este código, en el otro veremos lo siguiente (en el caso de no tener nuestra app):

image

Podemos ir un paso más allá, controlando el estado de la conexión con el evento TriggeredConnectionStateChanged. Este evento nos informará sobre el progreso de la conexión, mediante seis estados diferentes:

   1: public void FindPeerApp()

   2: {

   3:     PeerFinder.TriggeredConnectionStateChanged += PeerFinder_TriggeredConnectionStateChanged;

   4:     PeerFinder.Start();

   5: }

   6:  

   7: async void PeerFinder_TriggeredConnectionStateChanged(object sender, TriggeredConnectionStateChangedEventArgs args)

   8: {

   9:     switch (args.State)

  10:     { 

  11:         case TriggeredConnectState.Listening:

  12:             break;

  13:         case TriggeredConnectState.PeerFound:

  14:             break;

  15:         case TriggeredConnectState.Connecting:

  16:             break;

  17:         case TriggeredConnectState.Completed:

  18:             break;

  19:         case TriggeredConnectState.Canceled:

  20:             break;

  21:         case TriggeredConnectState.Failed:

  22:             PeerFinder.Stop();

  23:             break;

  24:     }

  25: }

Listening nos indica que nuestra aplicación ha iniciado la comunicación y estamos esperando que el otro dispositivo finalice la conexión.

PeerFound nos indica que existe otro dispositivo cerca.

Connecting indica que hemos recibido una solicitud de conexión, sin haberla iniciado nosotros.

Completed nos indica que hemos completado la conexión. A partir de este momento podremos usar la clase StreamSocket para comunicarnos con el otro dispositivo.

Canceled indica que la conexión ha sido cancelada.

Failed indica que un error evitó llevar a cabo la conexión.

Nos queda por mencionar que podemos usar nuestra aplicación Windows Phone 8 para anunciarnos a una aplicación Windows 8, simplemente indicando la propiedad AlternateIdentities de la clase PeerFinder:

   1: public void FindPeerApp()

   2: {

   3:     PeerFinder.AlternateIdentities.Clear();

   4:     PeerFinder.TriggeredConnectionStateChanged += PeerFinder_TriggeredConnectionStateChanged;

   5:     PeerFinder.ConnectionRequested += PeerFinder_ConnectionRequested;

   6:     PeerFinder.Start();

   7: }

Simplemente sustituyendo “Win8AppId” por el id de nuestra aplicación Windows 8, obtendremos el mismo resultado que entre dos Windows Phone. Si la aplicación está instalada en Windows 8, se lanzará. Si no está instalada, el usuario será llevado a la tienda para que pueda descargarla.

Hasta ahora hemos visto como “anunciar” nuestra aplicación al mundo exterior. Pero si queremos realizar una conexión punto a punto entre dos dispositivos, necesitamos primero obtener la lista de dispositivos a los que podemos acceder. Esto podemos hacerlo usando el método FindAllPeersAsync de la clase PeerFinder, que nos devolverá una lista con los dispositivos disponibles:

   1: public async Task<IReadOnlyCollection<PeerInformation>> FindPeers()

   2: {

   3:     return await PeerFinder.FindAllPeersAsync();

   4: }

Una vez que tengamos una lista de dispositivos, podremos conectar con uno en concreto usando el método ConnectAsync, que recibe un parámetro PeerInformation que hemos obtenido previamente con el método FindAllPeersAsync:

   1: public async Task<StreamSocket> ConnectToPeer(PeerInformation peer)

   2: {

   3:     return await PeerFinder.ConnectAsync(peer);

   4: }

En el dispositivo remoto, se lanzará el evento ConnectionRequested para que podamos identificar el dispositivo que se está conectando. Al mismo tiempo se lanzará el evento TriggeredConnectionStateChanged con el estado Completed. En este paso podremos obtener el SocketStream que se ha creado con la conexión.

Si la llamada a ConnectAsync tiene éxito, nos devolverá una instancia válida de la clase StreamSocket, que usaremos para recibir y enviar datos entre los dispositivos. Esta clase tiene tres propiedades importantes:

Information, nos ofrece información, como su nombre indica, sobre la conexión activa: la clave de sesión (SessionKey), estadísticas de ancho de banda, ip local y remota…

InputStream, contendrá la información enviada por el dispositivo remoto al que nos hemos conectado. Podremos obtener estos datos mediante el método ReadAsync del que dispone.

OutputStream, es donde escribiremos la información que queramos enviar al dispositivo remoto, usando el método WriteAsync.

NOTA: A la hora de conectar dos dispositivos con la clase PeerFinder es muy importante que el dispositivo que está escuchando, maneje el evento ConnectionRequested, de lo contrario la conexión se rechazará automáticamente.

Aunque el emparejamiento se lleva a cabo mediante NFC, cabe destacar que al invocar el método FindAllPeersAsync, se pasará a usar el bluetooth entre ambos terminales para llevar a cabo el envío y recepción de datos.

¿Como podemos probar todo esto?

Bien, la respuesta rápida: con dos dispositivos Windows Phone 8. Da igual si tienes un 920 y un 8X, un 620 y un Samsung Ativ S, o un 820 y un 920. Todos salvo el Lumia 520, incluyen NFC. De todas formas, reconozco que lo más normal es que no todo el mundo tenga dos dispositivos en su casa para probar alegremente. Si no tienes un par de Windows Phone 8, puedes probar parte de las conexiones, las que se realizan mediante NFC, haciendo uso de los emuladores y una aplicación llamada Proximity Tapper. Simplemente tendrás que instalar esta aplicación, asegurarte de que el firewall no la bloquea y dejarla iniciada. La pantalla se parece a esta:

image

*Al iniciar la aplicación, puede dar un error de UDP, le damos a aceptar y funciona correctamente. Aunque es ciertamente preocupante, el proyecto lleva sin actividad hace tiempo.

Entonces, despliega tu aplicación en dos emuladores de Windows Phone 8, por ejemplo el  WVGA y el WXGA, cuando los emuladores arranquen, se añadirán a la pantalla de proximity tapper sus IPs y nombre de dispositivo.

image

Y ya lo tenemos listo. Solo tenemos que seleccionar los dispositivos de la lista y presionar el botón Tap Selected Devices. Voila! los emuladores se emparejarán por NFC y si ejecutamos el método PeerFinder.Start en uno de ellos, el otro mostrará el aviso de la aplicación.

Lamentablemente, no he conseguido que funcione con el bluetooth, por lo que la llamada a FindAllPeersAsync o ConnectAsync, falla en los emuladores. Pero por lo menos podremos probar escenarios de emparejamiento con NFC, en el siguiente artículo hablaremos de ProximityDevice y como enviar mensajes sencillos usando solo NFC, sin Bluetooth o Wifi Direct y para eso nos vendrá de perlas este “emulador de NFC”.

Y Fin… Por ahora!!

Con esto, llegamos al fin del primer artículo sobre NFC. En próximos artículos hablaremos de como conectarnos a otros dispositivos, como usar la clase ProximityDevice y sobre el standard NDEF. Hasta entonces, os dejo el código fuente de la aplicación de ejemplo, integrando PeerFinder con MVVM.

Como siempre, un saludo y Happy Coding!!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *