Adobe AIR Auto-Update – How to force some updates and make others optional

If you are looking for information on how to add auto-update capabilities to your Adobe AIR app, start with my earlier blog post, “Adding auto update features to your AIR application in 3 easy steps“.

Most updates to software applications are optional for the user.  The typical flow is that the user is notified that an update is available and then given the choice to update now or later.  However, there are situations that warrant forcing the update.  For example, if you have made changes to server-side APIs that make existing client-side apps unusable, you obviously need all client apps to update themselves.  I recently ran into this situation with my online chess application.  I started reading through the AIR documentation to determine how to make some updates mandatory and others optional.  AIR provides an extensive set of APIs to control each step of the update process from comparing versions to downloading the update to managing the install but this was too much work for a lazy developer like me. 🙂

I typically use the ApplicationUpdaterUI version of the update framework because it’s easy to implement and the built-in dialogs that walk the user through the update are perfect.  To force an update with the ApplicationUpdatedUI, you simply disable two dialogs using the following code:

  • appUpdater.isDownloadUpdateVisible = false; // Disables (skips) this dialog:
  • appUpdater.isInstallUpdateVisible = false; // Disables (skips) this dialog:

With both of these dialogs disabled, the update immediately downloads and installs.   A dialog showing download and install progress is still displayed but you can turn these off too (I wouldn’t recommend turning this off).

My approach

I wrote some code that loads my server-side update.xml file (prior to initializing the application updater) and looks for a new tag I created called “FORCE”.  Once the file is loaded, I initialize the updater and toggle the dialog accordingly.   Now I can control whether an update is forced by simply updating my update.xml.

The sample code below builds on my original blog post.

Server-side xml file with <force>yes</force> added (update2.xml):

<?xml version="1.0" encoding="utf-8"?>
<update xmlns="http://ns.adobe.com/air/framework/update/description/1.0">
<version>v2</version>
<force>yes</force>
<url>http://tourdeflex.adobe.com/blogfiles/AIRAutoUpdateSample/server/AIRAutoUpdateSample-v2.air</url>
<description><![CDATA[
v2
  * These notes are displayed to the user in the update dialog
  * Typically, this is used to summarize what's new in the release
]]>
</description>
</update>

The modified source with code added to look for the FORCE tag.

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="200" height="70" creationComplete="preCheckForUpdate()">
	<mx:Script>
	<![CDATA[
		import flash.events.ErrorEvent;
		import flash.events.IOErrorEvent;
		import air.update.ApplicationUpdaterUI;
		import air.update.events.UpdateEvent;
		import mx.controls.Alert;

		private var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI();

		private var updateXMLURL:String = "http://tourdeflex.adobe.com/blogfiles/AIRAutoUpdateSample/server/update2.xml";

		// Pre-read the server-side XML file to look for <force>yes</force>
		private function preCheckForUpdate():void{
			var loader:URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE, checkForUpdate);
			loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError); // Just in case we can't read the update.xml						

			loader.load(new URLRequest(updateXMLURL));
		}

		private function checkForUpdate(event:Event):void {
			setApplicationVersion(); // Find the current version so we can show it below

		    var myXML:XML = new XML(event.target.data);
			namespace items = "http://ns.adobe.com/air/framework/update/description/1.0";
		    use namespace items;
		    var forceUpdate:String = myXML.force;

			appUpdater.updateURL = updateXMLURL; // Server-side XML file describing update
			appUpdater.isCheckForUpdateVisible = false; // We won't ask permission to check for an update

			// If <force>yes</force> was found above, turn off the download and install dialogs
			if(forceUpdate.toLowerCase() == "yes") {
				appUpdater.isDownloadUpdateVisible = false;
				appUpdater.isInstallUpdateVisible = false;
			}
			appUpdater.addEventListener(UpdateEvent.INITIALIZED, onUpdate); // Once initialized, run onUpdate
			appUpdater.addEventListener(ErrorEvent.ERROR, onError); // If something goes wrong, run onError
			appUpdater.initialize(); // Initialize the update framework
		}

		private function onError(event:ErrorEvent):void {
			Alert.show(event.toString());
		}

		private function onIOError(event:IOErrorEvent):void 
		{
			trace("Error loading URL.");
		}


		private function onUpdate(event:UpdateEvent):void {
			appUpdater.checkNow(); // Go check for an update now
		}

		// Find the current version for our Label below
		private function setApplicationVersion():void {
			var appXML:XML = NativeApplication.nativeApplication.applicationDescriptor;
			var ns:Namespace = appXML.namespace();
			ver.text = "Current version is " + appXML.ns::version;
		}
	]]>
	</mx:Script>

	<mx:VBox backgroundColor="blue" x="0" y="0" width="100%" height="100%">
		<mx:Label color="white" id="ver" />
	</mx:VBox>

</mx:WindowedApplication>
</code>

Keep in mind that forcing an update is borderline intrusive and should be done judiciously.

If you know of a better way to do this, please comment.

~ by gregorywilson on October 16, 2009.

19 Responses to “Adobe AIR Auto-Update – How to force some updates and make others optional”

  1. […] Related blog post: 10/16/2009 – Adobe AIR Auto-Update – How to force some updates and make others optional Possibly related posts: (automatically generated)Battlefield Heroes updates […]

  2. Hi Greg!
    Thank you for a great post!
    I’ve followed the instructions to force the update, but the download update dialog still showed up. I.e.:

    appUpdater.isDownloadUpdateVisible = false; (DID NOT WORK)
    appUpdater.isInstallUpdateVisible = false; (WORKED AS EXPECTED)

    I’m thinking that possibly isDownloadUpdateVisible is ignored with self-signed certificates. What do you think?

    Vitali

    • I’m using a self-signed cert and it’s working. Hmmm…

      AIR 1.5?

      Greg

      • Yes, AIR 1.5. I’ll continue investigating when time permits. For now it was just an attempt to save our users a few clicks when a new version of an internal tool is released.

  3. Hey Greg,
    I love your posts, but one thing I’ve noticed is that they are very difficult to print. Would it be possible to get a print.css added to the site? It would really help your readers, like myself.

    Thanks.

  4. Hey Greg,

    I also worked around this problem but instead provided access to an isForced property, which is set by serverside XML like your example.

    This allows you to inform the user then need to update, rather than making the application restart when they could be in the middle of something.

    http://www.pixelbox.net/2009/09/02/extended-air-app-updater/

    Let me know what you think

    Rob

    • Hey Rob – good post and another good example. As long as appUpdater.delay is set to zero (default value), it shouldn’t update in the middle of anything since it will only check for updates when the app is run each time (I call appUpdater.checkNow() each time app is run).

      Thanks!

      Greg

  5. Thank you for the very informative and useful post Greg.

  6. Hi Greg,
    Is it possible to have simillar update options for Flash Player based Flex app?
    Thanks
    Yog

  7. Hi Greg,

    I have followed your example, which is great and very well laid out. Having just one problem though and sure its a simple fix. When the update screen is loaded it is blank? Any ideas ?

    Rob

  8. I’m developing a AIR Application Online game where i have 1 Game Lobby AIR App (Flex-Based AIR) and games AIR App (Flash CS4 Built Swf, Create AIR file using Flex to load the Swf file).

    The game have only 1 Lobby(air file) and Numbers of games (air files).
    Purpose to having multiple AIR file to make use of AIR auto updates features for the lobby and all games.

    I want to remove/unchecked “Add shortcut icon to my desktop” from the Installation Preferences of AIR Application Install dialogue.

    May i know how to do remove/unchecked “Add shortcut icon to my desktop” feature?

  9. hey man great post, however when I do everything as instructed above, the update dialog fires, but without any content all there is, is a window with blue background. I’m using Air 1.5
    could u help a bit? ty.

  10. thnx for the info and fast response m8! I’ll look it up!

  11. That was resolved as expected. Now the update dialog opens for a sec then disapears. should I use 1.5 in the nameSpace?

    • solved it. And posting the solution: You need to be actually running a previous version than the one on the server to get it right. I was using 1.5 and had only put 1.7 to the update.xml whilst the server application version was compiled 1.5.
      hope it helps a bit someone…

  12. Hey Greg,

    I appreciate your efforts.
    In my application I am adding a button to check for updates, although it pops up if newer version is available. Is there any way to know that the application version is latest or any update is available? If yes, then I would disable the button as no updated version is available for the application.

    Thanks

  13. Very userfull post, and it works with out problems for AIR 2.0

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: