I am making an android application in Air for android using actionscript 3. I need to download a file from the server and save it to mobile sdcard. Following is my code, the file gets loaded from the server but how do I save it on sdcard?
import flash.filesystem.*;
var urlString:String = "http://www.mywebsite.com/xyz/myswftodownload.swf";
var urlReq:URLRequest = new URLRequest(urlString);
var urlStream:URLStream = new URLStream();
var fileData:ByteArray = new ByteArray();
urlStream.addEventListener(ProgressEvent.PROGRESS, onProgress);
urlStream.addEventListener(Event.COMPLETE, loaded);
urlStream.load(urlReq);
function loaded(event:Event):void
{
urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
trace("Loaded");
urlStream.removeEventListener(ProgressEvent.PROGRESS, onProgress);
urlStream.removeEventListener(Event.COMPLETE, loaded);
//NOW HOW TO SAVE THE LOADED FILE ON SDCARD??
}
function onProgress(evt:ProgressEvent):void {
var nPercent:Number = Math.round((evt.bytesLoaded / evt.bytesTotal) * 100);
//loadingAnim.bar.scaleX = nPercent / 100;
status.text = nPercent.toString() + "%";
}
You can do something like this
//NOW HOW TO SAVE THE LOADED FILE ON SDCARD
var file:File = File.userDirectory.resolvePath("myswftodownload.swf");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeBytes(fileData, 0, fileData.length);
fileStream.close();
File.userDirectory usually points to the sdcard (external storage). But beware of the fact that external storage doesn't have to be available at all time (for example when device connected as mass storage by usb).
In your case i would consider using internal storage instead and use File.applicationDirectory or File.applicationStorageDirectory for saving your swf files. External storage is better for saving files like images, music, documents..
Related
This is a Flash application to be deployed in Android device thru Adobe Air. I am trying to save the username and score (boxTwo.text + _clickTxt.text) of the user in a notepad .txt file, without any dialog box appearing in android device. It will be generated once the save button (btnSave) is pressed. I can't make it work. Thanks! This is my code:
import flash.net.FileReference;
import flash.events.Event;
var so:SharedObject = SharedObject.getLocal("Test");
var f:File=new File("path\to\file.txt")
var str:FileStream=new FileStream();
btnSave.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void
{
so.data.saveData = currentFrame;
so.flush();
}
btnSave.addEventListener (MouseEvent.CLICK, saveFile)
function saveFile(evt):void
{
str.open(f, FileMode.WRITE);
str.writeUTFBytes(boxTwo.text + _clickTxt.text);
str.close();
}
By Default Adobe Air does not allow to write files to any directory
You can get writing access only to:
File.documentsDirectory
File.applicationStorageDirectory
a directory that was been chosen by "browseForDirectory()" dialog box
fileVariable.browseForDirectory("Choose a directory");
(There are other directories specific for each platform but generally they are these 3 types)
So just change your path to an allowed directory
var string:String = "Text";
var file:File = File.documentsDirectory.resolvePath("myTxtFile.txt");
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
stream.writeUTFBytes(string);
stream.close();
Where is the best location to save in Android mobile using AIR and how? Im trying to figure out where i can save my file. Im creating a MEMO App where the user can save his/her File, my question is, where is the best location in Android Mobile so save?
That is what File.applicationStorageDirectory is for.
You can save whatever data you want to the file (XML, JSON, AMF, sqlite database), and you can save asynchronously to avoid UI hangs.
Example saving string data (such as serialized XML or JSON):
function save(data:String):void {
var file:File = File.applicationStorageDirectory.resolvePath("preferences.data");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE); // or openAsync()
fileStream.writeUTFBytes(data);
fileStream.close();
}
function load():String {
var file:File = File.applicationStorageDirectory.resolvePath("preferences.data");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var data:String = fileStream.readUTFBytes(fileStream.bytesAvailable);
fileStream.close();
return data;
}
Im making a Test Maker App for both Desktop and Android. I was able to save and load in Desktop but failed on Android. I can ONLY save my file, but i cannot load my saved file. The Android device says "No files were found". It doesnt even open a file browser. The type of saving and loading that im doing is the type where the user can actually look for his project and open it. Im currently using FileReference to do this. It works on Desktop but not on Android Mobile. Can somebody help me with this?
I'm pretty sure you can't use a FileReference on mobile (though someone feel free to correct me if wrong).
On mobile, you should use the File & FileStream classes for loading/saving local files.
Here is an example, of using a compile time constant you could create (to determine if desktop or AIR) and loading appropriately into and out of a textfield called textfield:
CONFIG::air {
var file:File = File.applicationStorageDirectory.resolvePath("myFile.txt");
if(file.exists){
var stream:FileStream = new FileStream();
stream.open(file, FileMode.READ);
textfield.text = stream.readUTF(); //this may need to changed depending what kind of file data you're reading
stream.close();
}else{
data = "default value"; //file doesn't exist yet
}
}
CONFIG::desktop {
//use your file reference code to populate the data variable
}
And to save: (assuming you have a textfield whose text you want to save)
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeUTF(textfield.text);
fileStream.close();
There are other save methods besides writeUTF (which is for plain text) writeObject is good for saving custom object when combined with flash.net.registerClassAlias
File classes are in the flash.filesystem package
EDIT
Here is something you can try for letting the user pick the location on AIR.
var file:File = File.applicationStorageDirectory;
file.addEventListener(Event.SELECT, onFileSelected);
file.browseForOpen("Open Your File", [new FileFilter("Text Files", "*.txt")]);
function onFileSelected(e:Event):void {
var stream:FileStream = new FileStream();
stream.open(e.target as File, FileMode.READ);
textField.text = stream.readUTF();
}
var saveFile:File = File.applicationStorageDirectory.resolvePath("myFile.txt");
saveFile.addEventListener(Event.SELECT, onSaveSelect);
saveFile.browseForSave("Save Your File");
function onSaveSelect(e:Event):void {
var file:File = e.target as File;
var stream:FileStream = new FileStream();
stream.open(file, FileMode.WRITE);
stream.writeUTF(textField.text);
stream.close();
}
var zip:FZip = new FZip();
zip.load(new URLRequest("xx.obb"));
this codes does not work. It throws "Unknown record signature:" error.
how did you extract .obb file ?
that way you need to read it? if it is to load a game I think it is a good way to load it so it would be better to load it from a specific route
for example: sdcard/android/obb/filename.obb
If your obb file is like any other zip file then you can treat it as such. First you will want a list of files to extract (could be all your files who knows).
Here is one way to get the files out :
private function obbFileUnpackingRoutine(event:Event):void{
addChild(obbUnpackScreen);
obbUnpackScreen.obbProgress.scaleX = zipCount/filesToUnpack.length;
setChildIndex(obbUnpackScreen, numChildren -1);
for (var i:uint = 0; i<24; i++){
if (zipCount == filesToUnpack.length){
zipDone = true;
removeEventListener(Event.ENTER_FRAME, obbFileUnpackingRoutine);
removeChild(obbUnpackScreen);
var fr:FileStream=new FileStream();
var str:String = File.applicationStorageDirectory.nativePath;
var cacheDir= new File(str +"/YourSettings");
fr.open(cacheDir.resolvePath("isObbUnpacked.pnr"),FileMode.WRITE);
fr.writeObject([zip.getFileCount(),zipCount]);
fr.close();
return
}
var file:FZipFile = zip.getFileByName(filesToUnpack[zipCount])
var cacheDir:File= null;
var str:String = File.applicationStorageDirectory.nativePath;
cacheDir= new File(str);
var fileContents = file.content
var fr:FileStream=new FileStream();
fr.open(cacheDir.resolvePath(file.filename),FileMode.WRITE);
fr.writeBytes(fileContents);
fr.close();
zipCount++;
}
}
If memory permits you may want to load your files directly from the zip file so you don't have to unpack them.
Any file that can only accessed with a urlRequest will of course have to be extracted
But you can load png files, mp3 files, and your own custom files with byteArrays
My obb file has thousands of tiny mp3 files and it can take upto 3 minutes to extract on an allWinner A10 processor.
Direct loading means it can get the files instantly. And there is almost no delay at all.
I want to download mp3 file, on mobile device iOs or android, because i dont want to download every time from server.
I write simple code, but not work correctly. File size is too big, because is not encode and after save I cant play it again.
Please help and sorry for bad English.
private var sound:Sound;
public function loadSound(tmpUrl:String):void
{
sound = new Sound();
sound.addEventListener(Event.COMPLETE,onLoadSuccessSound, false, 0, true);
sound.load(new URLRequest(tmpUrl));
}
protected function onLoadSuccessSound(event:Event):void
{
var fileData:ByteArray = new ByteArray();
sound.extract(fileData, sound.bytesTotal);
var file:File = new File(File.applicationStorageDirectory + "\\ppp.mp3");
var fs:FileStream = new FileStream();
fs.open(file, FileMode.WRITE);
fs.writeBytes(fileData,0,fileData.length);
fs.close();
}
Basically answer is to use URLStream and FileStream.
Question is pretty widespread and covered, for example, here Download a file with Adobe AIR and AS3: URLStream saving files to desktop?