4 Replies Latest reply on Mar 24, 2008 3:05 PM by Dr. Fred Mbogo

    installApplication from another AIR app

    Dr. Fred Mbogo Level 1
      I have a Flex application on a web site that has a companion AIR version of the same app, and I would like to offer badge.swf like functionality from within that Flex app for installing the AIR version.

      I had this working back when I was using Flex Builder 3 Beta 3, and it has failed at some time since then. I cannot say for certain that it happened immediately on upgrading to the final version, but I can't think of anything else I've done since that would break it.

      Here's my code for handling the "Download" button within the Flex version, based on code in various official Adobe samples and docs:

      function installClickHandler():void
      {
      var loaderContext:LoaderContext = new LoaderContext();
      loaderContext.applicationDomain = ApplicationDomain.currentDomain;
      var loader:Loader = new Loader();
      loader.contentLoaderInfo.addEventListener(Event.INIT, function(e:Event):void {
      var airSWF:Object = e.target.content;
      var status:String = airSWF.getStatus();
      if ((status == 'available') || (status == 'installed')) {
      var appID:String = 'my.app.id';
      var pubID:String = 'BIGLONGSTRINGOFHEX.1';
      airSWF.getApplicationVersion(appID, pubID, function(version:String):void {
      if (version != null) {
      airSWF.launchApplication(appID, pubID, [ ]);
      }
      else {
      airSWF.installApplication(' http://url.to.my/app.air', '1.0');
      }
      });
      });
      loader.load(new URLRequest(" http://airdownload.adobe.com/air/browserapi/air.swf'), loaderContext);
      }

      Not shown is the try block I have wrapping all of this, and all of the 'else' clauses for catching exceptional conditions. NONE of this happens. Depending on whether the AIR version is already installed or not, execution always either gets down to the installApplication() or launchApplication() call. It doesn't matter which fork the execution takes, it always fails silently. I have another page on the web site with the stock badge.swf, which works fine when pointed to the same AIR file URL.

      Is this an intended feature removal, or a bug? And if a bug, is it my bug, or Adobe's? :)

      P.S. How can I post code and retain the formatting?
        • 1. Re: installApplication from another AIR app
          Oliver Goldman Adobe Employee
          Both installApplication() and launchApplication() have to be called during a user event--e.g., a button click--in order to have any effect. This is a security consideration, not a bug.

          Most badges accomplish this by calling getApplicationVersion() immediately upon loading, or at some interval. When the user clicks the associated button they can then immediately invoke either launchApplication() or installApplication().

          regards,
          Oliver Goldman | Adobe AIR Engineering


          • 2. Re: installApplication from another AIR app
            Dr. Fred Mbogo Level 1
            Yes, I RTFM'd, and thought I'd answered the question implicitly by calling the function installClickHandler() above. :) It's called from the 'click' handler of an <mx:LinkButton>. Is this not close enough to a button click?

            Also, the code above is more complex than it once was, as I've added the other air.swf calls to help understand the problem. The version that worked before only called installApplication(), using code differing the sample in the manual only in matters of style. I don't think there would be any point in moving the call to getApplicationVersion() to some other part of the program.

            Is there some way to get an error code back from installApplication() that will help us understand why it is refusing to run? I don't see such a thing in the manual.
            • 3. Re: installApplication from another AIR app
              Oliver Goldman Adobe Employee
              Although installClickHandler() is being called from the click handler, the call to getApplicationVersion() is asynchronous. When the callback provided to that method is called, the click handler is no longer on the stack and your code is no longer running in the context of a user event.

              There are no error codes returned by installApplication(), as they would leak information back to the web page that the web page should not have.

              Oliver Goldman | Adobe AIR Engineering

              • 4. Re: installApplication from another AIR app
                Dr. Fred Mbogo Level 1
                Oh, I see. Too bad there's no way to pass the button click context info into the closure...

                I solved it this way:

                1. Make the Download button initially disabled, with no click handler.

                2. Load air.swf when the Flex app starts

                3. When it loads, check the AIR app's version. Then:

                4a. If no version, or version number isn't equal to the known latest AIR version, set the click handler to call installApplication(). Button text is changed to indicate whether it will download or upgrade.

                4b. Otherwise, set click handler to launchApplication() and change the button text to indicate that it will launch the existing version.

                5. Either way, enable the Download/Upgrade/Launch button.

                The click handler setup looks like this:
                downloadButton.addEventListener(MouseEvent.CLICK,
                function():void {
                airSWF.launchApplication(appID, pubID);
                });

                ...and similar for the installApplication() version.

                Because ECMAScript supports closures, you can do all of this within the "check for existing version" function, which loads the air.swf file. It's more complex than I'd like, but the code still fits on a single screen. Good enough.