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);