Recently I was building Flash Camp Brazil android version of app to attendees, and we came across a problem, using Google Maps on AIR mobile development. Since, theses days many developers are facing the problem, I’d like to demo and show you how to deal with that, even with other solutions around there.
Likely, I was authorize to open-source the application to the crowd, and many folks mailed us regarding Google Maps on air mobile project, they was in need help to solve a better propose and how to really work with Google Maps without facing 15 up to 30 seconds wait time. You of course don’t want your user waits this time to use your maps or app.
According to the official issue, Google uses SHA-1 encoding to locale somethings on the maps even collections of some sort of map data, which impacts in small devices with limited resources, since the .swc provided by Google Maps Team, is out of date and still uses Flex 3 architecture and component life cycle is hard to use on Mobile, since they are updated to Flex 4.5.
This particular problem isn’t only related to Flex problem actually is a problem on the .swc provided, which keeps you waits much longer than you expect. Since there’s no signal of update or fix, we have workarounds, that drive us for better safe and palliative solution for particular problem.
Google Maps is always update to Javascript developers, since is the main target for Google and of course they have this right, why not use those most recent release of js inside our project, it will of course help us a lot. The current version of Maps for Javascript developers in this time of blog post is V3, which is highly performance for Desktop and Mobile devices, Whooahhh!
Google always keep Javascript version update, and we can use that on our mobile Project. This way we can put in practice Adobe AIR StageWebView class in use and take advantage of using it with air mobile project.
Dealing with StageWebView is a little tricky because you have to remove it if you’re not in the current Screen and intend to remove it to show other view.
With your Flash Builder open, create a new Flex Mobile Project.

I created two views, first one is just to push to the Maps View where resides my StageWebView class, and where I will deal with it. But if you’re new to Flex Mobile here’s the source code of each view.
First View
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
<fx:Script>
<![CDATA[
protected function button1_clickHandler(event:MouseEvent):void
{
navigator.pushView(MapView);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout paddingLeft="10" paddingRight="10" paddingTop="40"/>
</s:layout>
<s:Button label="Show my map" click="button1_clickHandler(event)"/>
</s:View>
MapView (Second View)
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" viewDeactivate="removeStageWebViewHandler(event)" title="MapView" viewActivate="view1_viewActivateHandler(event)">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.events.ViewNavigatorEvent;
private var myWebView:StageWebView;
/**
* @protected
* Just add and set site of my StageWebView
* */
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
myWebView = new StageWebView();
myWebView.stage = this.stage;
myWebView.loadURL("http://maps.google.com");
myWebView.viewPort = new Rectangle(0,70,stage.stageWidth,stage.stageHeight-150);
}
/**
* @private
*
* Just override to re-scale due to auto-orientation project nature
* */
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
if (myWebView) {
var point:Point = localToGlobal(new Point());
myWebView.viewPort = new Rectangle(point.x, point.y, unscaledWidth, unscaledHeight);
}
}
protected function goBackHandler(event:MouseEvent):void
{
navigator.popToFirstView();
}
protected function removeStageWebViewHandler(event:ViewNavigatorEvent):void
{
myWebView.stage = null;
// just remove the target and will leave.
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:navigationContent>
<s:Button label="Go Back" click="goBackHandler(event)"/>
</s:navigationContent>
</s:View>
Great, by now you’re enabled to see the device showing the Google Maps optimize V3 map. And you hacked the Google Maps for Flash and used a better solution, but we have a serious problem, this just show you how to show the map, but if you want from a for example click on a item and show in the map that address. How to deal with that, Yeah! just use url parameters.
I can configure whatever I want in Google Maps V3 just by URL, when you search on “maps.google.com” directly on your browser you assume that hidden google Maps pass some parameters and those can be seen by clicking it at Link.
Well, I will use this URL “http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=”+ city + “&z=12&sensor=true”, to the demo, since “city” is a String property that I’ve created, I will pass throw navigator.pushToView to be setted, since my StageWebView is setted when the view is activate I will no need to worry about that.
Again, here’s my first view, with little list of special cities.
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="HomeView">
<fx:Script>
<![CDATA[
protected function button1_clickHandler(event:MouseEvent):void
{
navigator.pushView(MapView);
}
protected function list1_clickHandler(event:MouseEvent):void
{
navigator.pushView(MapView,mycities.selectedItem);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:layout>
<s:VerticalLayout paddingLeft="10" paddingRight="10" paddingTop="40"/>
</s:layout>
<s:actionContent>
<s:Button label="Show my map" click="button1_clickHandler(event)"/>
</s:actionContent>
<s:Label fontSize="29" fontWeight="bold" text="Or select a city bellow:"/>
<s:List id="mycities" width="100%" click="list1_clickHandler(event)">
<s:dataProvider>
<s:ArrayList>
<fx:String>San Francisco,CA</fx:String>
<fx:String>Petrolina,PE Brazil</fx:String>
<fx:String>London,UK</fx:String>
<fx:String>France,FR</fx:String>
</s:ArrayList>
</s:dataProvider>
</s:List>
</s:View>
And my Map View (second view)
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" viewDeactivate="removeStageWebViewHandler(event)" title="MapView" viewActivate="view1_viewActivateHandler(event)">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.events.ViewNavigatorEvent;
private var myWebView:StageWebView;
private var city:String;
/**
* @protected
* Just add and set site of my StageWebView
* */
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
// set the city with data default property of each view
city = data.toString();
myWebView = new StageWebView();
myWebView.stage = this.stage;
// myWebView.loadURL("http://maps.google.com"); // default
myWebView.loadURL("http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q="+ city + "&z=12&sensor=true");
myWebView.viewPort = new Rectangle(0,70,stage.stageWidth,stage.stageHeight);
}
/**
* @private
*
* Just override to re-scale due to auto-orientation project nature
* */
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
if (myWebView) {
var point:Point = localToGlobal(new Point());
myWebView.viewPort = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
}
}
override protected function stateChanged(oldState:String, newState:String, recursive:Boolean):void
{
}
protected function goBackHandler(event:MouseEvent):void
{
navigator.popToFirstView();
}
protected function removeStageWebViewHandler(event:ViewNavigatorEvent):void
{
myWebView.stage = null;
// just remove the target and will leave.
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:navigationContent>
<s:Button label="Go Back" click="goBackHandler(event)"/>
</s:navigationContent>
</s:View>
Awesome, I no need to worry about setting Lat, Long, don’t need to get my location or any kind of trick, just use URL parameter and my StageWebView, couldn’t be simple isn’t.
Here’s some screenshots of the app.


Good luck with your other projects. There’s always other ways like local files with markers, because via URL Google doesn’t provide that.