jueves, 12 de junio de 2014

Solución Made In Miguel

Seguimos trabajando en la aplicación de Cordova-Pet y nos está llevando por el camino de la amargura. La incapacidad para el correcto funcionamiento de los plugins hace resurgir de las sombras un héroe.

El problema: no nos vibraba el dispositivo. Comprobamos que está bien escrita la sentencia, que tenemos el plugin instalado que los permisos estaban bien escritos, ....

Solución aportada por Miguel:
Borra los permisos del AndroidManifest.xml, genera el apk; y vuelve a escribir los permisos a mano.
Bueno pues lo que parece una tontería, funciona a la perfección. La explicación que le damos es que Eclipse no nos actualiza correctamente los proyectos, así pues cuando instalas/desinstalas plugins se quedan "restos" dentro de los ficheros .xml, que consiguen que no nos vaya bien la aplicación.

miércoles, 11 de junio de 2014

Aplicaciones web en Chrome y Android


Google ha desarrollado, o mejor dicho, esta desarrollando una serie de herramientas para poder desarrollar aplicaciones Chrome que se ejecuten tanto en Android como en iOS como si fueran nativas basadas en Apache Cordova, hacia donde ha derivado este proyecto ya que estas herramientas están aun en un estado de desarrollo muy temprano.
            Se pueden empaquetar las aplicaciones Chrome para ser distribuidas por medio de Google Play o App Store.
            Estas aplicaciones estan desarrolladas con HTML, CSS y Javascript, que son los lenguajes con los que se trabaja en Apache Cordova.
            En la documentación de Chrome Apps Developer Tools, podemos ver las direcciones de trabajo que nos indican el proceso desde la creacion de la app, hasta su ejecución. Siendo estos dos caminos:
  • Por medio de la línea de comandos
  • A través del IDE o del SDK de las plataformas XCode o Eclipse

(Como podemos observar muy similar a Apache Cordova, por no decir que idéntico.)
            De hecho esta forma de trabajo pone a nuestra disposición todas las APIs de Apache Cordova.
            Para comenzar a desarrollar en este sistema existen una serie de aplicaciones de ejemplos y un proyecto en gitgub.

            De hecho tras investigar un poco, podemos ver que para desarrollar en la tecnología de Chrome, son necesarios los mismos requisitos que para Cordova o Phonegap:
  • nodejs
  • JAVA JDK 7
  • Andorid SDK version 4.4.2
  • Apache-ant

            A la hora de desarrollar proyectos, emular dispositivos... tan solo hay que cambiar la palabra cordoba por cca:

Chrome
Cordova
cca create HolaMundo
cordova create HolaMundo
cca emulate android
cordova emulate android
cca run android
cordova run android

            Incluso para realizar cambios en nuestros códigos HTML, CSS y Javascript es necesario acceder al directorio www.
            De hecho en la propia documentación puesta en githud:
(https://github.com/MobileChromeApps/mobile-chrome-apps/blob/master/docs/CordovaConsiderations.md) sobre el proyecto, derivan a ciertas consideraciones que hay que tener cuando se desarrolla en Chrome.

            Las diferencias más notables que hemos podido encontrar son:
  • En la tecnología desarrollada por Chrome, en principio solo se puede desarrollar para Android e iOs, mientras que en Apache Cordova entran también windows phone, windows 8 y BlackBerry
  • La forma de subir las aplicaciones a Play Store es directa con Chrome con tan solo una secuencia de comandos, mientras que no ocurre esto en Apache Cordova.

Aplicación de ZPAS.net

Aqui os dejamos la aplicación de ZPAS.net que hemos desarrollado con algunos plugins y que conlleva parte del catalogo

sábado, 7 de junio de 2014

Instalación de Cordova en Ubuntu

Uno de los inconvenientes de Apache Cordova es que hay muy buena documentación sobre sistemas Windows/MacOS. Por eso aquí trataremos la instalación de Cordova en un sistema Linux como es Ubuntu.
  • Instalación de ant:
    • $sudo apt-get install python-software-properties python g++ make ant
  •  Instalar Android SDK:
    • Puede que haya problemas con algunos repositorios de Android que fueron instalados en el sistema. Una manera de purgar y dejar limpia la instalación sería lanzando la siguiente sentencia:
      • $sudo apt-get remove android-tools-adb android-tools-fastboot
    • Descargamos el SDK de la página oficial y lo descomprimimos en el directorio que queramos. (Recordad y mantened la ruta porque será la utilizada para establecer el PATH).
  • Editamos el archivo ~/.bashrc:
    • $sudo gedit ~/.bashrc
  • Y añadimos al principio del fichero el siguiente PATH:
    • export PATH=${PATH}:/ruta-del-sdk/adt-bundle/sdk/platform-tools:/ruta-del-sdk/adt-bundle/sdk/tools
    • Donde ruta-del-sdk será donde tengamos alojado el SDK dentro de nuestro sistema.
    • Solo se enlazan los directorios platform-toos y tools.
    • Se recargan las variables del bash con:
      • $source ~/.bashrc
  • Instalación de node.js:
    • Añadimos el repositorio:
      • $sudo add-apt-repository ppa:chris-lea/node.js
    • Actulizamos:
      • $sudo apt-get update
    • Lanzamos instalación:
      • $sudo apt-get install python-software-properties python g++ make nodejs
  • Instalación de Cordova:
    • $sudo npm install -g cordova
Con esto hemos conseguido instalar Apache Cordova satisfactoriamente en Ubuntu. Vuelvo a remarcar la importancia de los PATH porque pueden dar problemas al intentar añadir la plataforma Android a un proyecto que hayamos creado, por poner un ejemplo.

Fuente

jueves, 5 de junio de 2014

Cuidad vuestras mascotas

Hemos comenzado la producción de una nueva aplicación bajo Cordova. Esta aplicación será un juego basado en el "lindo gatito", el cual conocemos muy bien todos. Pero esta vez la mascota será el logotipo de Cordova.

Primero decidimos que lo íbamos a basar en el clásico tamagotchi; así pues la mascota comerá, dormirá, jugará, hasta hará sus propias cacas. Pero el peso importante lo tenemos que decantar con la utilización de los plugins más punteros. Hemos decidido la introducción de: una pantalla de carga para usar splashscreen, que los mensajes los mostráramos en dialogs, el uso del acelerómetro para jugar con tu mascota, mostrar contenido web con ayuda de inappbrowser, vibración para alertar al jugador, almacenamiento de mascotas difuntas en bases de datos...

El siguiente paso obligatorio sería el diseño del mock-up para ayudarnos a estructurar y agilizar el desarrollo de la aplicación. Primero trasladado en papel como bocetos y luego digitalizado para la posterior documentación a presentar.

Entonces actualmente nos encontramos con la mayoría de ventanas ya programadas, un interfaz completamente definido a falta de la funcionalidad del "bichito", iconos y botones ya diseñados, logotipo finalizado y trabajando la documentación a la par.

miércoles, 4 de junio de 2014

Documentación Version 1.0

Por fin hemos culminado el trabajo con el exelearning, la documentación esta completa para realizar proyectos utilizando casi cualquier plugin, evento, e incluso bases de datos.
En esta versión 1.0, se pueden encontrar:
  • La instalación y los requisitos mínimos para que tu maquina pueda crear proyectos en Apache Cordova.
  • Como crear una aplicación desde cero, creando el proyecto y utilizar html5 y css3 para ello
  • Los plugins y eventos más importantes con ejemplos, vídeos demostrativos y enlaces a proyectos completos.
  • Información básica sobre la lectura, creación y borrado de archivos
  • Almacenamiento de datos por medio de la BD; SQLite
  • Como utilizar la línea de comandos (CLI)
  • Utilización del archivo config.xml
  • Como utilizar la privacidad con Apache Cordova y algunos consejos para que esta no se rompa.
  • Listas blancas
  • Como actualizar a la última versión de Apache Cordova.
Para acceder a esta documentación haz click sobre la imagen, y estarás listo para hacer tus propias aplicaciones en Android en muy poco tiempo.
http://apachecordova.esy.es/ 

Nota: Esta versión esta pendiente de la revisión gramatical y ortográfica final.


API de FileSystem

El API se divide en varios temas:
  • lectura y manipulación de archivos (File/Blob, FileList, FileReader),
  • creación y escritura (BlobBuilder, FileWriter),
  • acceso a sistemas de archivos y directorios (DirectoryReader, FileEntry/DirectoryEntry, LocalFileSystem).

Solicitud de un sistema de archivos

Una aplicación web puede solicitar acceso al sistema de archivos de prueba con window.requestFileSystem():

window.requestFileSystem(type, size, successCallback, opt_errorCallback)
  • type: Indica si el almacenamiento de archivos debe ser permanente. Los valores que se pueden utilizar son window.TEMPORARY y window.PERSISTENT. Los datos almacenados con el tipo TEMPORARY se pueden eliminar a elección del navegador. Los datos almacenados con el tipo PERSISTENT no se pueden borrar a menos que el usuario o la aplicación lo autoricen expresamente y requieren que el usuario otorgue espacio de almacenamiento a la aplicación.
  • size: Indica el espacio (en bytes) de almacenamiento que necesitará la aplicación.
  • successCallback. Indica la devolución de llamada que se activa cuando se autoriza el acceso a un sistema de archivos. Su argumento es un objeto FileSystem.
  • opt_errorCallback: Corresponde a una devolución de llamada opcional para la gestión de errores o para los casos en los que se deniega la solicitud de acceso al sistema de archivos. Su argumento es un objeto FileError.

Cómo crear un archivo

Para buscar o crear archivos, se puede utilizar el método getFile() de la interfaz DirectoryEntry del sistema de archivos. Una vez que se ha solicitado un sistema de archivos, se transmite a la devolución de llamada de operación correcta un objeto FileSystem que contiene una interfaz DirectoryEntry (fs.root) que señala al directorio raíz del sistema de archivos de la aplicación.

window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);
function onInitFs(fs) {

  fs.root.getFile('log.txt', {create: true, exclusive: true}, function(fileEntry) {

    // fileEntry.isFile === true
    // fileEntry.name == 'log.txt'
    // fileEntry.fullPath == '/log.txt'

  }, errorHandler);

}

Una vez que se ha solicitado el sistema de archivos, se transmite un objeto FileSystem al controlador de operación correcta. Dentro de la devolución de llamada, se puede solicitar fs.root.getFile() indicando el nombre del archivo que se va a crear. Se puede especificar una ruta absoluta o relativa, pero debe ser una ruta válida. Por ejemplo, es un error intentar crear un archivo cuyo elemento inmediatamente anterior no exista. El segundo argumento de getFile() es una cadena literal de objeto que describe el comportamiento que debe tener la función si el archivo no existe. En este ejemplo, create: true hace que se cree el archivo si no existe y que se genere un error en caso contrario (exclusive: true). Por su parte, create: false hace que el archivo simplemente se extraiga y se muestre. En ambos casos, el contenido del archivo no se sobrescribe, ya que solo se está obteniendo una entrada de referencia al archivo en cuestión.

Cómo leer un archivo por nombre

El código que aparece a continuación permite recuperar el archivo "log.txt", leer su contenido con el API FileReader e incorporarlo a una nueva área de texto (<textarea>) en la página. Si el archivo "log.txt" no existe, se genera un error.

function onInitFs(fs) {

  fs.root.getFile('log.txt', {}, function(fileEntry) {

    // Get a File object representing the file,
    // then use FileReader to read its contents.
    fileEntry.file(function(file) {
       var reader = new FileReader();

       reader.onloadend = function(e) {
         var txtArea = document.createElement('textarea');
         txtArea.value = this.result;
         document.body.appendChild(txtArea);
       };

       reader.readAsText(file);
    }, errorHandler);

  }, errorHandler);

}

window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);

Cómo escribir en un archivo

El código que aparece a continuación permite crear un archivo vacío llamado "log.txt" (en caso de que no exista) y escribir en él el texto "Lorem Ipsum".

window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, errorHandler);

function onInitFs(fs) {

  fs.root.getFile('log.txt', {create: true}, function(fileEntry) {

    // Create a FileWriter object for our FileEntry (log.txt).
    fileEntry.createWriter(function(fileWriter) {

      fileWriter.onwriteend = function(e) {
        console.log('Write completed.');
      };

      fileWriter.onerror = function(e) {
        console.log('Write failed: ' + e.toString());
      };

      // Create a new Blob and write it to log.txt.
      var bb = new BlobBuilder(); // Note: window.WebKitBlobBuilder in Chrome 12.
      bb.append('Lorem Ipsum');
      fileWriter.write(bb.getBlob('text/plain'));

    }, errorHandler);

  }, errorHandler);

}

Esta vez, se utiliza el método createWriter() de FileEntry para obtener un objeto FileWriter. Dentro de la devolución de llamada de operación correcta, se definen controladores para los eventos error y writeend. Para escribir los datos del texto en el archivo, se crea un objeto Blob, se le añade texto y se transmite el objeto a FileWriter.write().

Cómo añadir datos a un archivo

El código que aparece a continuación permite añadir el texto "Hello World" al final del archivo de registro. Si el archivo no existe, se genera un error.

window.requestFileSystem(window.TEMPORARY,1024*1024, onInitFs, errorHandler);

function onInitFs(fs) {

  fs.root.getFile('log.txt',{create: false}, function(fileEntry) {

    // Create aFileWriter object for our FileEntry (log.txt).
    fileEntry.createWriter(function(fileWriter){

      fileWriter.seek(fileWriter.length);
      // Start write position at EOF.

      // Create a new Blob and write it to log.txt.

      var bb = new BlobBuilder();

      bb.append('Hello World');

      fileWriter.write(bb.getBlob('text/plain'));

    }, errorHandler);

 }, errorHandler);

}

Cómo eliminar un archivo

El código que aparece a continuación permite eliminar el archivo "log.txt".

window.requestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
  fs.root.getFile('log.txt', {create: false}, function(fileEntry) {

    fileEntry.remove(function() {
      console.log('File removed.');
    }, errorHandler);

  }, errorHandler);
}, errorHandler);

Cómo copiar entradas, cambiarles el nombre y moverlas

Las interfaces FileEntry y DirectoryEntry comparten algunas operaciones.

Cómo copiar una entrada

Tanto FileEntry como DirectoryEntry cuentan con el método copyTo() para la duplicación de entradas. Este método permite hacer una copia recurrente en diferentes carpetas.
El código del ejemplo que aparece a continuación permite copiar el archivo "me.png" de un directorio en otro:

function copy(cwd, src, dest) {
  cwd.getFile(src, {}, function(fileEntry) {

    cwd.getDirectory(dest, {}, function(dirEntry) {
      fileEntry.copyTo(dirEntry);
    }, errorHandler);

  }, errorHandler);
}

window.requestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
  copy(fs.root, '/folder1/me.png', 'folder2/mypics/');
}, errorHandler);

Cómo mover una entrada o cambiarle el nombre

El método moveTo() de FileEntry y DirectoryEntry permite mover archivos y directorios y cambiarles el nombre. El primer argumento especifica el directorio principal al que se debe mover el archivo y el segundo argumento indica un nuevo nombre opcional para el archivo. Si no se especifica un nombre nuevo, se utilizará el nombre original del archivo.
El código de ejemplo que aparece a continuación permite sustituir el nombre del archivo "me.png" por "you.png" sin mover el archivo:

function rename(cwd, src, newName) {
  cwd.getFile(src, {}, function(fileEntry) {
    fileEntry.moveTo(cwd, newName);
  }, errorHandler);
}

window.requestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
  rename(fs.root, 'me.png', 'you.png');
}, errorHandler);

El código de ejemplo que aparece a continuación permite mover el archivo "me.png" (ubicado en el directorio raíz) a una carpeta llamada "newfolder".

function move(src, dirName) {
  fs.root.getFile(src, {}, function(fileEntry) {

    fs.root.getDirectory(dirName, {}, function(dirEntry) {
      fileEntry.moveTo(dirEntry);
    }, errorHandler);

  }, errorHandler);
}

window.requestFileSystem(window.TEMPORARY, 1024*1024, function(fs) {
  move('/me.png', 'newfolder/');
}, errorHandler);

martes, 3 de junio de 2014

Intentar guardar ficheros en local

La idea de esta incursión era poder escribir, leer y borrar ficheros que se encontraran en nuestro dispositivo. Antes de leer he pensado que sería mejor poder escribirlos con algún tipo de contenido. Algo sencillo: un documento de texto (.txt) con algún texto escrito.

Obviamente el plugin para poder manejar esta máquina será File. Como anteriormente se habría comentado el comando para instalar el plugin en nuestro proyecto sería:

cordova plugin add org.apache.cordova.file

He optado por no pedirle datos al usuario y que dándole a un simple botón automáticamente hiciera todo lo necesario para crear el fichero, escribirlo y alojarlo en nuestro dispositivo (en este caso se guarda en la tarjeta de memoria, que en realidad es donde se instala el apk, en otras palabras, donde se encuentra la aplicación instalada).

Lo primero sería especificar mediante JavaScript que queremos guardar un fichero. Nos ayudaremos del método requestFileSystem al que le especifico un guardado persistente, de un tamaño de 100 bytes y las dos llamadas éxito y de fallo:

window.requestFileSystem(LocalFileSystem.PERSISTENT,
                         100, 
                         gotFileSystem, 
                         fail);

Si este objeto se crea nos llevaría a la función gotFileSystem especificada anteriormente para que ahora nos cree físicamente el archivo en nuestro dispositivo. Nos ayudamos del método getFile, al que le paso el nombre del archivo, unas cuantas opciones y las dobles funciones de éxito y fallo:

fileSystem.root.getFile("readme2.txt",
                             {create: true, exclusive: false}, 
                             gotFileEntry, 
                             fail);

Si se ha creado satisfactoriamente el fichero en el dispositivo tenemos que crear un objeto FileWriter que nos sirva de manejador para escribir en el fichero en cuestión. Nos ayudamos del método createWriter, el cual solo recibe el éxito o el fallo:

fileEntry.createWriter(gotFileWriter, fail);

Una vez tenemos el manejador podremos escribir en nuestro documento con el método write. Automáticamente nos reemplazará el contenido con el texto que le hayamos pasado por argumento y lo guardará.

Todo esto está tal cual de la documentación oficial de Cordova. El problema con el que me he encontrado es que a veces solo crea los escuchadores, otras solo crea el fichero vacío, otras lo hace todo bien y una solución burda para que lo hiciera bien de primeras era tener que darle muchas veces repetidas al botón. He de decir que este ejemplo está copiado totalmente de la documentación y se supone que está testeado por los propios desarrolladores. Sin embargo, no conseguimos crear a la primera el fichero con el texto que le hayamos puesto.

Aplicación real con Apache Cordova

Como parte del proyecto, y con el fin de poder trabajar en él durante las prácticas, propusimos a la empresa, ZPAS.net, hacerle una aplicación para ellos, cuya página ni ten siquiera es responsive.
En respuesta ellos nos dijeron que querían una especie de presentación tipo catalogo, y es lo que le estamos haciendo, aunque aun estamos en la fase de desarrollarlo tipo web, podemos determinar varias cosas:
  • Las transiciones, overs, focus... de css3 no funcionan bien y hemos tenido que no recurrir a ellas
  • Se debe de producir primero en formato web local para poder desarrollarla entera y después introducir todos los plugins de Cordova y utilizarlos.
Esperamos tenerla terminada para dentro de poco, aunque como es normal, ahora mismo no podemos mostrar mucho, ya que esta en desarrollo, pero aun así ponemos aquí el menú principal.

lunes, 2 de junio de 2014

Primero incursión DataStorage

Hemos querido implementar un par de aplicaciones que nos sirviera para comprobar el manejo de bases de datos. Por un lado ha imperado el almacenamiento por Web SQL Database que se ha enfrentado al LocalStorage.

Ambos cuentan con sentencias potentes; por un lado el Web SQL se sirve de sentencias en lenguaje SQL, mucho más numerosas y potentes pero hay que remarcar que la W3C ha dejado de darle soporte ( no por ello, signifique que no podemos seguir utilizándola ). El LocalStorage utiliza menos sentencias y la disposición de sus datos se basa en claves y valores indexados.

La primera prueba sobre LocalStorage daba positivo pero en un navegador web convencional como en el que teníamos en nuestra máquina. Sin embargo al portarlo a Apache Cordova, la aplicación no lanzaba ningún resultado satisfactorio. Simplemente no aparecían los valores y claves que habíamos introducido. Aún tratamos de esclarecer porque funciona en un navegador y no en la aplicación nativa.

La segunda apuesta por Web SQL guarda y muestra bien los datos en toda la ejecución de la aplicación sin embargo, desconocemos donde se encuentran estos datos almacenados.

De ahí nuestro interés de que podamos administrar dichos datos para guardarlos en ficheros de extensión .sql por ejemplo. Será nuestra próxima arremetida contra este inconveniente.

jueves, 29 de mayo de 2014

Plugin InAppBrowser

Este plugin permite la visualización de una web en un navegador cuando se llama a la función window.open(), o cuando se abre un enlace compuesto por <a target="_blank">.

Instalación

cordova plugin add org.apache.cordova.inappbrowser

Para poderle dar uso a las funciones de este plugin, lo primero de todo es instanciar la ventana del 'inappbrowser'. Lo conseguimos con la sentencia de JavaScript window.open a la cual se le pasa como parámetros la URL, la herramienta que la cargará y unas opciones que varían según el sistema del dispositivo.

var ref = window.open(url, target, options);

InAppBrowser

Es el objeto devuelto por la llamada a window.open.

Métodos

  • addEventListener
  • removeEventListener
  • close
  • show
  • executeScript
  • insertCSS

Introducción a File Plugin

El plugin "File" de Cordova es simplemente una implementación de la API del sistema de ficheros de HTML5. No es algo en lo que vayas a entrar en profundidad, ya que en el ámbito de Apache Cordova, sólo nos interesa en lo referente al manejo eventual de esta característica por parte de otros plugins, como puede ser el caso de Media o FileTransfer.

En este enlace podéis encontrar una extensa documentación (en varios idiomas, incluido el español) sobre el manejo de esta API para HTML5

Para instalar el plugin File en un nuevo proyecto de Cordova, nos situamos en el directorio del mismo, y una vez instalada la plataforma correspondiente (Android en nuestro caso), escribimos lo siguiente:

cordova plugin add org.apache.cordova.file

Es habitual que File se descargue automáticamente junto con otro plugin que requiera de alguna de sus características, como es el caso de Media. Por lo que no es habitual que tengáis que recurrir a instalarlo manualmente.

Plataformas soportadas
  • Amazon Fire OS
  • Android
  • BlackBerry 10
  • iOS
  • Windows Phone 7 and 8*
  • Windows 8*
  • Firefox OS
Lista de códigos de error y significado
  • 1 = NOT_FOUND_ERR
  • 2 = SECURITY_ERR
  • 3 = ABORT_ERR
  • 4 = NOT_READABLE_ERR
  • 5 = ENCODING_ERR
  • 6 = NO_MODIFICATION_ALLOWED_ERR
  • 7 = INVALID_STATE_ERR
  • 8 = SYNTAX_ERR
  • 9 = INVALID_MODIFICATION_ERR
  • 10 = QUOTA_EXCEEDED_ERR
  • 11 = TYPE_MISMATCH_ERR
  • 12 = PATH_EXISTS_ERR

Con respecto al almacenamiento persistente de ficheros en Android, hay que tener en cuenta algunas consideraciones. Desde versiones anteriores de este plugin, existe la posibilidad de que el plugin detecte automáticamente la existencia de una tarjeta SD. Dependiendo de esto, los ficheros con los que trabaje la aplicación se almacenan en la tarjeta o bien en la memoria interna del dispositivo.

En la nueva versión podemos escoger entre esta opción o simplemente elegir almacenar los ficheros en la memoria interna. Esto podemos hacerlo editando directamente el fichero config.xml, escogiendo entre uno de estos dos parámetros:

<preference name="AndroidPersistentFileLocation" value="Internal"/>
<preference name="AndroidPersistentFileLocation" value="Compatibility"/>

También podemos configurarlo con una serie de parámetros opcionales:

<preference name="AndroidExtraFilesystems" value="
files,files-external,documents,sdcard,cache,cache-external,root"/>

  • files: Directorio interno de almacenamiento de ficheros de la aplicación
  • files-external: Directorio externo de almacenamiento de ficheros de la aplicación
  • sdcard: Directorio global de almacenamiento (por defecto la raíz de la tarjeta SD si está habilitado). Requiere el permiso android.permission.WRITE_EXTERNAL_STORAGE 
  • cache: Directorio de caché interno de la aplicación
  • cache-external: Directorio de caché externo de la aplicación
  • root: Raíz del sistema de ficheros


Cordova Media Plugin: No funciona

En la documentación oficial de Apache Cordova, acorde a las especificaciones de la última versión, 3.5.0, nos encontramos con lo siguiente:

Apache Cordova 3.5.0

[...]

Plugin versions tested with this release

[...]

  • cordova-plugin-media: 0.2.10
[...]

Sin embargo, tras haber actualizado a la última versión de Cordova y probar de nuevo el ejemplo desarrollado para explicar el plugin Media, sigue sin dar resultado, encontrándonos con el mismo error de la última ocasión:

 Uncaught ReferenceError: Media is not defined at file:///android_asset/www/index.html:19  

Es curioso el detalle de que, al instalar el plugin, se descarga conjuntamente de forma automática con el paquete del plugin File, ya que para usar Media hay que trabajar con ficheros. Como es obvio, tanto de File como de Media se descarga la última version de ambas (1.1.0 y 0.2.10 respectivamente). Sin embargo, al finalizar la descarga, aparece un warning advirtiendo de que el plugin Media depende de una versión anterior de File (1.0.1)

Se puede apreciar que no tiene ningún sentido. Y al no poder obtener de ninguna forma la versión necesaria del plugin File, y aún sin saber si eso solucionará el problema, es mejor dar por hecho que el plugin Media, definitivamente, no está recibiendo un soporte adecuado. Por lo que, sintiéndolo mucho, hemos decidido tirar la toalla con este plugin.

También hemos comprobado, por último, que la etiqueta
<audio>
de HTML5 tampoco funciona.

Plugin Globalization

Este plugin obtiene información y operaciones de representación específica al usuario local, idioma, y zona horaria. Nótese la diferencia entre local e idioma: local controla qué números, fechas, y horas aparecen en la región, mientras que el idioma determina que idioma de texto aparece, independientemente de los ajustes locales. Desafortunadamente, la mayoría de dispositivos móviles no hacen distinción entre estos ajustes.

Intalación

cordova plugin add org.apache.cordova.globalization

Objetos

  • GlobalizationError
     

Métodos

  • navigator.globalization.getPreferredLanguage
  • navigator.globalization.getLocaleName
  • navigator.globalization.dateToString
  • navigator.globalization.stringToDate
  • navigator.globalization.getDatePattern
  • navigator.globalization.getDateNames
  • navigator.globalization.isDayLightSavingsTime
  • navigator.globalization.getFirstDayOfWeek
  • navigator.globalization.numberToString
  • navigator.globalization.stringToNumber
  • navigator.globalization.getNumberPattern
  • navigator.globalization.getCurrencyPattern

miércoles, 28 de mayo de 2014

Cordova Media Plugin: Primer intento fallido

Hemos intentado implementar con Apache Cordova la siguiente aplicación, el funcionamiento es bastante simple: se carga un fichero de audio y se reproduce automáticamente. Una vez que consigamos esto intentaremos implementar botones de reproducción, pausa, etc... Pero de momento estamos atascados con el reconocimiento del fichero de audio en sí.

 <!DOCTYPE html>  
 <html>  
   <head>  
     <meta charset="utf-8" />  
     <meta name="format-detection" content="telephone=no" />  
     <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />  
     <link href="css/bootstrap.min.css" rel="stylesheet" media="screen">  
           <script type="text/javascript">  
       // Wait for device API libraries to load  
                //  
                function onLoad() {  
                     var my_media = null;  
                     document.addEventListener("deviceready", onDeviceReady, false);  
                }  
                // device APIs are available  
                //  
                function onDeviceReady() {  
                          var my_media = new Media("https://ia600808.us.archive.org/21/items/NasaAudioHighlightReels/Launch-Sound_STS-1-Launch.mp3",  
                               // success callback  
                               function () {  
                                    alert("playAudio():Audio Success");  
                               },  
                               // error callback  
                               function (err) {  
                                    alert("playAudio():Audio Error: " + err);  
                               }  
                          );  
                          my_media.play();  
                }  
     </script>  
     <title>Hello World</title>  
   </head>  
   <body onload="onLoad()">  
     <br/>  
     <br/>  
           <div class="container">  
                <div class="jumbotron">  
         <div class="row">  
             <div class="col-md-2"><img src="img/logo.png" class="img-responsive" alt="Responsive image"></div>  
           <div class="col-md-10"><h1>Cordova Media Plugin</h1></div>  
         </div>  
                     <button type="button" id="play" class="btn btn-primary"><span class="glyphicon glyphicon-play"></span></button>  
                     <button type="button" id="pause" class="btn btn-success"><span class="glyphicon glyphicon-pause"></span></button>  
                </div>  
           </div>  
           <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->  
           <script src="http://code.jquery.com/jquery.js"></script>  
           <!-- Include all compiled plugins (below), or include individual files as needed -->  
           <script src="js/bootstrap.min.js"></script>  
           <script src="js/jquery.min.js"></script>  
     <script type="text/javascript" src="cordova.js"></script>  
     <script type="text/javascript">  
       app.initialize();  
     </script>  
   </body>  
 </html>  

La consola de Eclipse ( "LogCat" en Android Developer Tools) notifica del siguiente error:

 Uncaught ReferenceError: Media is not defined at file:///android_asset/www/index.html:19  

Hemos intentado encontrar alguna solución por internet. Muchas pasaban por revisar los parámetros del plugin en los ficheros xml, modificar la ruta del fichero de audio, reinstalar el plugin... Pero ninguna ha dado resultado. Por lo que el problema es el siguiente: el plugin está instalado pero el emulador no reconoce la clase Media.

martes, 27 de mayo de 2014

Plugin de Geolocalización

La principal característica de este plugin es proporcionar al usuario las coordenadas que recoge el dispositivo móvil. Contempla una considerable cantidad de datos: latitud, longitud, altitud, .. y además se le puede especificar el margen de error que puede tener para determinar dichos datos.

Se sirve de la información recibida en el GPS o también de la conexión a Internet (WIFI, 3g, 4g, direcciones MAC,...)

Como además es una tecnología que permite conocer la posición del dispositivo (por tanto también al propio usuario) se debe tener en consideración la vulnerabilidad a la privacidad, obligando a la aplicación la labor de informar al usuario de que queda expuesto a algún tipo de riesgo de vulnerabilidad.

Instalación:

cordova plugin add org.apache.cordova.geolocation

Métodos:

  • navigator.geolocation.getCurrentPosition
  • navigator.geolocation.watchPosition
  • navigator.geolocation.clearWatch

Objetos:

  • Position
  • PositionError
  • Coordinates
Tengo que decir de que la aplicación que he desarrollado para que mostrara las coordenadas por pantalla funcionaba a la perfección pero con el detalle de que solo lo hacía cuando estaba conectado a Internet. Cuando volví a hacer una segunda prueba solo con el GPS activado el dispositivo no lanzaba ningún resultado. El modelo de smartphone utilizado ha sido un Samsung GT-S7560 con Android 4.0.4.

**Nueva actualización**: al intentar desarrollar una nueva aplicación basada en este plugin me he encontrado con que mi dispositivo no muestra dato alguno. He copiado los ejemplos de la documentación en un proyecto nuevo y sin tratar, le he activado y desactivado el WiFi y el GPS al dispositivo... pero como resultado tampoco ha mostrado los datos de geolocalización.

Llega Apache Cordova 3.5

Durante la realización de este proyecto, Apache Cordova a pasado a su versión 3.5, esto ha modificado algunas cuestiones en el desarrollo aunque en esencia sigue siendo el mismo.
Los cambios más importantes han sido:
  • El código común entre cordova-cli y cordova-plugman se ha mudado a su propio repositorio llamado cordoba-lib
  • Cada plataforma cuenta ahora con un archivo llamado package.json que se ha subido a NGP. Las futuras actualizaciones de cordova.cli harán uso de npm para las plataformas de carga
  • Caída del apyo de iOS 5.0 y de arm64. Desde ahora los proyectos se crean en código binario universal de 64 y 32 bits requiriendo como mínimo el despliegue en iOS 6.0
  • Esta será la última versión con soporte para Windows Phone 7
  • Se ha añadido soporte para Chrome devtools, con versiones de depuración de amazon-fireos.
Para actualizar su proyecto en la plataforma que desee, modifique andorid por su plataforma

npm install -g cordova
cd my_project
cordova platform update android

Fuente

jueves, 22 de mayo de 2014

Aplicación que reconoce el tipo de conexión del dispositivo (Network- Information Plugin)

Plataformas Soportadas

  • Amazon Fire OS
  • Android
  • BlackBerry 10
  • iOS
  • Windows Phone 7 and 8
  • Tizen
  • Windows 8

Propiedades

  • connection.type

Constantes

  • Connection.UNKNOWN
  • Connection.ETHERNET
  • Connection.WIFI
  • Connection.CELL_2G
  • Connection.CELL_3G
  • Connection.CELL_4G
  • Connection.CELL
  • Connection.NONE

Mediate el uso de este plugin de Apache Cordova podemos obtener información sobre el tipo de conexión a Internet de la que dispone nuestro dispositivo. Este plugin trabaja con un objeto denominado connection, mediante el cual, valiéndonos de sus constantes y propiedades, podemos obtener información.

El primer paso será instalar el plugin en el proyecto de Cordova que queramos utilizarlo. Nos situamos en el directorio del mismo y escribimos el siguiente comando:

cordova plugin add org.apache.cordova.network-information

Después importamos el proyecto al entorno de desarrollo para hacer las pruebas pertinentes.

Este sería el código de la aplicación web. El plugin trabaja con un objeto de Javascript denominado connection, el cual contiene varias constantes y una propiedad (type). Usando ambos, en la función checkConnection() se asocian cadenas de texto a los diferentes valores de las constantes en un array, que hacen las veces de índices del mismo. De esta forma, cuando lo mostremos, obtendremos un mensaje personalizado que nos especifica en español qué tipo de conexión tiene nuestro dispositivo.

 <!DOCTYPE html>  
 <html>  
   <head>  
     <meta charset="utf-8" />  
     <meta name="format-detection" content="telephone=no" />  
     <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />  
     <link rel="stylesheet" type="text/css" href="css/index.css" />  
           <link rel="stylesheet" type="text/css" href="css/tabla.css" />  
     <title>Network Info Plugin</title>  
           <script type="text/javascript" src="js/jquery.min.js"></script>  
           <script type="text/javascript" charset="utf-8">  
           // Wait for device API libraries to load  
           //  
           function onLoad() {  
                document.addEventListener("deviceready", onDeviceReady, false);  
           }  
           // mostramos en un mensaje de javascript el tipo de conexión que utiliza el dispositivo  
           function onDeviceReady() {  
                $(document).ready(function(){  
                     function checkConnection() {  
                          var networkState = navigator.connection.type; //Este plugin trabaja con el objeto CONNECTION  
                          var states = {};  
                          states[Connection.UNKNOWN] = 'DESCONOCIDO';  
                          states[Connection.ETHERNET] = 'ETHERNET';  
                          states[Connection.WIFI]   = 'CONECTADO A WIFI';  
                          states[Connection.CELL_2G] = 'CONEXION 2G';  
                          states[Connection.CELL_3G] = 'CONEXION 3G';  
                          states[Connection.CELL_4G] = 'CONEXION 4G';  
                          states[Connection.CELL]   = 'CONEXION MOVIL ESTANDAR';  
                          states[Connection.NONE]   = 'SIN CONEXION';  
                          return states[networkState];  
                     }  
                     $("#conx").text(checkConnection());  
                });  
           }            
           </script>  
   </head>  
   <body onload="onLoad()">  
     <div class="app">  
       <h1>ESTADO DE LA CONEXION</h1>  
       <div id="deviceready" class="blink">  
         <p class="event listening">Connecting to Device</p>  
         <p class="event received">Device is Ready</p>  
       </div>  
     </div>  
           <div class="generatecss_dot_com_table">  
                <table>  
                     <tr>  
                          <td>TIPO DE CONEXION</td>  
                     </tr>  
                     <tr>  
                          <td id="conx"></td>  
                     </tr>  
                </table>  
           </div>  
     <script type="text/javascript" src="cordova.js"></script>  
     <script type="text/javascript" src="js/index.js"></script>  
     <script type="text/javascript">  
       app.initialize();  
     </script>  
   </body>  
 </html>  

Podéis ver una explicación más detallada de este ejercicio, así como del código, en la documentación oficial del proyecto. Por último, aquí un vídeo con la aplicación en marcha:


Investigando con PHP en Apache Cordova

Hemos intentado, para ver si podíamos generar una aplicación que atacase a una base de datos y que se recibiera información desde el servidor por petición de usuario, meterle PHP al código html que se introduce en Apache Cordova, y hemos hecho varias pruebas:
   echo 'esto es una prueba PHP';

Y el resultado era que nos sacaba el texto, lo cual nos ha empezado a llenar de alegría, pero también ponía el ;, lo cual nos ha empezado a perturbar un poco, de modo que hemos hecho otras pruebas como estas:
Prueba 1
$a=1;
$b=2;
$c= $a+$b;
echo 'suma=' . $c;

Pero no ha ha habido ningún resultado

Prueba 2
Hemos intentado hacer un index.php, para ver si así lo leía, pero nos hemos quedado con las ganas, ya que ha aparecido un mensaje de error en el cual nos ponía que en el directorio www estaba buscando el archivo index.html

De momento nos hemos quedado con las ganas de poder acceder a información dinámica, pero no perdemos la esperanza de lograrlo de alguna manera... las posibilidades pueden ser enormes....

Privacidad en las aplicaciones

Hemos introducido un apendice donde incluimos algunas buenas formas de desarrollo, en lo que se refiere a la privacidad, control de datos, que hacer con ellos y como informar al usuario.
La entrada del apendice quedá más o menos de esta forma:
  • Política de privacidad: La aplicación debe de incluir una política de privacidad que se ocupe de temas tales como de que tipo de información recopila su información, como se utiliza la misma, con quienes la comparte y como se puede tomar decisiones relacionadas con la privacidad dentro de la misma. Con el fin de que el usuario pueda entenderlo, se debe de utilizar lenguaje y evitar tecnicismos. Lo ideal es que es que la política de privacidad se encuentre disponible antes de la descarga, en la descripción de la misma. Lo mejor es desarrollar una versión reducida para la aplicación que disponga de un enlace que envíe a la versión extendida de la misma.
  • Recopilación de información sensible: en ocasiones as aplicaciones recopilan información sensible de los usuarios, como datos financiera, salud, información acerca de niños, u obtenida a base de los aparatos del dispositivo tales como; cámara, contactos, geolocalización... Para estos casos, de forma general, lo ideal es obtener el consentimiento expreso del usuario antes de recoger esta información sensible y permitir en la medida de lo posible un mecanismo de control que permita al usuario cambiar de forma sencilla dichos permisos. Para este fin es muy recomendable utilizar cuadros de diálogos, que muestren el uso de los datos, y pedir permisos antes de la captura de la información.
  • Evitar la sorpresa del usuario: Si su aplicación recopila o utiliza la información de una manera que puede ser desconocida por el usuario, como por ejemplo un reproductor de música on-line, galerías de fotos... se deben de tomar medidas similares al apartado anterior; mostrando cuadros de dialogo con la información necesaria para evitar sorpresas al usuario.
  • Recopilación de datos de terceros: Si la aplicación toma datos que se proporcionan a otros medios, como redes sociales, anuncios... se debe de informar a los usuarios de que esa información será compartida. Como mínimo, la política de privacidad, debe de mostrar que información, como, donde y cuando se va a compartir, y si procede el usuario debe de tener la capacidad de control de excluirse cuando lo considere oportuno.
  • Seguridad y limitación de la recopilación: Los usuarios confían en la aplicación, y esperan que se tomen las precauciones necesarias de seguridad con su información, con el fin de que está este protegida. Lo mejor para evitar los compromisos de seguridad es ni recopilar información a menos que se tenga una razón para ello. Si se esta obligado a recoger datos de los usuarios, se deben de tener controles de seguridad apropiados para protegerlos y si se almacena en el dispositivo o en un servidor back-end, se debe de desarrollar una política de retención de los datos pertinentes que se debe de implementar tanto en la aplicación como en el servidor back-end.

Apicación con Networkinfo

Otra app que muestra el uso esta vez del plugin Networkinfo desde Apache Cordova

Aplicación de SplashScreen

Aplicación que muestra como funciona el Splashscreen en con Apache cordova

Aplicación de la brújula

Aquí os dejamos la aplicación de la brújula, recogiendo datos por medio de Apache Cordova:

Plugin Brújula

Gracias al uso del plugin Compass podemos dotar nuestras aplicaciones nativas de la utilidad de la brújula de la que dispone nuestro dispositivo móvil. Tan solo hay que tener algunas consideraciones destacables para dispositivos iOS, ya que estos tienen una tasa de refresco algo diferente. La orientación que lanzas los dispositovos iOS varía solo cuando de verdad ha cambiado el valor de la orientación; así pues si el dispositivo está bastante quieto no va a devolver nuevos datos.

Instalación

cordova plugin add org.apache.cordova.device-orientation

Métodos

  • compass.getCurrentHeading
  • compass.watchHeading
  • compass.clearWatch

 Objetos

  • compassError
  • compassHeading
Gracias al método watchHeading podemos monitorizar la orientación con una frecuencia que le hayamos configurado. Por defecto la frecuencia es de 100 milisegundos pero podemos adaptarla para al menos 1s. :


var options = { frequency: 1000 };
watchID = navigator.compass.watchHeading(onSuccess, onError, options);

Si la función watchHeading tiene éxito el ID va a ir guardando una orientación cada intervalo de tiempo (en este caso 1s).

De nuevo, hay que tener en consideración el manejador de eventos para cuando el dispositivo ha cargado todas las librerías de las APIs.

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

Aplicación del acelerometro

Aquí podemos ver la aplicación en funcionamiento que controla el acelerometro del dispositivo con Apache cordova

miércoles, 21 de mayo de 2014

Plugin Acelerómetro

Este plugin da acceso al acelerómetro del dispositivo. El acelorómetro es un sensor de movimiento que detecta cualquier cambio relativo a la orientación del dispositivo, en las tres dimensiones del eje (x, y & z).

Instalación

cordova plugin add org.apache.cordova.device-motion

Plataformas soportadas

  • Amazon Fire OS
  • Android
  • BlackBerry 10
  • iOS
  • Tizen
  • Windows Phone 7 y 8
  • Windows 8

Métodos 

  • navigator.accelerometer.getCurrentAcceleration
  • navigator.accelerometer.watchAcceleration
  • navigator.accelerometer.clearWatch

Objetos

  • Acceleration
A pesar los ejemplos que vienen en la documentación oficial he tenido problemas a la hora de implementar una aplicación que te mostrara por pantalla el valor de los ejes en tiempo real. Lo que pasaba es que no se advierte del uso del manejador de eventos para deviceready. Este manejador carga todas las librerías de las APIs y es una manera de asegurarse que al estar cargadas van a funcionar las llamadas a los plugins instalados.

Me he dado cuenta de ello al comprobar los mismos ejemplos en la documentación de Phonegap que en sus ejemplos resueltos lo incorporaban al código. Al hacer lo mismo en mi código la aplicación funcionó sin ningún error.

Si se quiere capturar los valores de los ejes en tiempo real lo idóneo sería utilizar el método watchAcceleration ya que en su último parámetro podemos especificarle la frecuencia con que se va a ir refrescando expresada en milisegundos:

navigator.accelerometer.watchAcceleration(accelerometerSuccess,
    accelerometerError,
    [accelerometerOptions]); 

Y es en accelerometerOptions donde le pasamos el parámetro frequency para especificar el tiempo de refresco de los valores de los ejes. Siempre en milisegundos, es decir 1000 ms será 1 s.

Otro dato interesante, y es que los valores de los ejes se basan en los efectos de la gravedad
(9,81 m/s2) lo que si tenemos nuestro dispositivo sobre una superfice plana y con la pantalla defrente los valores que lanzaría el acelerómetro serían: x=0, y=0, z=9.81.

Añadiendo una pantalla de carga personalizada a una aplicación Cordova

Mediante el plugin Splashscreen podemos agregar pantallas de carga personalizadas para nuestras aplicaciones Cordova. El manejo de este plugin requiere más manejo de código a nivel nativo que de tecnología web, desde donde sólo hay que contemplar un par de métodos sencillos (en la práctica, generalmente sólo se utiliza uno, el cual veremos más adelante).

El primer paso será crear un nuevo proyecto de Cordova. Una vez hecho esto, nos situaremos desde consola en el directorio correspondiente del mismo y ejecutaremos el siguiente comando, para instalar el plugin Splashscreen:

cordova plugin add org.apache.cordova.splashscreen

Antes de continuar, es indispensable ajustar nuestra imagen de carga al formato 9-patch de Android. Esto podemos hacerlo mediante Android Asset Studio. Cargamos la imagen desde nuestro ordenador, la ajustamos, y podemos descargar un fichero .zip con varias versiones PNG de nuestra imagen, ajustada a las diversas resoluciones estándar de dispositivos Android.

Después tendremos que trasladar estos ficheros al directorio de recursos de nuestro proyecto Android. Además, deberemos especificar el nuevo recurso en el fichero config.xml

 <preference name="SplashScreen" value="screen" />  
 <preference name="SplashScreenDelay" value="10000" />  

Donde "screen" equivale al nombre de nuestro fichero sin la extensión y 10000 es el tiempo de duración de la pantalla de carga en milisegundos. La duración por defecto si no se especifica nada es de 3000 ms

Importamos el proyecto de Cordova al entorno de desarrollo de Android, y nos aseguramos de incluir lo siguiente en el fichero .java principal, dentro del método onCreate()

super.setIntegerProperty("splashscreen", R.drawable.hwlef9);
super.loadUrl("file:///android_asset/www/index.html", 3000);

Donde "hwlef9" es el nombre del recurso, tal como lo hemos especificado en config.xml, y 3000 es, una vez más, el tiempo en ms que tarda en desvanecerse la pantalla de carga.

Debemos asegurarnos muy bien de que el recurso figura en el fichero R.java

Hecho esto tan sólo tendremos que preocuparnos, por último, en la aplicación web, de especificar en Javascript que desaparezca la pantalla una vez haya cargado Apache Cordova, para proceder a la visualización de la aplicación en sí. Es decir, escribiremos la siguiente instrucción dentro de la función lanzada por el manejador del evento deviceready:

navigator.splashscreen.hide();

Código fuente HTML:

1:  <!DOCTYPE html>  
2:  <html>  
3:   <head>  
4:    <title>Ejemplos de manejador de eventos Apache Cordova</title>  
5:       <link rel="stylesheet" type="text/css" href="css/index.css" />  
6:    <script type="text/javascript" charset="utf-8">  
7:    // Esperar a que carguen las librerias API del dispositivo  
8:    //  
9:    function onLoad() {  
10:      document.addEventListener("deviceready", onDeviceReady, false);  
11:    }  
12:    // Las APIs del dispositivo estan disponibles  
13:    //  
14:    function onDeviceReady() {  
15:      navigator.splashscreen.hide();  
16:    }  
17:    </script>  
18:   </head>  
19:   <body onload="onLoad()">  
20:       <div class="app">  
21:        <h1>Pantalla de carga</h1>  
22:        <div id="deviceready" class="blink">  
23:          <p class="event listening">Cargando...</p>  
24:          <p class="event received">LISTO!!!</p>  
25:                      <p>Muestra una pantalla de carga personalizada</p>  
26:        </div>  
27:      </div>  
28:      <script type="text/javascript" src="cordova.js"></script>  
29:      <script type="text/javascript" src="js/index.js"></script>  
30:      <script type="text/javascript">  
31:        app.initialize();  
32:      </script>  
33:   </body>  
34:  </html>  


Y ya podemos disponer de una pantalla de carga personalizada en nuestra aplicación Cordova:


Plugin device

La utilidad de este plugin es poder obtener información del dispositivo, ya sea de software o de hardware. Aunque para poder utilizarlo se debe implementar un manejador de eventos.

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    console.log(device.cordova);
}

Instalación:
cordova plugin add org.apache.cordova.device

Las propiedades que se pueden utilizar para identificar nuestro dispositivo serían:
  • device.cordova
  • device.model
  • device.name
  • device.platform
  • device.uuid
  • device.version
Nota importante: la propiedad device.name está en desuso. En su lugar se puede usar model ya que realiza la misma acción.
Nota importante 2: hay ciertos modelos de dispositivos que no muestran el nombre correctamente como puede pasar con los Nexus, pues su nombre los cambia por el de Passion. O en el caso de las BlackBerry únicamente muestran el número del modelo; para la BlackBerry Torch 9800 mostraría únicamente 9800.

Para terminar, un video demostrativo de una aplicación que muestra la información por pantalla: Enlace al post.

Aplicación que muestra información sobre el dispositivo

Esta aplicación muestra por pantalla un listado de características del dispositivo en el que se lanza. Algunas de ellas son la versión de Apache Cordova donde está desarrollada o el modelo del dispositivo.

Aplicación que agrega contactos

Esta aplicación añade un contacto nuevo a la base de datos del dispositivo móvil dados un nombre y un número de teléfono.

Plugin Contacts

Si queremos manejar el listado de contactos con los que disponemos en nuestro dispositivo móvil, este plugin sería la solución. Principalmente se pueden crear y buscar contactos pero además contamos con la posibilidad de agregar muchísimos más apartados al nuevo contacto.

Instalación:
cordova plugin add org.apache.cordova.contacts

Métodos
  • navigator.contacts.create
  • navigator.contacts.find
Objetos
  • Contact
  • ContactName
  • ContactField
  • ContactAddress
  • ContactOrganization
  • ContactFindOptions
  • ContactError
A parte cada objeto contiene una gran variedad de parámetros que identifican mucho más al contacto. Estos parámetros van desde el nombre, teléfono, dirección, e-mail; pasando por organización, urls, fecha de nacimiento... Nos da bastante juego a la hora de crear contactos. Se podría decir que estos objetos serían categorías que englobaran campos de datos referentes a su tema. Encontraremos campos como dirección postal, localidad, país; en el objeto de ContactAddress.

Por último un vídeo demostrativo de una pequeña aplicación que introduce un contacto en la base de datos del dispositivo: Enlace al post.

Plugin Camera

La principal competencia de este plugin es capturar, configurar y guardar imágenes tomadas desde la cámara o desde el álbum de fotos del dispositivo.

Instalación:

cordova plugin add org.apache.cordova.camera

Método principal:
  • getPicture( );
navigator.camera.getPicture(cameraSuccess,cameraError,[ cameraOptions ] );

Contiene además un considerable número de opciones o parámetros que se pueden configurar en para determinar por ejemplo: altura, anchura, calidad, donde se guarda, en qué formato, si será editable... Como nota importante habría que destacar la principal diferencia que toman los sistemas iOS, pues estos tienen menús flotantes en la pantalla del dispositivo, lo que conyeva a usar un parámetro específico para las opciones de dispositivos iOS como las tabletas iPad. CameraPopoverOptions. Por último podéis visualizar un vídeo demostrativo de una aplicación que arranca la cámara del dispositivo móvil para guardar la foto. Enlace al post.

Manejadores de eventos en Apache Cordova (II)

Continuamos investigando con los manejadores de eventos en Cordova, con escasos resultados, aunque hemos aprendido cosas nuevas.

En primer lugar, hemos intentado implementar una nueva aplicación de ejemplo en la que se hace uso de los eventos "pause" y "resume". El código muestra mensajes de tipo alert cuando la aplicación entra o sale del segundo plano de ejecución. El procedimiento es similar al utilizado en el ejercicio de los botones:

 <!DOCTYPE html>  
 <html>  
  <head>  
   <title>Cordova Pause Example</title>  
      <link rel="stylesheet" type="text/css" href="css/index.css" />  
   <script type="text/javascript" charset="utf-8" src="cordova-2.5.0.js"></script>  
   <script type="text/javascript" charset="utf-8">  
   function onLoad() {  
     document.addEventListener("deviceready", onDeviceReady, false);  
   }  
   function onDeviceReady() {  
     document.addEventListener("pause", onPause, false);  
     document.addEventListener("resume", onResume, false);  
   }  
   // Vamos a mostrar algunos mensajes segun entramos y salimos del segundo plano de ejecucion  
   function onPause() {  
     alert("Aplicacion en pausa");  
   }  
   function onResume() {  
     alert("Aplicacion activa");  
   }  
   </script>  
  </head>  
  <body onload="onLoad()">  
   <div class="app">  
       <h1>Eventos PAUSE y RESUME</h1>  
       <div id="deviceready" class="blink">  
         <p class="event listening">Cargando...</p>  
         <p class="event received">LISTO!!!</p>  
         <p>Esta aplicacion muestra un mensaje dependiendo de la ejecucion en segundo plano</p>  
       </div>  
     </div>  
     <script type="text/javascript" src="js/index.js"></script>  
     <script type="text/javascript">  
       app.initialize();  
     </script>  
  </body>  
 </html>  

Sin embargo, no es posible conseguir por ahora que las aplicaciones Cordova se pongan en segundo plano, siempre se cierran (tanto con el botón central como el de retroceso). Es posible forzar a que las aplicaciones se ejecuten en segundo plano de forma nativa, usando código Java.

El segundo intento fallido de hoy ha sido desarrollar una pequeña aplicación que se desplace por una barra de volumen de JQuery UI usando las teclas de volumen del teléfono. He caído en la cuenta un poco tarde de que estos eventos sólo funcionan en Blackberry 10, pero aun así, he aquí el código:


 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"  
            "http://www.w3.org/TR/html4/strict.dtd">  
 <html>  
  <head>  
   <title>Cordova Volume Down Button Example</title>  
   <link rel="stylesheet" href="themes/base/jquery.ui.all.css">  
      <script src="jquery-1.10.2.js"></script>  
      <script src="ui/jquery.ui.core.js"></script>  
      <script src="ui/jquery.ui.widget.js"></script>  
      <script src="ui/jquery.ui.mouse.js"></script>  
      <script src="ui/jquery.ui.slider.js"></script>  
      <link rel="stylesheet" href="../demos.css">  
   <style>  
   #eq span {  
     height:120px; float:left; margin:15px  
   }  
   </style>  
   <script type="text/javascript" charset="utf-8">  
   // Call onDeviceReady when Cordova is loaded.  
   //  
   // At this point, the document has loaded but cordova-2.5.0.js has not.  
   // When Cordova is loaded and talking with the native device,  
   // it will call the event `deviceready`.  
   //  
   function onLoad() {  
     document.addEventListener("deviceready", onDeviceReady, false);  
   }  
   // Cordova is loaded and it is now safe to make calls Cordova methods  
   //  
   function onDeviceReady() {  
     // Register the event listener  
     document.addEventListener("volumedownbutton", onVolumeDownKeyDown, false);  
     document.addEventListener("volumeupbutton", onVolumeUpKeyDown, false);  
   }  
   // Handle the volume down button  
   //  
   function onVolumeDownKeyDown() { 
           var valor = $( "#master" ).slider( "option", "value" );  
           valor -= 10;  
           $( "#master" ).slider( "option", "value", valor );  
   }  
   function onVolumeUpKeyDown() {  
           var valor = $( "#master" ).slider( "option", "value" );  
           valor += 10;  
           $( "#master" ).slider( "option", "value", valor );  
   }  
   $(function() {  
     // setup master volume  
     $( "#master" ).slider({  
                min: 0,  
                max: 100,  
       value: 60,  
       orientation: "horizontal",  
       range: "min",  
       animate: true  
     });  
   });  
   </script>  
  </head>  
  <body onload="onLoad()">  
   <p class="ui-state-default ui-corner-all ui-helper-clearfix" style="padding:4px;">  
   <span class="ui-icon ui-icon-volume-on" style="float:left; margin:-2px 5px 0 0;"></span>  
   Master volume  
   </p>  
   <div id="master"></div>  
  </body>  
 </html>  

Documentación en la red

Ya hemos subido la primera versión de la documentación a Internet, hemos creado un subdominio de hostinger donde poder alojarla y ya puede visitarse.
Para acceder a ella haz click sobre el icono de Apache cordova:
http://apachecordova.esy.es/

El archivo config.xml

Hemos estado investigando y creando la sección que habla sobre el archivo config.xml dentro de los proyectos de cordova, este archivo es independiente de la plataforma y esta basado en el formato especifico de la W3C (Empaquetado de aplicaciones web (Widgets)), ampliado para cumplir con las especificaciones de la API Cordova, con sus plugins y con la configuración de cada plataforma.

Por defecto tiene varios elementos:
    • Atributo id de la etiqueta <widget>: el cual proporciona un identificador y un número de versión.
    • La etiqueta <name>: especifica el nombre formal de la aplicación, como aparece en la pantalla principal del dispositivo y como aparecerá dentro de la tienda de app.
    • Las etiquetas <descripcion> y <author>: especifican metadatos e información de contacto que pueden aparecer en los anuncios de la tienda app.
    • La etiqueta opcional <content>: la cual define la página de inicio de la aplicación. El valor predeterminado por defecto es el archivo index.html, que habitualmente se encuentra en el directorio www del proyecto. 
    • Etiquetas <access>: definen el conjunto de dominios externos que pueden comunicarse con la aplicación. El valor determinado que se muestra, le permite acceder a cualquier servidor. 
    • La etiqueta <preference>: establece varias opciones como pares de, nombre/valor de atributos, referidos a las preferencias name, siendo sensible a las mayúsculas. Muchas de estas preferencias son exclusivas de plataformas especificas.
 Aparecen de este modo una serie de preferencias globales, como:
  • Fullscreen: permite ocultar la barra de estado en la parte superior de la pantalla. El valor predeterminado es false
  • Orientation: Permite bloquear la orientacion y evitar que se rote la pantalla en respuesta a los cambios de orientacion del  dispositivo. Los valores posibles son; default, landscape y protrait.
 Y otras preferencias sobre multiples plataformas, como:

  • DisallowOverscroll (boolean, valor predeterminado false): Si no se quiere que la interfaz regenere el scroll de la pantalla. Esto puede dar problemas, pero se arreglan tan solo poniendo el valor en true.
  • BackgroundColor: Sirve para definir el color de fondo de la aplicacion, admitiendo un valor hexadecimasl de cuatro bytes, representando el primero el valor alfa y los demas el RGB stándard para los siguientes tres bytes.
  • HideKeyboardFomAccessryBar (boolean, valor predeterminado false): si se coloca en true, se oculta la barra de herramientas que aparece encima del teclado.
Finalmente hemos puesto el uso de la etiqueta <feature> así como su posición en, los archivos config.xml y su formato básico:


 <featurename="Plugin"value="PluginID"/>