0

I am trying to make this code a resumable and again download an aerray of URLs but I am struggling. The code only seems to download the last file but ignores the first one.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="init(event)" viewSourceURL="srcview/index.html">
    <mx:Script>
        <![CDATA[


            import flash.events.Event;
            import flash.events.ProgressEvent;
            import flash.net.URLRequest;
            import flash.net.URLStream;
            import flash.utils.ByteArray;
            import mx.controls.Alert;
            import mx.events.FlexEvent;

            //Declear variables
            private var urlStream:URLStream;
            private var fData:ByteArray;
            private var bytesLoaded:Number = 0;
            private var totalBytesLoaded:Number = 0;
            private var bytesTotal:Number = 0;
            private var fileName:String = "";
            private var file:File;
            private var fileStream:FileStream = new FileStream;

            //initialize even listeners
            protected function init(event:FlexEvent):void{
                urlStream = new URLStream;
                urlStream.addEventListener(ProgressEvent.PROGRESS, onProgress);
                urlStream.addEventListener(Event.COMPLETE, onComplete);


                var letters:Array = ["http://www.khanhvanweb.com/Music/Spanish Guitar Toni Braxton.mp3","http://dropthebeat.tv/audio/ToniBraxton-Please.mp3"];

                for (var i:int = 0; i < letters.length; i++) {
                    trace("Element " + i + ": " + letters[i]);
                    fileInput.text = letters[i];

                startDownload();
                }

            }

            //Start Downloaing

        //  if (fileInput.text = ""){


            public function startDownload():void{
                bytesLoaded = 0;
                bytesTotal = 0;
                totalBytesLoaded = 0;

                var url:String = fileInput.text;
                var index:int = url.lastIndexOf('/');
                fileName = url.substring(index+1, url.length);

                var str1:String = "/Music/ClassicalShop.Net/";

            //  file = File.documentsDirectory.resolvePath(fileName);
                //'Save to classical muic directory
                file = File.userDirectory.resolvePath(String(File.userDirectory.url + str1 + fileName));

                status = file.url;

                if(file.exists) {
                    btn.label = 'Download';
                    mx.controls.Alert.show('Please remove "'+fileName+'" from your disk', 'File with the same name already exists');
                    return;
                }

                output.text += 'Downloading\n';

                urlStream.load( new URLRequest(url) );
                fData = new ByteArray;
                fileInput.enabled = false;

                fileStream.open(file, file.exists ? FileMode.APPEND:FileMode.WRITE); }


        //  }




            private function pauseDownload():void {
                output.text += 'Downloading is paused\n';
                if(urlStream.connected) {
                    fData.clear();
                    urlStream.readBytes(fData, fData.length);
                    urlStream.close();
                    fileStream.writeBytes(fData);

                    }

                fileStream.close();

                totalBytesLoaded += bytesLoaded;
                trace( "pause size:"+ totalBytesLoaded);

                }



            //Resume the Download
            private function resumeDownload():void {
                output.text += 'Downloading \n';
                output.text +='bytes='+totalBytesLoaded+'-'+bytesTotal + '\n';
                var header0:URLRequestHeader = new URLRequestHeader('range', 'bytes='+totalBytesLoaded+'-'+bytesTotal);

                var request:URLRequest = new URLRequest(fileInput.text);
                request.requestHeaders.push(header0);

                urlStream.load( request );

                fileStream.open(file, file.exists ? FileMode.APPEND:FileMode.WRITE);
                }

            //Set progress of the file download
            private function onProgress(event:ProgressEvent):void {
                bytesLoaded = event.bytesLoaded;
                if(bytesTotal == 0)
                    bytesTotal = event.bytesTotal;

                trace( "size:"+ bytesLoaded);

                progressBar.setProgress( (totalBytesLoaded + event.bytesLoaded) / bytesTotal, progressBar.maximum);

                if(urlStream.bytesAvailable == 0) return;
                if(urlStream.connected)
                    {
                    fData.clear();
                    urlStream.readBytes(fData, fData.length);
                    fileStream.writeBytes(fData);

                    }
                }

            //Action to take when the file has completed downloading
            private function onComplete(event:Event):void
                {
                output.text += 'Download complete\n';
                bytesLoaded = 0;
                bytesTotal = 0;
                totalBytesLoaded = 0;
                progressBar.setProgress(0, 1);

                if(urlStream.connected)
                    {
                    fData.clear();
                    urlStream.readBytes(fData, fData.length);
                    urlStream.close();
                    fileStream.writeBytes(fData);
                    }

                fileInput.enabled = true;
                btn.label = 'Download';
                fData = null;

                fileStream.close();

                System.gc();
                }


            //write the file to disk
            private function writeFile():void
                {


                output.text += 'Saving File\n';
                var fileStream:FileStream = new FileStream;
                fileStream.open(file, file.exists ? FileMode.APPEND:FileMode.WRITE);
                fileStream.writeBytes(fData);
                fileStream.close();
                output.text += 'File Saved\n';


                }


            private function btnClickHandler():void
                {

                if(bytesLoaded == 0)
                    {
                    btn.label = 'Pause';


                    startDownload();
                    }
                    else
                        {
                        if(urlStream.connected)
                            {
                            btn.label = 'Resume';
                            pauseDownload();
                            }
                            else
                                {
                                btn.label = 'Pause';
        resumeDownload();
    }}}
        ]]>
    </mx:Script>
    <mx:TextInput id="fileInput" y="15" left="67" right="10"/>
    <mx:Button id="btn" x="286" y="65" label="Download" click="btnClickHandler()"/>
    <mx:ProgressBar id="progressBar" x="67" y="65" 
                    mode="manual" minimum="0" maximum="1" label="Downloading %3%%"/>
    <mx:Label x="10" y="20" text="File URL"/>
    <mx:TextArea id="output" left="10" right="10" top="107" bottom="10"/>
    <mx:Button y="65" label="Clear Input" right="10" 
               enabled="{fileInput.text.length==0 ? false:fileInput.enabled}"
               click="fileInput.text = ''"/>
    <mx:Label x="67" y="46" 
              text="http://www.example.com/downloads/episode77.mp3" 
              color="#878787"/>
</mx:WindowedApplication>
Cœur
  • 37,241
  • 25
  • 195
  • 267

2 Answers2

0

This is because you are using global variables. When you start a new URLLoader/URLStream, it closes any previous request and starts with the new one. The solution is simple.

public function startDownload( urlRequest:URLRequest ):void{
    var loader:URLLoader = new URLLoader();
    loader.load( urlRequest );
}

Obviously that is just the basics and you would need to add the rest of your code, but you get the idea. You'll need a completely separate URLRequest and URLLoader/URLStream for each individual file, so you will have to create them within the scope of the function, not the global scope.

If you need to get the URLLoader in the COMPLETE or PROGRESS events, check out event.currentTarget and event.Target.

If you don't want them running simultaneously, you could have a "count" variable that you manually increase within the COMPLETE handler and use that count property to grab the next item in the array.

Josh
  • 8,079
  • 3
  • 24
  • 49
0

I'm not sure if you are trying on mobile platform or not but we have just released our new air native extension on Android which is a resumable, multi-section download manager. check it out here: http://myappsnippet.com/download-manager-air-native-extension/

Hadi tavakoli
  • 1,267
  • 2
  • 16
  • 30