Una de las maneras más versátiles que tenemos para crear nuestra primera aplicación para múltiples dispositivos (IPhone, Android, WP7, etc.) es utilizar HTML + Javascript y adaptarlas un poco para cada uno de los dispositivos sobre los que queremos que funcione.
Como suele ocurrir, hay unas cuantas formas de crear aplicaciones HTML5 para móviles:
Las dos primeras tienen la (dudosa) ventaja de poder olvidarnos de las normativas que exigen los fabricantes en sus tiendas online, pero dicha aplicación no podrá acceder a todos los elementos del dispositivo, sino sólo a los que nos permita el navegador de cada uno. Hay muchos estándares de HTML5 que aún están en borrador y por lo tanto cada fabricante decide si lo implementa o no.
Con la tercera opción tenemos la gran ventaja de poder ir más allá de las limitaciones del navegador y comunicarnos con las API del dispositivo de una forma más directa, pero manteniendo la ventaja de utilizar HTML5 y javascript para definir tanto el aspecto como el comportamiento de la aplicación.
Vamos a centrarnos en esta última opción y desarrollaremos un ejemplo sobre la plataforma Windows Phone 7. Para las otras plataformas de desarrollo sólo cambiará en el contenedor, la aplicación HTML será siempre igual.
Más adelante veremos cómo nuestra aplicación Silverlight se comunicará con la aplicación HTML. Por ahora veamos qué va a hacer nuestra aplicación HTML5. Vamos a crear un canvas donde dibujar una pelota que se mueva según la inclinación del dispositivo. Para ello necesitaremos usar el evento devicemotion definido en un draft de HTML5 y utilizaremos esos valores para dar aceleración a la pelota.
<!DOCTYPE html>Hasta ahora hemos escrito una aplicación HTML simple y con sólo una línea "sospechosa", la que apunta a un script llamado WP7Bridge.js. Es el script que usaremos para hacer de puente entre el motor javascript y las API del teléfono.
Dentro de algún tiempo desde HTML5 tendremos acceso a gran parte de las apis y sensores que traen los nuevos dispositivos (cámara, brújula y giroscopio, etc…), pero hay que tener en cuenta que muchas de estas API aún están en borrador, algunos navegadores no la implementan y otros tienen que actualizarse muy a menudo porque el API va cambiando, dejando nuestras aplicaciones sin esa funcionalidad como pasó con el API de WebSocket no hace mucho.
En el caso de Windows Phone 7 tenemos acceso al API de geolocalización desde HTML5, pero aún no se ha implementado el acceso al acelerómetro. Para poder comunicarnos con el acelerómetro del dispositivo vamos a usar un método que ejecutará el evento devicemotion como si fuera un evento nativo, utilizando el método window.dispatchEvent:
// js receiver for the accelerometer
// from the phone, fires the devicemotion event
// as defined in http://www.w3.org/TR/orientation-event/
function wp7ExtensionsaccelerometerChanged(x, y, z, intervalms) {
//here we create a fake deviceorientation event!
var event = document.createEvent("Event");
event.initEvent("devicemotion", true, true);
event.acceleration = null;// new Acceleration();
event.accelerationIncludingGravity = new Acceleration();
event.accelerationIncludingGravity.x = parseFloat(x);
event.accelerationIncludingGravity.y = parseFloat(y);
event.accelerationIncludingGravity.z = parseFloat(z);
event.rotationRate = null;// new RotationRate();
event.interval = parseInt(intervalms);
window.dispatchEvent(event);
};
Este método lo almacenaremos en el fichero WP7Bridge.js y desde la parte nativa de la aplicación del dispositivo llamaremos a este método cada vez que se produzca un cambio en el acelerómetro. De esta manera podremos crear cualquier puente entre las capacidades del dispositivo y las aplicaciones HTML5. Para el caso del WP7 vamos a crear una aplicación Silverlight, que tiene acceso a los sensores del dispositivo, y que contendrá un control WebBrowser donde alojaremos nuestra aplicación.
Como ya os he comentado, nuestra aplicación HTML5 tendrá que vivir dentro de una aplicación del dispositivo, de esta manera podremos empaquetarla y distribuirla como cualquier otra aplicación. Para ello crearemos una solución de tipo Windows Phone con las herramientas e insertaremos un elemento WebBrowser en el Grid principal.
<!--ContentPanel - place additional content here-->Veréis que el control tiene una serie de propiedades:
En el código de la página XAML que contiene al WebBrowser crearemos nuestro puente que nos permitirá realizar llamadas al código Javascript. Crearemos una instancia del acelerómetro y en cada evento llamaremos a un método del componente browser que nos permitirá llamar a cualquier script definido en la página WebBrowser.InvokeScript.
public class Html5Bridge:IDisposablePara finalizar, en WP7.5 tendremos que usar algún truco más para poder cargar el contenido HTML local en el WebBrowser, pues no tenemos permiso para acceder directamente a los archivos que incluye nuestro archivo XAP. Para solucionarlo basta con copiar esos archivos al sistema de ficheros local justo en el momento de arranque de la aplicación:
private void Application_Launching(object sender, LaunchingEventArgs e)
{
string[] files = new string[] {
"107785__hans__tink.mp3",
"default.htm",
"WP7Bridge.js",
"main.css" };
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
store.CreateDirectory("html");
foreach (string file in files)
{
var info = Application.GetResourceStream(new Uri("html/" + file, UriKind.Relative));
if (info != null)
{
using (var writeStream = new IsolatedStorageFileStream("html" + file, FileMode.Create, store))
{
byte[] bytes;
using (var binaryReader = new BinaryReader(info.Stream))
{
bytes = binaryReader.ReadBytes((int)info.Stream.Length);
}
using (var writer = new BinaryWriter(writeStream))
{
writer.Write(bytes);
}
}
}
}
}
}
Escribiendo un mínimo de código para la plataforma, el cual será común al resto de nuestras aplicaciones HTML5, hemos conseguido que nuestra aplicación HTML5 funcione en Windows Phone 7.5. Para los demás dispositivos será muy parecido. Así suelen hacerlo plataformas como phonegap para permitir ejecutar el mismo código en todos los dispositivos.