En los capítulos anteriores hemos revisado diversos temas importantes para el desarrollo de aplicaciones Flex para móviles los cuales te recomendamos revisar si aún no lo has hecho:

Uso de la Cámara

El uso de la cámara dentro de las aplicaciones es una característica muy vistoza que permite a los usuarios un alto nivel de interacción puesto que podemos permitir que agreguen contenido generado desde su propio dispositivo. Un gran ejemplo de esto es la aplicación llamada Scrapbook toda una referencia hablando de ejemplos bien logrados dentro de PlayBook.

Si vamos a utilizar la cámara dentro de nuestras aplicaciones, lo primero que debemos tener en cuenta es proporcionar los permisos adecuados a nuestra aplicación tal y como lo hemos descrito en el capítulo de Permisos y Configuraciones de esta guía. Dentro de los parámetros que hay que dar de alta se encuentran use_camera y access_shared una vez hecho esto y aprovechando el API disponible nuestras aplicaciones podrán aprovechar la interface nativa de la cámara de la PlayBook.

A continuación vamos a poner un código muy simple que nos permitirá interactuar con la cámara dentro de una aplicación Flex.

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="application1_creationCompleteHandler(event)">

<s:layout>
<s:VerticalLayout horizontalAlign="center" verticalAlign="middle" gap="25" />
</s:layout>

<fx:Script>
<![CDATA[
import mx.events.FlexEvent;

private var camara:CameraUI;

private function capturar(event:MouseEvent):void {
camara.launch(MediaType.IMAGE);
}

protected function application1_creationCompleteHandler(event:FlexEvent):void
{
if (CameraUI.isSupported){ 
camara = new CameraUI();
camara.addEventListener(MediaEvent.COMPLETE, onComplete);
camara.addEventListener(ErrorEvent.ERROR, onError);
} else {
miBoton.label="Cámara no Disponible";
}
}

private function onComplete(event:MediaEvent):void {
var mp:MediaPromise = event.data;
imagen.source = mp.file.url;
}

private function onError(event:ErrorEvent):void {
trace("error");
}

]]>
</fx:Script>

<s:Button id="miBoton" label="Tomar Foto" click="capturar(event)" enabled="{CameraUI.isSupported}" /> 

<s:Image id="imagen" width="550" click="imagen.source=null"  />

</s:Application>

En la aplicación anterior tenemos una interface bastante simple en la cual hay un botón asociado a una función capturar() que manda llamar el API de la cámara dentro del dispositivo BlackBerry PlayBook, previamente hay un setup inicial en la aplicación asociado al evento creationComplete que valida la disponibilidad de la cámara y en caso de no estar disponible, cambia la etiqueta de nuestro botón de captura.

Una vez tomada la foto existe un componente Image que aprovecha la información contenida en un elemento de tipo MediaPromise y lo asocia con la propiedad source de la imagen.

El resultado al momento de ejecutar la aplicación podemos apreciarlo en la siguiente imagen:

API Camara PlayBook

Cabe destacar que para probar de manera correcta esta aplicación tendremos que hacerlo directamente sobre un dispositivo físico, ya que ni AIR en el escritorio ni el simulador ejecutándose sobre VMWare tienen la posibilidad de darnos acceso.

Datos del Acelerómetro

El acelerómetro dentro de un dispositivo nos permite medir los cambios de velocidad de un dispositivo cuando se mueve sobre diferentes planos. De los primeros dispositivos capaces de dar acceso a los desarrolladores en la Plataforma Flash a este tipo de información fue el llamado Chumby que también tuvo una relación con QNX la base del sistema operativo de PlayBook.

Mediante el acelerómetro es posible que nuestro dispositivo sepa internamente en que posición lo estamos sosteniendo y permita por ejemplo rotar la pantalla, inclusive en algunos dispositivos se encuentra la función de activar el shuffle dentro del reproductor musical y estos son tan solo algunos ejemplos de lo que podríamos lograr si incorporamos este tipo de características a nuestras aplicaciones. Ahora revisemos un sencillo ejemplo del API del acelerómetro dentro de PlayBook:

<?xml version="1.0" encoding="utf-8"?>
  <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark" 
  creationComplete="application1_creationCompleteHandler(event)">
  <fx:Script>
  <![CDATA[
  import flash.sensors.Accelerometer;
  
  import mx.events.FlexEvent;
  
  private var acelerometro:Accelerometer;
  
  private function actualizar(event:AccelerometerEvent):void { 
  datosAcelerometro.text = "aceleración X:" + event.accelerationX + "\n\n" 
  + "aceleración Y: " + event.accelerationY + "\n\n" 
  + "aceleración Z: " + event.accelerationZ; 
  }
  
  protected function application1_creationCompleteHandler(event:FlexEvent):void
  {
  if(Accelerometer.isSupported==true){
  acelerometro = new Accelerometer();
  acelerometro.addEventListener(AccelerometerEvent.
  UPDATE,actualizar); 
  } else {
  //status.text = "Accelerometer not supported"; 
  }
  }
  
  ]]>
  </fx:Script>
  
  <s:TextArea id="datosAcelerometro" width="100%" height="300" />
</s:Application>

En el código de esta aplicación veremos que se declara una variable “acelerómetro”, la cual vamos a asociar a un objeto de tipo Accelerometer una vez que validemos la disponibilidad del mismo dentro de la función application1_creationCompleteHandler. Al final hay un evento actualizar ligado a dicho acelerómetro que mostrará la información correspondiente dentro de un componente de TextArea cada que se detecte un cambio en la posición del dispositivo.

El resultado podemos apreciarlo en la siguiente imagen:

Acelerómetro BlackBerry PlayBook

Al igual que en el ejemplo del API de cámara para probar esta aplicación necesitaremos hacerlo en un dispositivo que nos reportará los movimientos en los diferentes ejes X, Y o Z, no podremos apreciarlo mediante el emulador.

Grabar Audio desde el Micrófono

Es posible utilizar las ondas de audio recibidas por el micrófono dentro de una aplicación Flex para PlayBook mediante el API disponible, solo debemos activar los permisos de uso de record_audio y play_audio para empezar.

En el siguiente código se aprovecha el API de micrófono en una aplicación, en un momento más explicaremos su funcionamiento:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
xmlns:s="library://ns.adobe.com/flex/spark" 
creationComplete="application1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;

private var microfono:Microphone;
private var grabacion:ByteArray;
private var sonido:Sound;


private function micDataHandler(event:SampleDataEvent):void{
grabacion.writeBytes(event.data);
}

protected function grabarHandler(event:MouseEvent):void
{ 
grabacion = new ByteArray();
microfono.addEventListener(SampleDataEvent.SAMPLE_DATA, micDataHandler);
grabar.enabled = false;
detener.enabled = true;
}

protected function detenerHandler(event:MouseEvent):void
{
microfono.removeEventListener(SampleDataEvent.SAMPLE_DATA, micDataHandler);
grabar.enabled = true;
reproducir.enabled = true;
}

protected function reproducirHandler(event:MouseEvent):void
{
grabacion.position = 0;
sonido = new Sound();
sonido.addEventListener(SampleDataEvent.SAMPLE_DATA, reproducirSonido);
sonido.play(); 
}

private function reproducirSonido(event:SampleDataEvent):void
{
for (var i:int = 0; i < 8192 && grabacion.bytesAvailable > 0; i++){
var sampleo:Number = grabacion.readFloat();
event.data.writeFloat(sampleo);
event.data.writeFloat(sampleo);
}
} 

protected function application1_creationCompleteHandler(event:FlexEvent):void
{
detener.enabled = false;
reproducir.enabled = false;
if(Microphone.isSupported){
microfono = Microphone.getMicrophone();
microfono.rate = 44; 
microfono.setUseEchoSuppression(true);
} else {
estado.text="Microphone no disponible";
}
}

]]>
</fx:Script>

<s:layout>
<s:VerticalLayout horizontalAlign="center" />
</s:layout>

<s:Label id="estado" text="Click para grabar" width="100%" />
<s:Button id="grabar" label="Grabar" click="grabarHandler(event)" />
<s:Button id="detener" label="Detener" click="detenerHandler(event)" />
<s:Button id="reproducir" label="Reproducir" click="reproducirHandler(event)" />
</s:Application>

Primero necesitamos una instancia de un objeto microfono de tipo Microphone, que podemos declarar directamente en el bloque de Script de nuestra aplicación, después en la función asociada al evento creationComplete revisamos si hay acceso al dispositivo y en caso positivo establecemos el rate para ese objeto microfono a 44 (hablando en términos de frecuencia), también cambiaremos el estado enabled de los botones de nuestra interface para reflejar al usuario que debe de grabar primero algo antes de intentar reproducirlo.

Dentro de la función grabarHandler de la aplicación creamos un objeto de tipo ByteArray en la variable grabacion que nos permitirá asociar la información obtenida del audio una vez que se registra el evento SampleDataEvent que se encarga de notificar a micDataHandler que debe usar la función writeBytes para grabar el sonido. Dentro de la lógica de esa aplicación si queremos detener la grabación de audio solo hace falta presionar el botón detener que manda llamar a la función detenerHandler que lo único que hace es remover el listener para el evento SampleDataEvent.

El responsable de reproducir el sonido es la función reproducirHandler al acceder al ByteArray y crear una instancia de un objeto de tipo Sound y registrar un listener para que el mismo sonido notifique de un evento SampleDataEvent a la función reproducirSonido en donde se recorre el ByteArray disponible para escribirlo a la propiedad data del SampleDataEvent y ser reproducido en las bocinas de la PlayBook.

El resultado podemos apreciarlo en la siguiente imagen:

Micrófono para PlayBook

Al igual que en el ejemplo del API de cámara y acelerómetro para probar esta aplicación necesitaremos hacerlo en un dispositivo que nos permitirá grabar los sonidos desde el micrófono.

Gestos Multitouch

Una de las principales ventajas de un dispositivo de tipo tableta es el hecho de poder recibir interacción de parte del usuario hacia nuestras interfaces mediante los dedos y el registrar los múltiples puntos de contacto es algo que podemos hacer mediante el API Multitouch en nuestra PlayBook. Para poder registrar las múltiples pulsaciones sobre la pantalla tendremos clases específicas como GestureEvent enfocada a detectar un tap con dos dedos sobre la pantalla.

La forma de utilizarlo es muy simple como veremos a continuación:

<?xml version="1.0" encoding="utf-8"?>
  <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
  xmlns:s="library://ns.adobe.com/flex/spark"
  applicationComplete="application1_applicationCompleteHandler(event)">
  <fx:Script>
  <![CDATA[
  import mx.events.FlexEvent;
  
  private function onGesture(event:GestureEvent):void{
  informacion.text = "event = " + event.type + "\n" +
  "localX = " + event.localX +  " localY = " + event.localY + "\n"
  + "stageX = " + event.stageX + " stageY = " + event.stageY; 
  }
  
  protected function application1_applicationCompleteHandler(event:FlexEvent):void
  {
  Multitouch.inputMode = MultitouchInputMode.GESTURE;
  if(Multitouch.supportsGestureEvents){
  stage.addEventListener(GestureEvent.GESTURE_TWO_FINGER_TAP, onGesture);
  } else {
  trace("no soportado");
  } 
  
  }
  
  ]]>
  </fx:Script>
  
  <s:layout>
  <s:VerticalLayout />
  </s:layout>
 <s:TextArea id="informacion" width="100%" height="150" editable="false"/>
  
  <s:Image width="500" height="133" source="@Embed('maestros.png')"/>
  
  </s:Application>

Al cargarse la aplicación manda llamar al evento application1_applicationCompleteHandler que es el responsable de invocar al API de Multitouch con el GestureEvent de GESTURE_TWO_FINGER_TAP. Al ejecutar la aplicación veremos las coordenadas localX y localY actualizarse al igual que stageX y stageY, sin embargo algo interesante a notar es que si hacemos un doble tap sobre la imagen dentro de la aplicación las coordenadas locales serán relativas al objeto.

El resultado podemos apreciarlo en la siguiente imagen:

Gestos BlackBerry PlayBook

Este en un ejemplo que tendremos que probar en un dispositivo PlayBook que nos permitirá interactuar con gestos de tipo Multitouch.

Tips de Experto

  • Recientemente se publicó la versión 2.0 del sistema operativo de BlackBerry PlayBook para los usuarios, el cuál también vino acompañado de una actualización del SDK que utilizamos para desarrollo.
  • En otro nivel de especialización dentro del desarrollo de aplicaciones para BlackBerry PlayBook existe otro nivel de componentes llamados QNX mismos que se encuentran documentados en la siguiente dirección. Es una decisión bastante interesante el experimentar las posibilidades que ofrecen.