AIR Mobile – Utilisation de Google Maps par StageWebView
L'API Google Maps est disponible sous plusieurs formats. Sous forme d'API JavaScript, qui doit être la plus utilisée ou sous forme d'API ActionScript:
En ce qui concerne l'API ActionScript, vous pouvez récupérer un fichier SWC contenant les composants essentiels comme Map ou Overlay. Quelques tags plus tard, vous pouvez avoir votre carte dans votre application. Mais avant de l'utiliser, il vous faut récupérer une clé API en donnant à Google l'URL de l'application par laquelle vous allez charger l'API. Tout cela pour compter vos nombres de demandes de tuiles et de géocodage (limités en usage gratuit).
Sauf que si vous voulez utiliser une carte Google Maps dans une application AIR, vous n'êtes pas lié à une URL, leur système partait donc en miettes. Il n'était d'ailleurs pas possible d'intégrer une carte Google Maps dans une application AIR pendant un bon moment jusqu'à l'arrivée d'un fix.
Google Maps API for Flash + AIR: How did we ever breathe before?
En plus de passer une clé (propriété "url" sur Map), on passe une "key" qui correspond à une URL par laquelle l'application AIR peut être téléchargée. Franchement discutable comme concept mais le pire n'est pas là.
Le bug qui bloque tout le monde
Alors ils ont beau faire les malins avec leur système de key, les gars du SDK Google Maps se sont complètement plantés. Pour preuve, un Bug Report qui est là depuis le 29 Septembre 2010:
http://code.google.com/p/gmaps-api-issues/issues/detail?id=2750
Pour résumer, si vous l'utilisez dans un projet AIR, votre application freeze pendant 15-30 secondes. La raison est complètement interne à l'API et comme le code n'est pas open source, il n'est pas très facile de savoir d'où vient ce bug. Certains sont quand même aller fouiller dans les tripes de l'API et on trouvé que l'on chargeait toute l'application dans un ByteArray sur lequel on effectuait un cryptage SHA1, sûrement pour les problématiques de clé API. Bref, c'est inutilisable, même si plusieurs "workaround" sont apparus dans le thread dont un monkey patch de la classe SHA1.
Pour les applications mobile, même problème. Sur un système Android, on vous demande même si vous voulez faire un "force close" tellement il pense que l'application ne répond plus. Inutilisable en l'état.
La solution avec StageWebView
Si vous avez besoin de plus de fonctionnalités basées sur l'API AS, vous êtes foutus (vous pouvez toujours utiliser le hack mais attention aux problèmes de licence). Pour une utilisation simple (affichage de carte), il existe une alternative que je ne vais même pas appeler un "hack". De plus, cette solution sur mobile est cross-platform (Android, iOS). Ce que l'on va faire, c'est utiliser la classe StageWebView pour intégrer un navigateur dans son application et afficher Google Maps en version mobile (adapté).
Pour info, @achauvire l'a utilisée dans son application AIR pour iOS (ESEO sur l'AppStore) si vous voulez la tester.
Voici la solution expliquée sur le blog d'Igor Costa:
Hacking Google maps to work on your Flex 4.5 /AIR mobile project
Voici entre autre, la partie de code qui nous intéresse:
<?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)">
<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>
<s:navigationContent>
<s:Button label="Go Back" click="goBackHandler(event)"/>
</s:navigationContent>
</s:View>
Après, vous pouvez utiliser tous les paramètres URL qu'il est possible d'utiliser dans Google Maps pour effectuer des recherches / placements. Voici le rendu sur Android:
Articles similaires
- AIR pour mobiles – Bug de Google Maps (freeze) enfin pris en compte par Google
- AIR Mobile – Afficher des pop-up natives depuis AIR (hack)
- Flex/Air – Google Maps API non compatible avec Adobe Air
- AIR pour Android – Visualiser la géolocalisation GPS sur Google Maps avec Air
- AIR pour Android – Application P2P Radar (Google Maps 3D, Twitter et Stratus)
Aucun trackbacks pour l'instant







1 juin 2011
Merci pour la citation.
A noter que nous n'avons pas utilisé l'url http://maps.google.com mais une page qui se charge d'afficher une carte avec l'api V3 javascript car nous devions créer des marqueurs en fonction d'une requête en base.
9 juin 2011
Hello,
J'ai testé la solution.. et visiblement la StageView reste blanc.
Ce problème est également rapporté sur le site d'Igor Costa resté sans solution à ce jour.
A bientôt
Aurélien
12 février 2012
Hello,
Très intéressant comme article. Petite question pour les spécialistes, comment faire pour interagir avec la StageWebView afin de poser un marker… OU si quelqu'un est calé en Google Maps, comment poser un marker sur une carte qui ne soit pas une StaticMap ?
Merci !!
Cdlt,
Guillaume
12 février 2012
OK, avec http://www.flex-tutorial.fr/2011/05/24/air-mobile-la-librairie-stagewebviewbridge-pour-etendre-les-capacites-de-stagewebview/, je pense que j'ai trouvé de quoi m'occuper…
17 février 2012
Hello,
Je suis en train de tester l'intégration de cette solution à une appli mobile. Les premiers test on été concluant dans l'émulateur sous flex. Mais lorsque j'ai voulu tester l'application sur iphone… et bien ça ne marche pas.
Après recherche il semble, a moins qu'il y ai une subtilité que je n'ai pas compris, qu'il y ai un problème avec l'API de google. La V3 en faite. La V2 semble fonctionner.
Du coup j'aimerai quand même être sûr de cela. En fait j'ai juste vu un petit message dans le bug reporting de google map api (en bas de page), mais c'est tout.
http://code.google.com/p/gmaps-api-issues/issues/detail?id=2750#c82
Sinon j'ai téléchargé l'application de @achauvire qui en effet fonctionne. Donc, j'aurais aimé savoir quelle version de l'api à-t-il utilisé ?
Merci
17 février 2012
Bonjour,
Je voudrais savoir s'il était possible (avec cette solution) de mettre des boutons dans une bulle Google Maps et faire un évent sur ce bouton (vers une autre vue).
Merci d'avance.
18 février 2012
@Graphy et Guillaume
Jetez un oeil sur e-skimo:
http://e-skimo.com/
Il y a un composant GMaps qui permet une intégration facile dans une application Flex, et la possibilité d'ajouter des markers par exemple
@Graphy
Salut,
en fait, il ne faut pas utiliser le composant "Map" du SDK Google Maps, comme expliqué dans cet article, il faut intégrer un composant StageWebView (de Flex) et le faire pointer sur une simple page web. Sur cette page web, tu vas intégrer une carte Google Maps grâce à l'API Google Maps JavaScript
@Guillaume
Oui, il est possible d'ajouter un Marker, il suffit dans ta page web d'appeler la méthode addMarker sur ta carte. Regarde bien le composant de la librairie e-skimo
Fabien
23 février 2012
Hello
Super Fabien, merci pour ton lien, cela m'a permet de comprendre la cause et de résoudre mon problème.
Pour info, il ne s'agissait pas d'un bug de la v3 de l'api google (oups, toutes mes confuses =), enfin pas vraiment, mais plutôt parce que je cherchais à utiliser la fonction loadString() de StageWebView, et ce pour m'éviter d'avoir à faire à appelle à une page html externe.
Or cela ne fonctionne pas. Cela vient bien de l'api google qui plante lorsque l'on appelle map = new google.maps.Map(…). Pour quelle raison, mystère… surement un problème d'url.
Le composant GMap d'e-skimo crée un fichier temporaire à l'aide d'un objet File et écrit le code html à l’intérieur. Au final il peut donc faire appel à la fonction loadURL()… les malins
En tout cas, encore merci, parce que j'en étais presque à m'avouer vaincu =)
23 février 2012
Bonjour,
En fait ajouter le marqueur avec l'API Javascript Google Maps, je sais le faire.
Ma question c'est : comment savoir (depuis l'appli mobile Flex) que l'utilisateur a cliqué sur tel marqueur (pour ouvrir un fichier de cet objet).
Guillaume