• Home
  • About Me
  • AIR Central
  • AS3 Libs
  • Books
  • Flex Central
  • Resources
  • The Guru's
  •  

    AIR ConnectionManager

    October 1st, 2007

    UPDATED FOR AIR BETA 3

    Many AIR applications require Internet access. The problem is that since the application is launched from the desktop, an Internet connection can not be assumed. I have created a ConnectionManager that will handle all that is involved in testing for a connection.

    The constructor of the ConnectionManagr class accepts three optional arguments. The first is a Boolean which when true, will show the Alert message when a connection failure occurs, it defaults to true. The second is the URL that the ConnectionManager will attempt to connect to. It defaults to http://www.google.com. The last is a String that holds the alert message. It defaults to “This application requires an internet connection.”. The ConnectionManager has a public property named isConnected that will hold the current status of the application. To use the ConnectionManager you will simply need to create an instance of the ConnectionManager class and set any of the optional arguments. Once an instance is created, it will create an instance of the URLMonitor, which will announce any changes in status and set the isConnection property to true or false.

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    3.     <mx:Script>
    4.         <![CDATA[
    5.             import com.everythingflex.air.managers.ConnectionManager;
    6.             [Bindable]
    7.             private var cm:ConnectionManager = new ConnectionManager();
    8.         ]]>
    9.     </mx:Script>
    10.     <mx:Label text="Connection Status: {cm.isConnected}"
    11.         fontSize="20"
    12.         horizontalCenter="0"
    13.         verticalCenter="0"/>
    14. </mx:WindowedApplication>

    cm1002.png

    Pull you internet connection and you will see that an Alert shows and the status property that is bound to the label component updates.

    cm1001.png

    And here is the ConnectionManager class:

    1. package com.everythingflex.air.managers
    2. {
    3.     import air.net.URLMonitor;
    4.     import flash.events.StatusEvent;
    5.     import flash.net.URLRequest;
    6.     import mx.controls.Alert;
    7.    
    8.     public class ConnectionManager
    9.     {   
    10.         private var eventObj:StatusEvent;
    11.         private var urlMonitor:URLMonitor;
    12.         // if true, show the Alert window
    13.         private var showMessage:Boolean;
    14.         // message to display when connection fails and showMessage is true
    15.         private var message:String;
    16.        
    17.         // URL to test for a connection
    18.         [Bindable]
    19.         public var connectionURL:String;
    20.         [Bindable]
    21.         public var isConnected:Boolean = false;
    22.        
    23.         public function ConnectionManager(showMessage:Boolean=true,
    24.             connectionURL:String="http://www.google.com",
    25.             message:String="This application requires\nan Internet connection"):void{
    26.            
    27.             this.showMessage = showMessage;
    28.             this.connectionURL = connectionURL;
    29.             this.message = message;
    30.             startMonitor();
    31.         }
    32.        
    33.         // start the URLMonitor and test against the connectionURL
    34.         public function startMonitor():void{
    35.             var urlRequest:URLRequest = new URLRequest(connectionURL)
    36.             urlRequest.method = "HEAD";
    37.             urlMonitor = new URLMonitor(urlRequest);
    38.             urlMonitor.addEventListener(StatusEvent.STATUS, statusChanged);
    39.             urlMonitor.start();
    40.         }
    41.        
    42.         // handle changes in the connection status and dispatches StatusEvent
    43.         public function statusChanged(event:StatusEvent):void{
    44.             this.isConnected =  urlMonitor.available;
    45.             if(!this.isConnected && this.showMessage){
    46.                 Alert.show(this.message, "Connection Failure");
    47.             }
    48.             eventObj = new StatusEvent(StatusEvent.STATUS);
    49.             dispatchEvent(eventObj);
    50.         }   
    51.     }
    52. }

    AIR Update Manager

    October 1st, 2007

    UPDATED FOR AIR BETA 3

    AIR applications are out in the world with no connection back to home unless you actively code your application to check in from time to time to say hello is there a new version of me available? I have been working on an easy system for keeping AIR applications up to date and I have come up with an UpdateManager that simplifies this process.

    Here is how the UpdateManager works.

    Upon load of the application the UpdateManager examines the applicationDescriptor property of the NativeApplication.nativeApplication to determine the version of the installed application. This is then stored in the currentVersion property. The constructor accepts one required argument and one optional argument. The first required argument is the URL that holds the version.xml file to test. There is an example of the version.xml file below. The second is a Boolean telling the UpdateManager whether to automatically check for an update or wait until the user triggers the check. It defaults to true. If true, it will load in this XML file, parses it and compares the version property of the XML file with the version that was parsed from the applicationDescriptor. If there is a difference, and the forceUpdate property of the version.xml file is true, the application is automatically updated. If there is a difference and forceUpdate is false, the user is alerted of the available update, given a description of the update, and given the option to update their application The UpdateManager will then perform the update using the File and FileStream classes to download and write the new air file to disk and then the Updater class to complete the update.
    The UpdateManager also contains a checkForUpdate() method which will allow your application to provide a way for its user to manually trigger a check for an update. To use the UpdateManager, you will simply need to create an instance of the UpdateManager and pass in the URL of the version.xml file. You may also pass in the optional second argument.

    um1001.png

    There is also a method in the UpdateManager that will allow you to offer a way for your users to check for available updates anytime the application is running. This method will perform as stated previously if an update is available or will show a message that there are no updates available.

    um1002.png

    A sample WindowedApplication file:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    3.     <mx:Script>
    4.         <![CDATA[
    5.             import com.everythingflex.air.managers.UpdateManager;
    6.             private var um:UpdateManager = new UpdateManager("http://www.yourdomain.com/AIR/UMTest/version.xml",false);
    7.         ]]>
    8.     </mx:Script>
    9.     <mx:Button click="um.checkForUpdate()" label="Test for Update"
    10.         horizontalCenter="0" verticalCenter="0"/>
    11. </mx:WindowedApplication>

    Here is the version.xml file that needs to be on a server accessible by your AIR application. There are several properties that must be set. The currentVersion should be the same as the newest AIR package’s application.xml that you have set in the downloadLocation property. The forceUpdate property will automatically update the user without giving the user the option to say no. The message will be displayed to the user as Details: “message contents” within the Alert window. This is where you can show what new features are in the update.

    version.xml file

    1. <?xml version="1.0" encoding="ISO-8859-1"?>
    2. <currentVersion version=".2"
    3.                        downloadLocation="http://www.yourdomain.com/AIR/UMTest/UM.air"   
    4.                        forceUpdate="false"
    5.                        message="Added new features"/>

    The UpdateManager class

    1. package com.everythingflex.air.managers
    2. {
    3.     import flash.desktop.NativeApplication;
    4.     import flash.desktop.Updater;
    5.     import flash.events.Event;
    6.     import flash.filesystem.File;
    7.     import flash.filesystem.FileMode;
    8.     import flash.filesystem.FileStream;
    9.     import flash.net.URLRequest;
    10.     import flash.net.URLStream;
    11.     import flash.utils.ByteArray;
    12.    
    13.     import mx.controls.Alert;
    14.     import mx.events.CloseEvent;
    15.     import mx.rpc.events.FaultEvent;
    16.     import mx.rpc.events.ResultEvent;
    17.     import mx.rpc.http.HTTPService;
    18.    
    19.     public class UpdateManager
    20.     {
    21.         // URL of the remote version.xml file
    22.         private var versionURL:String;
    23.         // load in the applicationDescriptor
    24.         private var appXML:XML = NativeApplication.nativeApplication.applicationDescriptor;
    25.         private var ns : Namespace = appXML.namespace();
    26.         // set the currentVersion information
    27.         private var currentVersion:String = appXML.ns::version;
    28.         // holder for remote version.xml XML data
    29.         private var version:XML;
    30.         private var urlStream:URLStream = new URLStream();
    31.         private var fileData:ByteArray = new ByteArray();
    32.        
    33.        // the constructor requires the versionURL
    34.         public function UpdateManager(versionURL:String,autoCheck:Boolean=true):void{
    35.             this.versionURL = versionURL;
    36.             if(autoCheck)loadRemoteFile();
    37.         }
    38.            
    39.         // load the remote version.xml file
    40.         private function loadRemoteFile():void{
    41.             var http:HTTPService = new HTTPService();
    42.             http.url = this.versionURL;
    43.             http.useProxy=false;
    44.             http.method = "GET";
    45.             http.resultFormat="xml";
    46.             http.send();
    47.             http.addEventListener(ResultEvent.RESULT,testVersion);
    48.             http.addEventListener(FaultEvent.FAULT,versionLoadFailure);
    49.         }
    50.          
    51.         /*
    52.         test the currentVersion against the remote version file and either alert the user of
    53.         an update available or force the update, if no update available, alert user
    54.         */
    55.         public function checkForUpdate():Boolean{
    56.           if(version  ==  null){
    57.             this.loadRemoteFile();
    58.             return true;
    59.           }
    60.           if((currentVersion != version.@version) && version.@forceUpdate == true){
    61.               getUpdate();
    62.           }else if(currentVersion != version.@version){
    63.               Alert.show("There is an update available,\nwould you like to get it now? \n\nDetails:\n" + version.@message, "Choose Yes or No", 3, null, alertClickHandler);
    64.           }else{
    65.               Alert.show("There are no new updates available", "NOTICE");
    66.           }
    67.           return true;
    68.         }
    69.        
    70.         /*
    71.         test the currentVersion against the remote version file and either alert the user of
    72.         an update available or force the update
    73.         */
    74.         private function testVersion(event:ResultEvent):void{
    75.           version = XML(event.result);
    76.           if((currentVersion != version.@version) && version.@forceUpdate == true){
    77.               getUpdate();
    78.           }else if(currentVersion != version.@version){
    79.               Alert.show("There is an update available,\nwould you like to " +
    80.                          "get it now? \n\nDetails:\n" + version.@message,
    81.                          "Choose Yes or No", 3, null, alertClickHandler);
    82.           }
    83.         }
    84.        
    85.         /*
    86.         Load of the version.xml file failed
    87.         */
    88.         private function versionLoadFailure(event:FaultEvent):void{
    89.             Alert.show("Failed to load version.xml file from "+
    90.                         this.versionURL,"ERROR");
    91.         }
    92.        
    93.         // handle the Alert window decission
    94.         private function alertClickHandler(event:CloseEvent):void {
    95.             if (event.detail==Alert.YES){
    96.                 getUpdate();
    97.             }
    98.         }
    99.        
    100.         // get the new version from the remote server
    101.         private function getUpdate():void{
    102.             var urlReq:URLRequest = new URLRequest(version.@downloadLocation);
    103.             urlStream.addEventListener(Event.COMPLETE, loaded);
    104.             urlStream.load(urlReq);
    105.         }
    106.        
    107.         // read in the new AIR package
    108.         private function loaded(event:Event):void {
    109.             urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
    110.             writeAirFile();
    111.         }
    112.        
    113.         // write the newly downloaded AIR package to the application storage directory
    114.         private function writeAirFile():void {
    115.             var file:File = File.applicationStorageDirectory.resolvePath("Update.air");
    116.             var fileStream:FileStream = new FileStream();
    117.             fileStream.addEventListener(Event.CLOSE, fileClosed);
    118.             fileStream.openAsync(file, FileMode.WRITE);
    119.             fileStream.writeBytes(fileData, 0, fileData.length);
    120.             fileStream.close();
    121.         }
    122.        
    123.         // after the write is complete, call the update method on the Updater class
    124.         private function fileClosed(event:Event):void {
    125.             var updater:Updater = new Updater();
    126.           var airFile:File = File.applicationStorageDirectory.resolvePath("Update.air");
    127.           updater.update(airFile,version.@version);
    128.         }
    129.        
    130.     }
    131. }

    AIR, Flex, and Adobe Media Player

    October 1st, 2007

    AIR Beta 2, Flex 3 Beta 2, and the Adobe Media Player are all available for download at http://labs.adobe.com!

    adobe_air_225×50.jpg


    flex3_fx_225×50.jpg


    amp_225×50.jpg