1 Reply Latest reply on Apr 7, 2008 9:02 PM by Dr. Fred Mbogo

    AIR Seamless install from within Flex App

    dkerr
      experimenting with this goal: Single button click to install an Air App from within a flex app...
      built this test flex app using code from with the Adobe docs...

      http://www.fusionpage.com/flex/airSeamless/bin/airSeamless.html (code at bottom)

      Gettin' close to what I want. Seems to works as long the user doesn't have Air installed and/or they don't have my .air app installed. But, if either case is true, appears to hang.

      I want it to:
      -install Air if they don't have it
      - install my .air app if they don't have it
      - update my .air app if it is a new version

      My assumption was that air.swf installapplication() would do all of this for me. Should it? What am I missing? Seems like this should be an out-of-the-box thing, but I'm not having much luck finding examples.

      Any help would be appreciated.
      Don Kerr
      Manager, Space City AUG





      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="absolute">
      <mx:Script>
      <![CDATA[
      public var airSWF:Object;
      public function installButtonClick():void {

      var airSWFLoader:Loader = new Loader();
      var loaderContext:LoaderContext = new LoaderContext();
      loaderContext.applicationDomain = ApplicationDomain.currentDomain;
      airSWFLoader.contentLoaderInfo.addEventListener(Event.INIT, onInit);
      airSWFLoader.load(new URLRequest(" http://airdownload.adobe.com/air/browserapi/air.swf"),loaderContext);
      }

      public function onInit(e:Event):void {
      airSWF = e.target.content;
      installApp();
      }
      public function installApp():void{
      var airurl:String = " http://www.fusionpage.com/flex/launchPadAIR/FusionpagelaunchPad.air";
      var runtimeVersion:String = "1.0";
      //var arguments:Array = ["launchFromBrowser"]; // Optional
      airSWF.installApplication(airurl, runtimeVersion);
      }

      public function getStat():void{
      var status:String = airSWF.getStatus();
      statText.text = status;
      }



      ]]>
      </mx:Script>
      <mx:VBox>

      <mx:Button label="INSTALL AIR App" click="installButtonClick();"/>
      <mx:Button label="Status" click="getStat();"/>
      <mx:Label id="statText"/>

      </mx:VBox>
      </mx:Application>
        • 1. Re: AIR Seamless install from within Flex App
          Dr. Fred Mbogo Level 1
          It's not hanging. airSWF.installApplication() just quietly returns without doing anything if it's not being called in direct response to a UI event. The UI event is over by the time your onInit() is called. You need to load air.swf ahead of the UI event, so you can just call into it at need.

          You can argue that this is wasteful as it means you end up loading it speculatively instead of only when you know for certain you need it.

          On the other hand, having air.swf available at startup opens other doors, like being able to test whether the AIR version is already installed, and change the UI accordingly. My own Flex app's "install AIR version" button becomes "launch AIR version" instead when it sees the AIR version is installed and up-to-date, or "upgrade AIR version" if an old version is installed.

          Here's the code. (Sorry for the formatting...Adobe, fix the forum to let us post code sanely!)

          public function checkForAirVersion(flexVersion:String):void
          {
          var loader:Loader = new Loader();

          loader.contentLoaderInfo.addEventListener(Event.INIT, function(e:Event):void {
          try {
          var airSWF:Object = e.target.content;
          var status:String = airSWF.getStatus();
          if ((status == 'available') || (status == 'installed')) {
          var appID:String = 'my.application.id';
          var pubID:String = 'HUGEHEXNUMBERHERE.1';
          airSWF.getApplicationVersion(appID, pubID,
          function(airVersion:String):void
          {
          if (airVersion != null) {
          if (airVersion != flexVersion) {
          downloadButton.label = 'Upgrade AIR Version';
          }
          else {
          downloadButton.label = 'Launch AIR Version';
          downloadButton.addEventListener(MouseEvent.CLICK,
          function():void {
          airSWF.launchApplication(appID, pubID);
          });
          }
          }

          if (downloadButton.label.indexOf('Launch') == -1) {
          downloadButton.addEventListener(MouseEvent.CLICK,
          function():void {
          airSWF.installApplication(
          ' http://my.site.com/path/to/app.air',
          '1.0');
          });
          }

          downloadButton.enabled = true;
          });
          }
          }
          catch (e:Error) {
          trace('Error installing or checking for AIR version:\n\n' + e.message);
          }
          });

          var loaderContext:LoaderContext = new LoaderContext();
          loaderContext.applicationDomain = ApplicationDomain.currentDomain;
          loader.load(
          new URLRequest(" http://airdownload.adobe.com/air/browserapi/air.swf"),
          loaderContext);
          }


          This whole feature is self-contained in a single top-level function, called at application startup. There aren't even any external variables. The only thing I recommend that you do externally is disable your download button so the user can't click on it until the Flex version decides which of the three possible actions the button will do. This is why it sets the 'enabled' property to true near the end of the INIT event handler.