Skip to main content
Participant
February 9, 2013
Question

Has anyone been successful with "apk expansion pack" solution through air for android for large apps

  • February 9, 2013
  • 3 replies
  • 1912 views

We have a 300 MB application which is very video happen and we need to find a solution that packages the content along an install file that is less than 50 MB for the android market.

any help would be greatly appreciated.

This topic has been closed for replies.

3 replies

Participant
July 1, 2013

In Flash CS6, I built my own downloader for when the app is run the first time. First it creates a list of files to be downloaded then downloads them one at a time. After all files are downloaded I used the ELS to save the download status.

import flash.net.URLRequestHeader;

import flash.net.URLLoader;

import flash.net.URLLoaderDataFormat;

import flash.net.URLRequest;

import flash.filesystem.FileStream;

import flash.filesystem.File;

import flash.filesystem.FileMode;

import flash.utils.ByteArray;

import flash.events.ProgressEvent;

import flash.display.Loader;

import VideoInfo;

import flash.events.IOErrorEvent;

import flash.net.NetworkInfo;

import flash.net.NetworkInterface;

function downloadAllFiles():void {

    //downloads files

    fileIndex = 0;

    downloadNextFile();

}

function downloadNextFile():void {

    //downloads one file

    if (fileIndex <= video_list.length-1) {

        //progress bar

        //progress_mc.width = 1;

        //progress_txt.text = "";

        status_txt.text = "Download in progress...";

        var fileURL:String           = video_list[fileIndex].videoURL;

        fileName                         = video_list[fileIndex].videoName;

        fileSize                           = video_list[fileIndex].videoSize;

        var fileMimeType:String = video_list[fileIndex].videoMimeType;

        var header:URLRequestHeader = new URLRequestHeader("Content-Length", "0");

        var header2:URLRequestHeader = new URLRequestHeader("Content-Type", fileMimeType);

        fileRequest = new URLRequest(fileURL);

        fileRequest.method = URLRequestMethod.GET;

        fileRequest.contentType = fileMimeType;

        fileRequest.requestHeaders.push(header);

        fileRequest.requestHeaders.push(header2);

        urlLoader = new URLLoader();

        urlLoader.addEventListener(Event.COMPLETE, onDownloadComplete);

        urlLoader.addEventListener(ProgressEvent.PROGRESS, onDownloadProgress);

        urlLoader.addEventListener(IOErrorEvent.IO_ERROR, onDownloadError);

        urlLoader.dataFormat = URLLoaderDataFormat.BINARY;

        urlLoader.load(fileRequest);

    } else {

        trace("All files have been downloaded.");

        wait_txt.text = "";

        status_txt.text = "All files were downloaded.";

        //show continue button

        btn_box_mc.btnLabel.text = "CONTINUE";

        btn_box_mc.visible = true;

        downResBtn.visible = true;

        downResBtn.addEventListener(MouseEvent.CLICK, onDownloadCompleteFunc);

        //saved download status in the local store

        MovieClip(root).setAssetsDownloadStatus();

    }

}

function onDownloadCompleteFunc(evt:MouseEvent):void {

    //downloads complete handler

    //start app

}

function onDownloadComplete(evt:Event):void{

    //download complete handler

    status_txt.text = "Downloaded " + fileName + ".";

    //trace(fileName + " downloaded to " + File.applicationStorageDirectory.nativePath);

    var dataD:ByteArray = evt.target.data;

    //save the file

    var fileStream:FileStream = new FileStream();

    var dFile:File = File.applicationStorageDirectory;

    dFile = dFile.resolvePath(fileName);

    fileStream.open(dFile, FileMode.WRITE);

    fileStream.writeBytes(dataD, 0, dataD.length);

    fileStream.addEventListener(Event.COMPLETE, onSaveComplete);

    fileStream.addEventListener(ProgressEvent.PROGRESS, onSaveProgress);

    fileIndex++;

    //accumlated oize

    totalAccumulatedSize += curVideoAccumulatedSize;

    downloadNextFile();

}

function onDownloadError(evt:IOErrorEvent):void {

    //download error handler

    trace("Error downloading " + fileName);

    wait_txt.text = "";

    status_txt.text = "Error downloading " + fileName + ".";

    //show exit button

    btn_box_mc.btnLabel.text = "QUIT";

    btn_box_mc.visible = true;

    downResBtn.visible = true;

    downResBtn.addEventListener(MouseEvent.CLICK, exitFunc);

}

function exitFunc(evt:MouseEvent):void {

    //exit

    NativeApplication.nativeApplication.exit(0);

}

function onDownloadProgress(evt:ProgressEvent):void{

    //download complete handler

    //trace("Progress: " + evt.currentTarget.bytesLoaded + "/" + fileSize);

    //var temp_txt:String = debug_txt.text;

    //debug_txt.text = temp_txt + "\nFile: " + fileName + " (bytes downloaded: " + evt.currentTarget.bytesLoaded + "/" + fileSize + ")";

    curVideoAccumulatedSize = evt.bytesLoaded; //file must reside on a server that doesn't gzip enabled

    var count:Number = fileIndex + 1;

    var perc:Number = Math.round(100*(totalAccumulatedSize + curVideoAccumulatedSize)/totalSize);

    var partialMB:Number = (totalAccumulatedSize + curVideoAccumulatedSize)/1048576;

    progress_txt.text = String(perc) + "% completed (" + String(partialMB.toFixed(1)) + " of " + totalSizeMB.toFixed(1) + " MB)";

    status_txt.text = "Downloading file #" + count + " of " + video_list.length + ":  "  + fileName;

    //progress bar

    progress_mc.width = 480*(partialMB/totalSizeMB);

}

function onSaveProgress(evt:ProgressEvent):void{

    //save complete handler

    trace("Saving file... ");

}

function onSaveComplete(evt:Event):void{

    //save complete handler

    trace("File saved.");

}

function createVideo(fn:String, fs:int, mimetype:String):VideoInfo {

    //returns a video

    var assetsURL:String = "http://mywebsite.com/myvirtualdirectory/";

    var fURL:String = assetsURL + fn;

    var video:VideoInfo = new VideoInfo(fn, fURL, fs, mimetype);

    return video;

}

function createVideoList():void {

    //creates the list of videos to download

    //populate video list

    video_list.push(createVideo("building2_1.flv", 1858694, "video/x-flv"));

    video_list.push(createVideo("building2_2.flv", 1905661, "video/x-flv"));

    video_list.push(createVideo("building2_3.flv", 1810634, "video/x-flv"));

    video_list.push(createVideo("building2_4.flv", 1994332, "video/x-flv"));

    video_list.push(createVideo("building3_1.flv", 1828362, "video/x-flv"));

    video_list.push(createVideo("building3_2.flv", 2550128, "video/x-flv"));

    video_list.push(createVideo("building4_1.flv", 2249678, "video/x-flv"));

    video_list.push(createVideo("building4_2.flv", 1301540, "video/x-flv"));

    video_list.push(createVideo("building5_1.flv", 3152689, "video/x-flv"));

    video_list.push(createVideo("building5_2.flv", 4258518, "video/x-flv"));

    video_list.push(createVideo("building5_4.flv", 1741195, "video/x-flv"));

    video_list.push(createVideo("building6_1.flv", 3295741, "video/x-flv"));

    video_list.push(createVideo("building7.flv", 1723062, "video/x-flv"));

    video_list.push(createVideo("district1.mp4", 1876220, "video/mp4"));

    video_list.push(createVideo("district3.mp4", 2087587, "video/mp4"));

    video_list.push(createVideo("district6.mp4", 2011591, "video/mp4"));

    video_list.push(createVideo("district8.mp4", 4870888, "video/mp4"));

     video_list.push(createVideo("global1.mp4", 2007542, "video/mp4"));

    video_list.push(createVideo("global2.mp4", 4148857, "video/mp4"));

    video_list.push(createVideo("global3.mp4",  3563990, "video/mp4"));

    video_list.push(createVideo("global4.mp4", 2452995, "video/mp4"));

    //calculate total size

    for (var p=0; p < video_list.length; p++) {

        totalSize += video_list

.videoSize;

    }

    totalSizeMB = 0.1*Math.round(10*totalSize/1048576);

    //start download

    downloadAllFiles();

}

var fileName:String;

var fileSize:int;

var fileRequest:URLRequest;

var urlLoader:URLLoader;

var fileIndex:Number = 0;

var curVideoAccumulatedSize:Number = 0;

var totalAccumulatedSize:Number = 0;

var totalSize:Number = 0;

var totalSizeMB:Number = 0;

var video_list:Array = new Array();

//create list of files to be downloaded

createVideoList();

VideoInfo.as

package {

    public class VideoInfo {

        public var videoName:String;

        public var videoURL:String;

        public var videoSize:Number;

        public var videoMimeType:String;

        public function VideoInfo(videoNameP:String, videoURLP:String, videoSizeP:Number, mimetypeP) {

            videoName             = videoNameP;

            videoURL             = videoURLP;

            videoSize            = videoSizeP;

            videoMimeType        = mimetypeP;

        } 

    }

}

June 12, 2013

I have the same issue. My app exceeds the max size with 50 MB. Is there no way to use the "apk expansion pack"?

Adobe Employee
June 12, 2013

Could you please try break your application into multiple swfs and other assets.

And then try packaging them externally into an "apk expansion pack".

And then you may use this pack as recommened by Google  - unzipping the contents if required and using them.

Legend
January 13, 2014

Hi Damanjit,

I've tried researching this before and found little info. Any chance you've come across any useful blogs / tutorials from AIR developers who have used expansion packs successfully?

Thanks,
G

Mark.fromOP
Inspiring
February 10, 2013

This is not what you are looking for but you can stream the video instead of having it embedded, of course this requires at least a network connection.