1. ¿Qué es?
  2. Consideraciones a tener en cuenta antes de subir la app a PhoneGap Build
  3. Ripple
  4. Compilar una aplicación
  5. Compilación sin firma
  6. Compilación con firma (signing with keystore)
  7. config.xml
  8. Posibles errores al subir la aplicación a google play
  9. Hola Mundo
  10. Notificaciones
  11. Reproducción multimedia
  12. Geolocalización
  13. Uso de la cámara de fotos
  14. Lectura de ficheros
  15. Uso de varios frameworks
  16. Consejos para mejorar la aplicación

Phonegap

Server: irc.freenode.net
Channel: #phonegap

PhoneGap Build

Permite compilar en la nube. De esta forma no será necesario instalar los SDK de los sistemas para los que queremos compilar. Por otra parte, para compilar una aplicación para IOS es necesario un ordenador MAC. Esto lo podremos salvar utilizando PhoneGap Build.
https://build.phonegap.com/

Una vez registrados, la opción
upload an archive or index.html file
Nos permite subir tanto un archivo .zip como un archivo .html

Luego podremos instalar la aplicación en el móvil escaneando su código de barras la aplicación de android barcode scanner o bien descargar el apk.

Consideraciones a tener en cuenta antes de subir la app a PhoneGap Build

Habrá que eliminar el fichero phonegap.js del proyecto. Hacemos esto porque phonegapbuild requiere una librería diferente por cada plataforma y poner nosotros una librería concreta ocasionaría problemas al ejecutar la aplicación.

Para cargar la librería que phonegapbuild colocará utilizaremos la siguiente línea:

	
<script src="phonegap.js"></script>
	

Notas:

En las últimas versiones de Phonegap Build la compilación para BlackBerry, Web OS y Symbian no funciona.

Ripple

Simulador de aplicaciones móviles. Sirve tanto para aplicaciones web para móviles como para phonegap.

Podemos instalarlo desde la chrome store.

Tras la instalación, aparecerá el logo de Ripple a la derecha de la url de direcciones del navegador.

Para probar nuestra aplicación basta con acceder a la url de la misma y habilitar ripple (en lo sucesivo quedará habilitado para esta url).

Ya que estamos trabajando con la última versión de phonegap, esta será la que habrá que establecer por defecto en Ripple.

Por seguridad chrome no permite que los plugins (Ripple) accedan al sistema de archivos local. Por tanto, para poder testear nuestra aplicación necesitaremos que esté subida a un servidor, aunque sea local.

Si no funcionase Ripple (al pulsar en enable no hace nada), podemos pulsar en preferencias → herramientas → extensiones → Allow access to file URLs

Fotos de los iconos

drawable-ldpi 36x36 (icon.png)
drawable-mdpi 48x48 (icon.png)
drawable-hdpi 72x72 (icon.png)
drawable-xhdpi 96x96 (icon.png)

drawable-land-ldpi 320x200 (screen.png)
drawable-land-mdpi 480x320 (screen.png)
drawable-land-hdpi 800x480 (screen.png)
drawable-land-xhdpi 1280x720 (screen)

drawable-port-ldpi 200x320 (screen.png)
drawable-port-mdpi 320x480 (screen.png)
drawable-port-hdpi 480x800 (screen.png)
drawable-port-xhdpi 720x1280 (screen.png)

Compilar una aplicación

Requisitos previos

Instalar Apache Cordova

Primero habrá que instalar nodejs. Puedes hacerlo de dos formas.

  1. Ejecutando el script de instalación que se muestra en este enlace (recomendado). Este script, además de instalar nodejs configura correctamente los permisos necesarios para poder usarlo.
  2. Descargándolo de este enlace.

En este curso, usaremos Cordova.

	
$  sudo su 
$ cordova create my-app com.pablomonteserin.myapp #Es conveniente indicar un nombre de paquete o de lo contrario, cuando compilemos para subir a la tienda correspondiente se nos indicará que ese paquete ya estaba en uso
$ cd my-app
$ cordova platform add android

Compilación sin firma

cordova build android	

Generar una firma (keystore)

Si estamos usando el Android Studio, podemos generar una firma o vincular nuestro proyecto a una firma ya existente desde el menú Build -> Generate Signed APK

Compilar

El siguiente comando

sudo cordova build

Ejecutado desde la raíz de nuestro proyecto cordova, mueve el contenido de la carpeta www a las carpetas de las plataformas que hayamos añadido a nuestro proyecto.

En Android

Abriremos la carpeta platforms/android desde el Android Studio y compilaremos desde aquí

config.xml - versionado

Modificaré el atributo version del nodo widget del fichero config.xml situado en la raíz de nuestro proyecto phonegap. Esto modificará automáticamente atributo opcional android-versionCode del mismo nodo, que es el que a su vez modificará el atributo android:versionCode del AndroidManifest.xml generado.

Posibles errores al subir la aplicación a google play (https://play.google.com/apps/publish) utilizando el apk generado por phonegap build

You need to use a different package name because "com.phonegap.www" already exists in Google Play.
→ habrá que definir un paquete para la aplicación:

You uploaded an APK that was signed in debug mode. You need to sign your APK in release mode.
Habrá que firmar la aplicación.

Hola mundo - Phonegap

	
<doctype html>
<html>
	<head>
		<meta charset="UTF-8">
		<!-- la siguiente línea evita que los números de teléfono se conviertan en links clickables-->
		<meta name="format-detection" content="telephone-no">
		<!-- la siguiente línea evita que el usuario pueda hacer zoom sobre la aplicación, como ocurre con una página web, -->
		<meta name="viewport" content="user-scalable=no, initial-scale=1, minimum-scale=1, maximum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi">
		<title>Mi aplicación</title>
		<link rel="stylesheet" href="css/estilos.css">
		<script src="cordova-2.5.0.js"></script>
		<script>
			document.addEventListener("deviceready", onDeviceReady, false);
			function onDeviceReady(){
				alert("hola mundo!");
			}
		</script>
	</head>
	<body>
		<div>Place holder</div>
	</body>
</html>
	
Ver ejemplo

Notificaciones (beep, vibrate alert)

	
navigator.notification.alert("Este es un mensaje");

// Beep three times
navigator.notification.beep(3);

// Vibrate for 2 seconds
navigator.notification.vibrate(2000);
	
Ver ejemplo.

Reproducción multimedia

		
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady(){
	//var reproductor = new Media("http://www.pablomonteserin.com/curso/javascript/phonegap_exercises/2_media/Hakuna.mp3", onSuccess, onError);

	//Para cargar archivos locales (en android) tendremos que indicar la ruta de la siguiente forma:
	var reproductor = new Media("/android_asset/www/Hakuna.mp3", onSuccess, onError);

	reproductor.play();
}
function onSuccess(){
	alert("reproduccionOK");
}

function onError(error){
	console.log(error.message);
}
		
	
Ver ejemplo.

Geolocalización


<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<link rel="stylesheet" type="text/css" href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css">
<script type="text/javascript">
/*
-PhoneGap Documentation: The Android 2.x simulators will not return a geolocation result unless the enableHighAccuracy option is set to true.
- Para que se ejecute deviceReady, será necesario ejecutar la aplicación en Ripple, en el emulador, o en móvil; no basta sólo con ejecutar en un navegador, aunque sea a través de localhost.
- Si ejecutamos en el emulador es probable que sea necesario mandar las coordenadas de nuestra ubicación para que funcione la geolocalización (En eclipse: Window → show view → Emulator Control Location Controls → Manual → Send)
*/
document.addEventListener("deviceReady", deviceReady, false);
function deviceReady(){
	navigator.geolocation.getCurrentPosition(onGeoSuccess, onGeoError, { enableHighAccuracy: true });
}

function onGeoSuccess(position){
	var lat = position.coords.latitude;
	var lon = position.coords.longitude;
	var currentPosition = new google.maps.LatLng(lat, lon);
	var mapoptions = {
		zoom : 12,
		center: currentPosition,
		mapTypeId: google.maps.MapTypeId.ROADMAP
	};
	var map = new google.maps.Map(document.getElementById("map"), mapoptions);
	var marker = new google.maps.Marker({
		position: currentPosition,
		map: map
	});
}
function onGeoError(error){
	if(error==1){
		alert("turn on geolocation services")
	}else{
		alert("geoError: " + error);
		alert("geoError: " + error.message);
	}
}
	
Geolocation

Uso de la cámara de fotos

		
document.addEventListener("deviceready", onDeviceReady, false);
var valores;

function onDeviceReady(){
	alert("inicia");
	capturador = navigator.device.capture;
}

function captura_audio(){
	alert("captura audio");
	capturador.captureAudio(capturaOK, capturaError);
}
function captura_video(){
	alert("captura video");
	capturador.captureVideo(capturaOK, capturaError);
        navigator.camera.getPicture(onSuccess, onFail, { quality: 50 }); 
}
function captura_imagen(){
	alert("captura imagen");
	capturador.captureImage(capturaOK, capturaError);

}
function capturaOK(archivos){
	alert("capturaOK")	
	for(var i =0; i<archivos.length; i++){
		var ruta = archivos[i].fullPath;
			alert(ruta)	
	}
}
function capturaError(){
	alert("error en la captura");
}
		
	
código qr aplicación phonegap Descargar APK.

Notas:

En el caso de Android, si un Activity es totalmente eclipsado por otro, será parado, almacenando su estado e información. Sin embargo, es posible que sea eliminado por el sistema cuando los requerimientos de memoria así lo estimen. Por tanto, al volver del capturador de multimedia es posible que la aplicación sea reiniciada, en lugar de ir al método capturaOK.

Lectura de ficheros

		
document.addEventListener("deviceready", function(){
	alert("deviceready");
	window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, archivosDisponibles, function(){
		alert("No esta disponible el sistema de archivos");
	});
}, false);

function archivosDisponibles(fileSystem){
//fileSystem.root nos da la carpeta de almacenamiento persistente asociada a nuesta aplicación, de donde podremos escribir y leer archivos
	alert(fileSystem.root.fullPath);
	fileSystem.root.getFile("readme.txt", null, archivoLeido, function(){
		alert("No esta disponible el sistema de archivos 2");
	});
}

function archivoLeido(archivo){
	alert("archivo leido");
	archivo.file(function(archivo){
		var reader = new FileReader();
		reader.onloadend = function(evento){
			alert(evento.target.result);
		}
		reader.readAsText(archivo);
	}, function(){
		alert("Error");
	});
}
		
	
Ver ejemplo.

Notas:

Probablemente tengamos que editar el contenido de un fichero readme.txt ubicado en la raíz del sistema de ficheros que vemos al conectar nuestro móvil al ordenador para tener una información que leer.

Uso de varios frameworks

Si estamos usando deviceReady y jQuery y jQueryMobile, es probable que queramos asegurarnos de que todo este cargado antes de hacer nuestras llamadas a los servicios del teléfono. Para ello, podemos usar el siguiente sistema:

/*DeviceReadyDeferred y jqmReadyDeferred son dos variables que utilizaremos como flags para controlar cuando el framework fue cargado.*/
var deviceReadyDeferred = $.Deferred();  
var jqmReadyDeferred = $.Deferred();	
document.addEventListener("deviceReady", deviceReady, false);
function deviceReady(){
	deviceReadyDeferred.resolve(); // el framework deviceReady fue cargado
}
/*Iniciaremos jQueryMobile cuando la section cuya id es firstpage esté cargada. Por tanto, deberé tener una página con la estructura propia de jQueryMobile*/
$(document).on("pageinit", "#firstpage",function(evt){
	$(document).bind("pageshow", "#firstpage",function(e, data){
		jqmReadyDeferred.resolve(); // el framework jquery mobile fue cargado	
	});
});

$.when(deviceReadyDeferred, jqmReadyDeferred).then(doWhenBothFrameworksLoaded);
function doWhenBothFrameworksLoaded() {
...
Ver ejemplo

Envío de información al servidor

Este sería el código que recogería la información enviada.

<?php
	$valor = $_REQUEST['valor'];
	echo $valor;

	$conexion = mysqli_connect('localhost', 'root', 'pp', 'test')
	or die("hubo un error al conectar con la base de datos");

	mysqli_set_charset($conexion, "utf8");
	$sql = "INSERT INTO usuario(name) VALUES('$valor')";
	mysqli_query($conexion, $sql)or die($sql);
?>

Consejos para mejorar la aplicación

No esperar a que la página esté totalmente cargada para acceder a la siguiente página

En lugar de solicitar la página y esperar que esté lista para cargarla, lo que haremos será cargar la siguiente página (para que el usuario se dé cuenta de que ha ocurrido algo), mostrar una ruedita de loading, y finalmente pintar la página cuando ya la tengamos.

Cachea tus datos

Cachea tus datos (ya sean estáticos o dinámicos) (en localStorage o en la base de datos).

displayUI();
//Primero cargo lo que hay en la cache y luego lo que viene del server.
cache.loadData().done()(function(data){
	ShowData();
});
server.loadData().done()(function(data){
	ShowData();
});

Haz las animaciones de una página a otra en CSS en lugar de Javascript

Esto incrementará la velocidad de la aplicación.

Cuando queramos ejecutar la animación, añadiremos al elemento un class que se encargará de hacerla.

Haz las animaciones CSS usando aceleración por hardware (llamando a translate3d(,,))

.page{
	Position:absolute; top:0; left:0; width:100%; height:100%; 
	transform:translate3d(0,0,0);
}
.page.left{
	transform: translate3d(-100%, 0, 0)
}
.page.center{
	transform:translate3d(0,0,0)
}
.page.right{
	transform: translate3d(100%, 0, 0);
}
.page.transition{
	transition-duration: .25s;
}

Podemos usar una librería para automatizar este proceso:
https://github.com/ccoenraets/PageSlider

Evitar el delay de 300ms de los clicks

Cuando hacemos click sobre un item, el sistema espera 300 ms para comprobar si se trata de un click o de un doble click.

Para evitarlo, podemos sustituir todos los clicks por touch events usando:
https://github.com/ftlabs/fastclick

Otros

icono de mandar un mail¡Contacta conmigo!
contacta conmigoPablo Monteserín

¡Hola! ¿En qué puedo ayudarte?