Acceder a dispositivos de almacenamiento en AIR 2.0

Este es uno de los tips de Adobe AIR 2.0 que más me agradó preparar, porque en realidad tenía la necesidad, en un proyecto, de acceder a dispositivos de almacenamientos para leer, editar y grabar información. La clase StorageVolume nos permite leer todos los archivos existentes en nuestro dispositivo de almacenamiento, reconociendo los permisos de los archivos, si son de sistema o no, etc. Por otro lado podemos crear y eliminar directorios, así como también archivos: moviendo, copiando, etc. Recuerda que debes tener Adobe AIR 2.0 configurado en tu Flash Builder o Eclipse

Entonces para este tip, haremos una básica aplicación que permita reconocer cuando se insertó o removió un dispositivo de almacenamiento. Empezaremos creando la interfaz:

Código :

<s:Label id="msg" width="100%" y="20" text="inserta un USB drive"  
          verticalAlign="top" textAlign="center" 
          color="#110E91" fontWeight="bold"/>
<mx:Box id="boxContent" width="90%" height="126" x="20"  y="40"/>

Ahora crearemos nuestros listener que estén pendientes de cuando el dispositivo sea agregado o retirado, para eso usaremos una función que será ejecutada al iniciar la aplicación:

Código :

private function init():void{
   StorageVolumeInfo.storageVolumeInfo.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_MOUNT, mount, false, 0, true);
   StorageVolumeInfo.storageVolumeInfo.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_UNMOUNT, unMount, false, 0, true);
}

Y escribimos ahora las funciones que nos avisará en el campo de texto:

Código :

private function mount(e:StorageVolumeChangeEvent):void{
   var myDrive:StorageVolume = e.storageVolume;
   msg.text = "Se conectó: "+ myDrive.name + "  Size: "+Math.round( (myDrive.rootDirectory.spaceAvailable /1073741824) *100)/100 +" Gb";
}
         
private function unMount(e:StorageVolumeChangeEvent):void{
   msg.text = "Se removió: "+ e.rootDirectory.nativePath;
}

Si conectamos un dispositivo:

Si retiramos el dispositivo:

Vemos que nuestro evento StorageVolumeChangeEvent nos avisa cuando un dispositivo fue agregado o removido, este a su vez, nos envía información importante como por ejemplo el nombre, el espacio disponible, que tipo es ("FAT", "NTFS", "HFS" o "UFS"), etc. Pero lo más importante es poder acceder a los archivos que contiene.

Reconocer los archivos

En realidad hasta aquí es el tip de acceso a dispositivos de almacenamiento, pero decidí ampliarlo un poco más reconociendo los archivos que contiene, para eso usaremos la propiedad rootDirectory y recorreremos el dispositivo usando el método getDirectoryListing().

Usaré una función que nos haga el trabajo de reconocer los directorios (carpetas) y archivos para poder guardarlos en un arreglo y usarlo después:

Código :

private var $__arrFile:Array = new Array();

private function readDrive( files:File ):void{
   var arr:Array = files.getDirectoryListing();
   for each (var f:File in arr){
      if (f.isHidden == false){
         if (f.isDirectory){
            trace("Directorio", f.name);
         }else{
            trace("archivo", f.name );
            $__arrFile.push(f);
         }
      }
   }
}

Listo!!!, tenemos guardado en el arreglo todos los archivos que podemos acceder.

¿Y ahora?

Ya tenemos los archivos del dispositivo y podemos basarnos en el anterior tip que hice de Abrir archivos con Adobe AIR 2.0, creando una lista y abriendo con la aplicación por defecto cada file.

Nos valdremos de un componente creado en Flex para poder colocar el nombre del archivo y su id del array. Lo llamaremos MyBox.mxml.

Código :

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" 
       xmlns:s="library://ns.adobe.com/flex/spark" 
       xmlns:mx="library://ns.adobe.com/flex/mx" 
       creationComplete="init()"
       width="200" height="20">
   <s:Label x="10" y="5" width="180" height="15" 
          id="campo" buttonMode="true"/>
   
   <fx:Script>
      <![CDATA[
         public var idBox:int;
         
         private function init():void{
            this.addEventListener(MouseEvent.MOUSE_OVER, mouseEvent, false, 0, true);
            this.addEventListener(MouseEvent.MOUSE_OUT, mouseEvent, false, 0, true);
         }
         
         public function setLabel(myText:String):void{
            if(myText.length>=20)
               myText = myText.substr(0,15)+"..."+myText.substr(myText.length-4,4);
            campo.text = myText
         }
         
         private function mouseEvent(e:MouseEvent):void{
            if(e.type == MouseEvent.MOUSE_OVER)
               this.alpha = 0.2;
            else
               this.alpha = 1;
         }
      ]]>
   </fx:Script>
   
</s:Group>

Volvemos a nuestra aplicación y creamos una función que utilice el componente MyBox y haga la lista:

Código :

private function createList():void{
   for (var i:int = 0; i< $__arrFile.length; i++) {
      var box:MyBox = new MyBox();
      box.setLabel( $__arrFile[i].name );
      box.y = 30*i;
      box.idBox = i;
      box.addEventListener(MouseEvent.CLICK, go, false, 0, true);
      boxContent.addElement(box);
   }
}

He creado un listener de Mouse que llama al evento go, que abrirá el archivo con su aplicación por defecto:

Código :

private function go(e:MouseEvent):void{
   var tmp:File = ($__arrFile[e.currentTarget.idBox] as File);
   tmp.openWithDefaultApplication();
}

Y con eso tenemos ya nuestra aplicación funcionando, reconociendo los archivos de tu dispositivo de almacenamiento y al dar click abrir el archivo.

Ingresamos un dispositivo:

Hacemos click a un elemento de la lista, por ejemplo al SWF:

Eso es todo, quería hacer los thumb pero creo que ya salía un poco del tip, pero haré otro con eso :P Aquí les dejo el código completo:

Código :

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                  xmlns:s="library://ns.adobe.com/flex/spark" 
                  xmlns:mx="library://ns.adobe.com/flex/mx" 
                  creationComplete="init()"
                  width="300" height="200">

   <fx:Script>
      <![CDATA[
         
         private var $__arrFile:Array = new Array();
         
         private function init():void{
            StorageVolumeInfo.storageVolumeInfo.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_MOUNT, mount, false, 0, true);
            StorageVolumeInfo.storageVolumeInfo.addEventListener(StorageVolumeChangeEvent.STORAGE_VOLUME_UNMOUNT, unMount, false, 0, true);
         }
      
         private function mount(e:StorageVolumeChangeEvent):void{
            var myDrive:StorageVolume = e.storageVolume;
            msg.text = "Se conectó: "+ myDrive.name + "  Size: "+Math.round( (myDrive.rootDirectory.spaceAvailable /1073741824) *100)/100 +" Gb";
            readDrive( myDrive.rootDirectory );
         }
         
         private function unMount(e:StorageVolumeChangeEvent):void{
            msg.text = "Se removió: "+ e.rootDirectory.nativePath;
         }
         
         private function readDrive( files:File ):void{
            var arr:Array = files.getDirectoryListing();
            for each (var f:File in arr){
               if (f.isHidden == false){
                  if (f.isDirectory){
                     trace("Directorio", f.name);
                  }else{
                     trace("archivo", f.name );
                     $__arrFile.push(f);
                  }
               }
            }
            createList();
         }
         
         private function createList():void{
            for (var i:int = 0; i< $__arrFile.length; i++) {
               var box:MyBox = new MyBox();
               box.setLabel( $__arrFile[i].name );
               box.y = 30*i;
               box.idBox = i;
               box.addEventListener(MouseEvent.CLICK, go, false, 0, true);
               boxContent.addElement(box);
            }
         }
         
         private function go(e:MouseEvent):void{
            var tmp:File = ($__arrFile[e.currentTarget.idBox] as File);
            tmp.openWithDefaultApplication();
         }
      ]]>
   </fx:Script>
   
   <s:Label id="msg" width="100%" y="20" text="inserta un USB drive"  
          verticalAlign="top" textAlign="center" 
          color="#110E91" fontWeight="bold"/>
   <mx:Box id="boxContent" width="90%" height="126" x="20"  y="40"/>
   
</s:WindowedApplication>

Pueden descargar la aplicación aquí.

Enviar comentario

Deja una respuesta