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 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í.