I wrote couple of handy classes to handle retrieving / downloading of any type of files to a local directory in AIR. These classes are useful for building an AIR application that works online and offline. You can download multimedia, HTML and other file types. Once files are downloaded you can store the information in SQLite database and serve the information, once your system is not connected to the internet.
The core class “DownloadManager.as” allows you to download files to any location in your local drive using: “File.desktopDirectory.resolvePath(fileLocalLocation)” or you can also point to where the application directory sits: “File.applicationStorageDirectory.resolvePath(fileLocalLocation);”
public function downloadFileFromServer(fileURL:String, fileLocalLocation:String):void
{
//var file:File = File.desktopDirectory.resolvePath(fileLocalLocation);
var file:File = File.applicationStorageDirectory.resolvePath(fileLocalLocation);
request = new URLRequest(fileURL);
fileStream.openAsync(file, FileMode.WRITE);
stream.addEventListener(ProgressEvent.PROGRESS, onDownloadProgress);
stream.addEventListener(Event.COMPLETE, onDownloadComplete);
stream.load(request);
}
Notice we defined the steam event handlers and load the file. We now need to define event handler, to handle the progess during the download and once completed;
private function onDownloadProgress(event:ProgressEvent):void
{
var byteArray:ByteArray = new ByteArray();
var precent:Number = Math.round(bytesLoaded*100/bytesTotal);
bytesLoaded = event.bytesLoaded;
bytesTotal = event.bytesTotal;
stream.readBytes(byteArray, 0, stream.bytesAvailable);
fileStream.writeBytes(byteArray, 0, byteArray.length);
var progressEvent:ProgressEvent = new ProgressEvent(ProgressEvent.PROGRESS);
progressEvent.bytesLoaded = bytesLoaded;
progressEvent.bytesTotal = bytesTotal;
this.dispatchEvent(progressEvent);
}
private function onDownloadComplete(event:Event):void
{
fileStream.close();
stream.close();
stream.removeEventListener(ProgressEvent.PROGRESS, onDownloadProgress);
stream.removeEventListener(Event.COMPLETE, onDownloadComplete);
var completeEvent:Event = new Event(Event.COMPLETE);
this.dispatchEvent(completeEvent);
}
Here’s a little MXML component that implements the download manager and the ReadDirectoryHelper.
Once we init the application, we check if the file exists and download the file if it doesn’t exists. Additionally, we are using the download manager with a ProgressBar to show the download progress.
<WindowedApplication xmlns="http://ns.adobe.com/mxml/2009"
layout="absolute"
initialize="init()">
<Script>
<![CDATA[
import com.elad.framework.utils.ReadDirectoryHelper;
import com.elad.framework.utils.DownloadManager;
import mx.controls.Alert;
private function init():void
{
var array:Array = ReadDirectoryHelper.getDirectoryFiles("/Users/elad/Desktop/tmp/");
var isExists:Boolean = ReadDirectoryHelper.isFileExists(array, "file.flv");
if (isExists == false)
downloadFile();
else
Alert.show("File Already exists");
}
private function downloadFile():void
{
var downloadHelper:DownloadManager = new DownloadManager();
downloadHelper.addEventListener(ProgressEvent.PROGRESS, onDownloadProgress);
downloadHelper.addEventListener(Event.COMPLETE, onDownloadComplete);
downloadHelper.downloadFileFromServer("http://samples.mplayerhq.hu/FLV/asian-commercials-are-weird.flv",
"/Users/elad/Desktop/tmp/file.flv");
}
private function onDownloadProgress(event:ProgressEvent):void
{
var value:Number = event.bytesLoaded;
var total:Number = event.bytesTotal;
var precent:Number = Math.round(value*100/total);
if (progressBar.minimum==0)
{
progressBar.minimum = value;
progressBar.maximum = total;
}
progressBar.label = "Progress "+precent+"%";
progressBar.setProgress(value, total);
}
private function onDownloadComplete(event:Event):void
{
Alert.show("Download Completed!");
}
]]>
</Script>
<ProgressBar id="progressBar"
x="4" y="63"
minimum="0"
label="Progress 0%"
mode="manual" />
</WindowedApplication>

To download the source code of the AIR application click here.


















