Avoiding sandbox violation in AIR when using DragManager on locally stored images

For a mini AIR project I had some issue with sandbox security violation warnings that kept coming up any time I was using DragManager on images for which the source had been set to some locally held images (within the User Directory).

To bypass these warning, it is required to load the bytes into a bitmap and to get the image component display the bitmap. Code below.

The component that contains the image. The source is bound to the variable imageBitmap


override public function set data(value:Object):void
loadImageFromUrl(imageFile.url);
}

// avoiding the security sandbox violation that occurs when using the url as source
private function loadImageFromUrl(imageUrl:String):void
{
var bmpLoader:BitmapLoader = new BitmapLoader();
bmpLoader.addEventListener(
BitmapLoadEvent.COMPLETE,
function(event:BitmapLoadEvent):void { imageBitmap = event.bitmap; }
)
bmpLoader.load(imageUrl);
}

A separate class is used to do the loading as this functionality is required in different places in the application.


package com.widged.utils
{
import flash.display.Bitmap;
import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.ByteArray;

// All this is required to avoid a security sandbox violation upon image dragging the image.

public class BitmapLoader extends EventDispatcher
{
private var _bitmap:Bitmap;
public function get imageBitmap():Bitmap
{
return _bitmap;
}

public function BitmapLoader()
{
}

/**
* Load the bytes of an image at a given url
*/
public function load(imageUrl:String):void
{
var urlLoader:URLLoader = new URLLoader();
var urlRequest:URLRequest = new URLRequest(imageUrl);

urlLoader.addEventListener(Event.COMPLETE, onByteLoaded);
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load(urlRequest);
}

/**
* Load the bytes into a loader to create a bitmap
*/
private function onByteLoaded(event:Event):void
{
var bytes:ByteArray = URLLoader(event.target).data;
var byteLoader:Loader = new Loader();
byteLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBitmapComplete);
byteLoader.loadBytes(bytes);
}

/**
* Send the bitmap data to any listening component
*/
private function onBitmapComplete(event:Event):void
{
this.dispatchEvent(new BitmapLoadEvent(BitmapLoadEvent.COMPLETE, Bitmap(event.target.content)));
}

}
}

A custom event carrying the bitmap data


package com.widged.utils
{
import flash.display.Bitmap;
import flash.events.Event;

public class BitmapLoadEvent extends Event
{

public static const COMPLETE:String = "bitmapComplete";

public var bitmap:Bitmap;

public function BitmapLoadEvent(type:String, bmp:Bitmap)
{
super(type, false, false);
this.bitmap = bmp;
}

/**
* Override of the clone function of the Event class.
* Such an override is required whenever creating a new class
*/
override public function clone():Event {
return new BitmapLoadEvent(type, bitmap);
}

}
}

Powered by Drupal, an open source content management system