I found this code snippet i little while ago and found it useful in the app im creating for IOS and i´m trying to save and load this file in AS3 without it asking for a save/load file location and without the device prompting. I am using AIR for IOS
Just to be clear i just want it to save and load to a predetermined location (I.e the app folder).
i have typed in the code below.
stop();
// Timeline instances
var textField1:TextField;
var textField2:TextField;
var saveBtn:SimpleButton;
var loadBtn:SimpleButton;
saveBtn.addEventListener(MouseEvent.CLICK, saveClick);
function saveClick(e:MouseEvent):void {
// Save the state of both text fields
save(textField1.text, textField2.text, "SaveData.xml");
}
loadBtn.addEventListener(MouseEvent.CLICK, loadClick);
function loadClick(e:MouseEvent):void {
load();
}
function save(text1:String, text2:String, SaveData:String):void {
var xml:XML = <xml>
<text1>{text1}</text1>
<text2>{text2}</text2>
</xml>;
var file:FileReference = new FileReference();
file.save(xml, SaveData);
}
function load():void {
var file:FileReference = new FileReference();
file.browse([new FileFilter("XML", "*.xml")]);
file.addEventListener(Event.SELECT, loadSelect);
}
function loadSelect(e:Event):void {
var file:FileReference = e.target as FileReference;
file.addEventListener(Event.COMPLETE, loadComplete);
file.load();
}
function loadComplete(e:Event):void {
var file:FileReference = e.target as FileReference;
var xml:XML = XML(file.data.readUTFBytes(file.data.bytesAvailable));
// Assign the loaded XML text values back to the text fields
textField1.text = xml.text1;
textField2.text = xml.text2;
}
Saving file without prompt, or select dialog, or user consent whatsoever. As I mentioned before, no additional permissions required (I think) to write to File.applicationStorageDirectory location.
Implementation:
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
function saveFile(fileName:String, fileData:String):void
{
var aFile:File = File.applicationStorageDirectory.resolvePath(fileName);
var aStream:FileStream = new FileStream;
aStream.open(aFile, FileMode.WRITE);
aStream.writeUTFBytes(fileData);
aStream.close();
}
Usage:
var X:XML = <xml>
<text1>{text1}</text1>
<text2>{text2}</text2>
</xml>;
saveFile("mytest.xml", X.toXMLString());
Related
i use txt file that contain paths.
after loaded txt file and split to path array
then load img file from array path
but i get err in loading img
please help me
sample code:
var imglst:Array=new Array();
var lodimg:Loader=new Loader();
var lodtxt:URLLoader=new URLLoader();
lodtxt.load(new URLRequest("imglst.txt"));
lodtxt.addEventListener(Event.COMPLETE,onL_C);
function onL_C(e:Event)
{
var t:Array=new Array();
t=e.target.data.split(/\n/);
var s:URLRequest=new URLRequest(t[0].toString());
trace(t[0]);
lodimg.load(s);
}
lodimg.contentLoaderInfo.addEventListener(Event.COMPLETE,onL_Cimg);
function onL_Cimg(e:Event)
{
var i:Bitmap=new Bitmap();
i=Bitmap(lodimg.content);
i.width=100;
i.height=100;
addChild(i);
trace("OK");
}
Are you loading images from a different website from your own? Does the other website(s) have a crossdomain.xml to allow permissions of loading their content? Usually Flash will give you a "security error" as an event but your code isn't listening for such an event so your program is not aware of any such problems... look on google how to handle AS3 errors.
Anyways a workaround is to just load the bytes of file using URLloader and on completion you then only use Loader to decode the bytes into pixel colours.
import flash.utils.ByteArray;
var imglst : Array;
var lodimg : Loader;
//var lodtxt : URLLoader = new URLLoader();
var lodURL:URLLoader = new URLLoader();
var img_bytes : ByteArray = new ByteArray();
lodURL.load(new URLRequest("http://yoursite/imglst.txt"));
lodURL.addEventListener(Event.COMPLETE,onL_C);
function onL_C (e:Event)
{
//# Since load complete no need to keep listening for that
lodURL.removeEventListener(Event.COMPLETE,onL_C);
var t:Array=new Array();
t=e.target.data.split(/\n/);
var s:URLRequest=new URLRequest(t[0].toString());
trace(t[0]);
//lodimg.contentLoaderInfo.addEventListener(Event.COMPLETE,onL_Cimg);
//lodimg.load(s);
//# Now we know path so we load those file bytes
lodURL.dataFormat = URLLoaderDataFormat.BINARY;
lodURL.load(s); lodURL.addEventListener(Event.COMPLETE, onBytes_C);
}
function onBytes_C (e:Event)
{
//# on complete load of bytes...
trace("got bytes");
img_bytes = lodURL.data;
//trace("Image bytes total : " + img_bytes.length);
img_bytes.position = 0; //avoid "end of file" error
lodimg = new Loader();
lodimg.contentLoaderInfo.addEventListener(Event.COMPLETE,onL_Cimg);
lodimg.loadBytes(img_bytes); //we already have data so this will be fast
}
function onL_Cimg (e:Event)
{
var i:Bitmap = new Bitmap();
i = lodimg.content as Bitmap;
i.width=100;
i.height=100;
addChild(i);
trace("OK");
}
I'm having an issue trying to get my code work for my Adobe Flash project. Basically I'm trying to get a button to play a random sound everytime it's clicked which works but I can't have that same code on the same frame for a different button which is why it gives me this error.
Here is my code:
import flash.utils.Dictionary;
import flash.events.MouseEvent;
var request:URLRequest = new URLRequest("19103_b.mp3");
var ci_diese:Sound = new Sound();
ci_diese.load(request);
var request_two:URLRequest = new URLRequest("19203_b.mp3");
var d_diese:Sound = new Sound();
d_diese.load(request_two);
var request_three:URLRequest = new URLRequest("19204_b.mp3");
var f_diese:Sound = new Sound();
f_diese.load(request_three);
var play_liste = 0;
var dictSounds = new Dictionary ();
dictSounds[1] = d_diese;
dictSounds[2] = ci_diese;
dictSounds[3] = f_diese;
fireweapon_H3AR.addEventListener (MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler (event:MouseEvent) : void {
play_liste = Math.ceil(Math.random () *3);
dictSounds[play_liste].play ();
ready_H3AR.addEventListener (MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler (event:MouseEvent) : void {
play_liste = Math.ceil(Math.random () *3);
dictSounds[play_liste].play ();}
}
import flash.utils.Dictionary;
import flash.events.MouseEvent;
var request:URLRequest = new URLRequest("Readya.mp3");
var ci_diese2:Sound = new Sound();
ci_diese2.load(request);
var request_two:URLRequest = new URLRequest("Readyb.mp3");
var d_diese2:Sound = new Sound();
d_diese2.load(request_two);
var request_three:URLRequest = new URLRequest("Readyc.mp3");
var f_diese2:Sound = new Sound();
f_diese2.load(request_three);
var play_liste = 0;
var dictSounds = new Dictionary ();
dictSounds[1] = d_diese2;
dictSounds[2] = ci_diese2;
dictSounds[3] = f_diese2;
ready_H3AR.addEventListener (MouseEvent.MOUSE_DOWN, mouseDownHandler);
function mouseDownHandler (event:MouseEvent) : void {
play_liste = Math.ceil(Math.random () *3);
dictSounds[play_liste].play ();}
}
Any way to rewrite this to accommodate more than one button? The first half works up until it repeats itself at "import flash." I've been searching everywhere for answers so please help!!
You should not name two functions or two variables the same, because the last ones are going to overwrite the first ones.
For example
var request:URLRequest = new URLRequest("19103_b.mp3");
is then overwritten
var request:URLRequest = new URLRequest("Readya.mp3");
The same happens with the button ready_H3AR an the function listener mouseDownHandler
By the way, you don't need to import the classes twice:
import flash.utils.Dictionary;
import flash.events.MouseEvent;
Usually when a task or a block of code is intended to be used many times, it's better to put it in a function to get a simpler and more maintainable code.
So you can do like this :
var sounds:Array = [
['01.mp3', '02.mp3', '03.mp3'], // sounds for the 1st button
['04.mp3', '05.mp3', '06.mp3'] // sounds for the 2nd button
];
var sound:Sound,
sound_channel:SoundChannel = new SoundChannel();
function play_sound(sound_name:String): void
{
var request:URLRequest = new URLRequest('mp3/' + sound_name);
sound = new Sound();
sound.addEventListener(Event.COMPLETE, on_sound_loaded);
sound.load(request);
}
function on_sound_loaded(e:Event): void
{
// if you want, you can stop the current playing sound
// otherwise you don't need the SoundChannel
sound_channel.stop();
sound_channel = Sound(e.target).play();
}
button_01.addEventListener(MouseEvent.MOUSE_DOWN, on_press);
button_02.addEventListener(MouseEvent.MOUSE_DOWN, on_press);
function on_press(e:MouseEvent): void
{
// to get values : 0, 1 or 2
var random:int = int(Math.random () * sounds[0].length);
// if it's the 1st button so pick the sound from the 1st sounds array
if(e.currentTarget.name == 'button_01'){
play_sound(sounds[0][random]);
} else {
play_sound(sounds[1][random]);
}
}
Hope that can help.
I have an Adobe Air desktop message board App built in Flash cs5, it loads an external ".txt" file in a dynamic text field and checks for a new file every 2 minutes. I need it to notify user with (NotificationType.CRITICAL) only if the file is new not just everytime it loads it. is it possible?
all the code in the app:
NativeApplication.nativeApplication.startAtLogin=true
stage.nativeWindow.alwaysInFront=true;
//external text file load and recheck every 2 minutes
var myInterval:uint = setInterval (loadUrl, 120000);
var loader:URLLoader = new URLLoader(new URLRequest("https://my_text_file.txt"));
loader.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void {
var loadedText:URLLoader = URLLoader(event.target);
if(myText_txt.htmlText!=loadedText.data){
myText_txt.htmlText = loadedText.data;
stage.nativeWindow.notifyUser(NotificationType.CRITICAL)
}else {
//do nothing
}
}
function loadUrl():void {
loader = new URLLoader(new URLRequest("https:///my_text_file.txt"));
loader.addEventListener(Event.COMPLETE, completeHandler);
}
// button control
Minimize_BTN.addEventListener(MouseEvent.CLICK, minimize);
function minimize(e:MouseEvent){
stage.nativeWindow.minimize();
}
drag_BTN.addEventListener(MouseEvent.MOUSE_DOWN, drag);
function drag(e:MouseEvent){
stage.nativeWindow.startMove();
}
stop(); //Stop on the frame you want
Your code might not work if the myText_txt field is modifying the loaded text (e.g., if myText_txt's condenseWhite property is set to true). A more accurate way to determine if the text has changed would be to store it in a String variable named, for example, oldText and then comparing oldText with the newly loaded text.
Here's part of your code re-written to include the oldText variable. This code is also more efficient because it instantiates some variables only once and it avoids duplicating some code:
import flash.net.URLRequest;
function completeHandler(event:Event):void
{
var newText:String = loader.data;
if(newText != oldText)
{
myText_txt.htmlText = newText;
stage.nativeWindow.notifyUser(NotificationType.CRITICAL);
oldText = newText;
}
}
function loadUrl():void
{
loader.load(req);
}
// Initialize your variables and event handlers only one time
var req:URLRequest = new URLRequest("https:///my_text_file.txt");
// Set cacheResponse to false to prevent a successful response
// from being cached.
req.cacheResponse = false;
// And don't bother checking the cache, either.
// Not necessary, but the request will execute a little faster.
req.useCache = false;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, completeHandler);
// Use oldText inside completeHandler() to determine
// whether the file's text has changed
var oldText:String = "";
var myInterval:uint = setInterval(loadUrl, 120000);
// Start loading the text right away
loadUrl();
Why don't you use FileReference object to find out about some properties like modificationDate and based on this verify if file is different you can also test it's size.
I have my Flash project properties set for: AIR 3.4 for Desktop and ActionScript 3.0...
I created a button for the user to select a file (csv) from the local drive. I then want to be able to get the string value of the File Object but do not know how...
Here is what I have so far:
BTN_CSV.addEventListener(MouseEvent.CLICK, getCSV);
var myFile:File = new File();
function getCSV(e:MouseEvent):void {
var docFilter:FileFilter = new FileFilter("Documents", "*.csv");
myFile.browse([docFilter]);
myFile.addEventListener(Event.COMPLETE, completeHandler);
}
function completeHandler(event:Event) {
var csvData = myFile.nativePath;
csvData = csvData.data.split("\n");
parseCSV(csvData);
}
I'm getting an error 1061: Call to a possibly undefined method split through a reference with static type flash.utils: ByteArray. I don't know how to get the file path for the file obj...
The file class is basically just a pointer to the file you want.
Your code is almost there you just need to add in the FileStream class.
Source
import flash.filesystem.*;
import flash.events.Event;
var file:File = File.documentsDirectory;
file = file.resolvePath("Apollo Test/test.txt");
var fileStream:FileStream = new FileStream();
fileStream.addEventListener(Event.COMPLETE, fileCompleteHandler)
fileStream.openAsync(file, FileMode.READ);
function fileCompleteHandler(event:Event):void {
var str:String = fileStream.readMultiByte(fileStream.bytesAvailable, File.systemCharset);
trace(str);
fileStream.close();
}
[EDIT]
import flash.events.Event;
import flash.filesystem.File
import flash.filesystem.FileStream
import flash.filesystem.FileMode
var file:File =File.documentsDirectory;
file.addEventListener(Event.SELECT,onSelect)
file.browse()
function onSelect(event:Event):void{
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var str:String = fileStream.readMultiByte(file.size, File.systemCharset);
trace(str);
}
I currently have an swf that allows you to select and display a file and upload it to the server using FileReference. This works great but i need to be able to select and display multiple (up to 25 in some cases) and then upload them all at the end.
I know you can use the FileReferenceList to select multiple files at the same time in the dialog popup but my issue is that the user needs to select one at a time, do stuff to that image, then select another, do stuff and so on... then at the end when they press upload it upload them all onto the server.
Is it possible or is there a way so i can maybe add every new selected file into an array, then at the end it uploads all the files in the array either in one go or loops through each until all objects in the array are complete?
Can anyone help? I'll post the full code for my working single file upload below.
Please, please help, i'm limited with flash and have only been learning for 3-4 months and i've been stuck for over a week now :(
Lauren
as3 Code:
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.utils.ByteArray;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.display.MovieClip;
import fl.controls.ProgressBarMode;
import flash.display.Bitmap;
import flash.display.BitmapData;
progressBar.visible=false;
UploadprogressBar.visible=false;
// Create FileReference.
var imageFile:FileReference;
// Create Loader to hold image content
var image_loader:Loader = new Loader();
var image_content:Sprite = new Sprite();
// Get Extension Function.
var imageExtension;
function getExtension($url:String):String {
var extension:String = $url.substring($url.lastIndexOf(".")+1, $url.length);
return extension;
}
// Random Number Function to create new filename on server.
function randomNum(low:Number=0, high:Number=1):Number {
return Math.floor(Math.random() * (1+high-low)) + low;
}
var myNumber:Number= randomNum(1000,9999);
var myString:String= String(myNumber);
var RandomNumbers = myString;
var imageFilePath = (RandomNumbers);
// Select Button Function.
select_btn.addEventListener(MouseEvent.CLICK, onselect_btnClicked);
function onselect_btnClicked(event:MouseEvent):void {
imageFile=new FileReference();
imageFile.addEventListener(Event.SELECT, onFileSelected);
var imageTypeFilter:FileFilter = new FileFilter("JPG/PNG Files","*.jpeg; *.jpg;*.gif;*.png");
imageFile.browse([imageTypeFilter]);
}
// File Selected Function.
function onFileSelected(event:Event):void {
imageFile.addEventListener(Event.COMPLETE, onFileLoaded);
imageFile.addEventListener(ProgressEvent.PROGRESS, onProgress);
var imageFileName = imageFile.name;
imageExtension = getExtension(imageFileName);
imageFile.load();
progressBar.visible=true;
progressBar.mode=ProgressBarMode.MANUAL;
progressBar.minimum=0;
progressBar.maximum=100;
UploadprogressBar.mode=ProgressBarMode.MANUAL;
UploadprogressBar.minimum=0;
UploadprogressBar.maximum=100;
}
// File Progress Function.
function onProgress(event:ProgressEvent):void {
var percentLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
progressBar.setProgress(percentLoaded, 100);
}
// File Loaded Function.
function onFileLoaded(event:Event):void {
var fileReference:FileReference=event.target as FileReference;
var data:ByteArray=fileReference["data"];
var movieClipLoader:Loader=new Loader();
movieClipLoader.loadBytes(data);
movieClipLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onMovieClipLoaderComplete);
imageFile.removeEventListener(Event.COMPLETE, onFileLoaded);
imageFile.removeEventListener(ProgressEvent.PROGRESS, onProgress);
}
// Load Image onto Stage Function.
function onMovieClipLoaderComplete(event:Event):void {
var loadedContent:DisplayObject=event.target.content;
image_loader =event.target.loader as Loader;
var scaleWidth:Number=345/image_loader.width;
image_loader.scaleX=image_loader.scaleY=scaleWidth;
image_loader.height=200;
image_loader.scaleX=image_loader.scaleY;
image_loader.x=10;
image_loader.y=10;
image_content.buttonMode=true;
image_content.addChild(image_loader);
addChild(image_content);
}
// Upload Button Function.
upload_btn.addEventListener(MouseEvent.CLICK, onupload_btnClicked);
function onupload_btnClicked(event:MouseEvent):void {
var filename:String=imageFile.name;
var urlRequest:URLRequest = new URLRequest("http://www.xxxxx.com/xxxxx/file-reference.php");
var variables:URLVariables = new URLVariables();
urlRequest.method = URLRequestMethod.POST;
imageFile.addEventListener(ProgressEvent.PROGRESS, onUploadProgress);
imageFile.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onUploadComplete);
variables.ID = (RandomNumbers);
urlRequest.data = variables;
imageFile.upload(urlRequest);
}
// File Upload Progress Function.
function onUploadProgress(event:ProgressEvent):void {
var percentLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
UploadprogressBar.setProgress(percentLoaded, 100);
trace("loaded: "+percentLoaded+"%");
upload_status_txt.text='upload in progress...';
}
// Upload File Completed Function.
function onUploadComplete(event:Event):void {
upload_status_txt.text='upload complete';
imageFile.removeEventListener(ProgressEvent.PROGRESS, onProgress);
imageFile.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA,onUploadComplete);
UploadprogressBar.visible=false;
}
php Server Code:
<?php
function getExtension($str) {
$i = strrpos($str,".");
if (!$i) { return ""; }
$l = strlen($str) - $i;
$ext = substr($str,$i+1,$l);
return $ext;
}
$fileID = $_POST['ID'];
$filename = basename( $_FILES['Filedata']['name']);
$extension = getExtension($filename);
$extension = strtolower($extension);
$uploadID = $fileID.'.'.$extension;
if (move_uploaded_file($_FILES['Filedata']['tmp_name'], "images/".$uploadID))
{
echo "OK";
}
else
{
echo "ERROR";
}
?>
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html
"When you call the FileReferenceList.browse() method, which creates an array of FileReference objects."
You need to use FileReferenceList instead of FileReference.