1

I have an adobe air application working on both IOS and Android. I have searched all over the internet to see how can i check whether the device is connected to a working connection or not. The most logical way was the following :
Create a ConnectionChecker class with the following content :

package
{
    import flash.events.*;
    import flash.net.*;

    [Event(name="error", type="flash.events.Event")]
    [Event(name="success", type="flash.events.Event")]
    public class ConnectionChecker extends EventDispatcher
    {
        public static const EVENT_SUCCESS:String = "success";
        public static const EVENT_ERROR:String = "error";

        // Though google.com might be an idea, it is generally a better practice
        // to use a url with known content, such as http://foo.com/bar/mytext.txt
        // By doing so, known content can also be verified.

        // This would make the checking more reliable as the wireless hotspot sign-in
        // page would negatively intefere the result.
        private var _urlToCheck:String = "http://www.google.com";


        // empty string so it would always be postive
        private var _contentToCheck:String = "";    

        public function ConnectionChecker()
        {
            super();
        }

        public function check():void
        {
            var urlRequest:URLRequest = new URLRequest(_urlToCheck);
            var loader:URLLoader = new URLLoader();
            loader.dataFormat = URLLoaderDataFormat.TEXT;

            loader.addEventListener(Event.COMPLETE, loader_complete);
            loader.addEventListener(IOErrorEvent.IO_ERROR, loader_error);

            try
            {
                loader.load(urlRequest);
            }
            catch ( e:Error )
            {
                dispatchErrorEvent();
            }
        }

        private function loader_complete(event:Event):void
        {
            var loader:URLLoader = URLLoader( event.target );
            var textReceived:String = loader.data as String;

            if ( textReceived )
            {
                if ( textReceived.indexOf( _contentToCheck ) )
                {
                    dispatchSuccessEvent();
                }
                else
                {
                    dispatchErrorEvent();
                }
            }
            else
            {
                dispatchErrorEvent();
            }
        }

        private function loader_error(event:IOErrorEvent):void
        {
            dispatchErrorEvent();
        }


        private function dispatchSuccessEvent():void
        {
            dispatchEvent( new Event( EVENT_SUCCESS ) );
        }

        private function dispatchErrorEvent():void
        {
            dispatchEvent( new Event( EVENT_ERROR ) );
        }
    }
}

Afterwards, whenever i need to actually test the presence of a working connection, i'd do the following :

                    var checker:ConnectionChecker = new ConnectionChecker();
                    checker.addEventListener(ConnectionChecker.EVENT_SUCCESS, checker_success);
                    checker.addEventListener(ConnectionChecker.EVENT_ERROR, checker_error);
                    checker.check();

And the appropriate functions are :

private function checker_success(event:Event):void
{
    trace("U have cnx");
    continueTheGame.visible = true;
    // There is internet connection
}

private function checker_error(event:Event):void
{
    trace("U dn't have cnx");
    continueTheGame.visible = false;
    // There is no internet connection
}

All the above answer is based on this link i found on SO https://stackoverflow.com/a/13569775/5128351

Now the problem is, no matter whether i have connection or no, i will always get the result that no connection available. Am i missing something??

EDIT:

I tried to add the following to the xml file, but i'm still getting the same result :

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>google.com</key>
        <dict>
            <!--Include to allow subdomains-->
            <key>NSIncludesSubdomains</key>
            <true/>
            <!--Include to allow HTTP requests-->
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <!--Include to specify minimum TLS version-->
            <key>NSTemporaryExceptionMinimumTLSVersion</key>
            <string>TLSv1.1</string>
        </dict>
    </dict>
</dict>
Community
  • 1
  • 1
Elias Rahme
  • 2,226
  • 3
  • 28
  • 53

3 Answers3

1

Regarding _contentToCheck String :

// empty string so it would always be positive
private var _contentToCheck:String = "";

I would suggest you check for actual "target" text within that loaded HTML source. This way, if it exists, you can be sure at least Google was loaded O.K (device has connection).

// check string of HTML to confirm web load was successful
private var _contentToCheck:String = "<!doctype html>"; //beginning of Google's HTML text


Regarding Check() function

What happens if you use logic like below in your loader_complete event...?

private function loader_complete(event:Event):void
{
    var loader:URLLoader = URLLoader( event.target );
    var textReceived:String = loader.data as String;

    if ( textReceived.length > 0 )
    {
        //index will be -1 if search text is not found (use IS NOT EQUAL to check this)
        if ( textReceived.indexOf( _contentToCheck ) != -1 )
        {
            dispatchSuccessEvent();
        }
        else
        {
            dispatchErrorEvent();
        }
    }
    else
    {
        dispatchErrorEvent();
    }
}

Code is not compiler tested but the logic should be good for your own test. Hope it helps.


EDIT with code sample:

Below is the two codes I tested (which correctly detects On/Off internet connection).
Re-enable those traces in function loader_complete to double-check anything.

(1) FLA is linked to this Connect_test_01.as (is main AS class)

package  
{
    import flash.display.MovieClip;
    import flash.events.*;

    import ConnectionChecker; 

    public class Connect_test_01 extends MovieClip 
    {
        public var checker:ConnectionChecker;

        public function Connect_test_01() 
        {
            checker = new ConnectionChecker();
            checker.addEventListener(ConnectionChecker.EVENT_SUCCESS, checker_success);
            checker.addEventListener(ConnectionChecker.EVENT_ERROR, checker_error);
            checker.check();
        }

        private function checker_success(event:Event):void
        {
            //# There is internet connection
            trace("-- YES - Net found.. You are connected");
            //continueTheGame.visible = true;
        }

        private function checker_error(event:Event):void
        {
            //# There is no internet connection
            trace("-- NO - Net not found... No connection");
            //continueTheGame.visible = false;
        }


    } //end Class

} //end Package

(2) This is the ConnectionChecker.as used in above code's imports.

package
{
    import flash.events.*;
    import flash.net.*;

    [Event(name="error", type="flash.events.Event")]
    [Event(name="success", type="flash.events.Event")]
    public class ConnectionChecker extends EventDispatcher
    {

        public var urlRequest:URLRequest;
        public var loaderA:URLLoader;
        public var loaderB:URLLoader;

        public var textReceived:String;

        public static const EVENT_SUCCESS:String = "success";
        public static const EVENT_ERROR:String = "error";

        // URL to connect for testing
        private var _urlToCheck:String = "https://www.google.com";

        // check string within HTML content to confirm web load was successful
        private var _contentToCheck:String = "<!doctype html>"; //beginning of Google's HTML text 

        public function ConnectionChecker()
        { super(); }

        public function check():void
        {
            urlRequest = new URLRequest(_urlToCheck);
            loaderA = new URLLoader();
            loaderA.dataFormat = URLLoaderDataFormat.TEXT;

            loaderA.addEventListener(Event.COMPLETE, loader_complete);
            loaderA.addEventListener(IOErrorEvent.IO_ERROR, loader_error);

            try { loaderA.load(urlRequest); }
            catch ( e:Error ) { dispatchErrorEvent(); }
        }

        private function loader_complete(event:Event):void
        {
            loaderB = URLLoader( event.target );
            textReceived = String(loaderB.data); // as String;

            //# check contents of load (should be HTML source-code)
            //trace ("STRING CHECK : " + "\n" + textReceived + "\n");

            //# minus-1 means Not Found. Should be Zero since Search Text is beginning
            //trace("Index of String : " + textReceived.indexOf( _contentToCheck ) + "\n" );

            if ( textReceived.length > 0 )
            {
                //index will be -1 if search text is not found (use IS NOT EQUAL to check this)
                if ( textReceived.indexOf( _contentToCheck ) != -1 )
                { dispatchSuccessEvent(); }
                else { dispatchErrorEvent(); }
            }
            else
            { dispatchErrorEvent(); }
        }

        private function loader_error(event:IOErrorEvent):void
        { dispatchErrorEvent(); }


        private function dispatchSuccessEvent():void
        { dispatchEvent( new Event( EVENT_SUCCESS ) ); }

        private function dispatchErrorEvent():void
        { dispatchEvent( new Event( EVENT_ERROR ) ); }
    }
}
VC.One
  • 14,790
  • 4
  • 25
  • 57
  • i will check it in a couple of hours and get back to you, ur answer makes sense ! – Elias Rahme Oct 06 '16 at 06:59
  • Still the same thing, i am constantly getting no connection , what do you suggest @VC.One – Elias Rahme Oct 06 '16 at 14:59
  • The code works for me. I've added a code sample of what I've tried. Just re-shuffled some things (eg: made vars as public to all functions instead of just declaring them within a specific function where they exist only for that function)... – VC.One Oct 09 '16 at 12:37
  • Your code works like a charm on android !!! and i do need that ! but on iOS it doesn't !! what could be doing such a behavior ??! – Elias Rahme Oct 12 '16 at 11:39
  • Sorry I don't know about iOS issue. Maybe try loading from HTTPS. iOS might not allow input loaded from a _non-secure_ URL... Try check with : `https://www.google.com`... – VC.One Oct 12 '16 at 19:35
0

Adobe created a URLMonitor class to handle this.

http://help.adobe.com/en_US/air/reference/html/air/net/URLMonitor.html

http://www.infin8design.com/clients/stack/air.zip

crooksy88
  • 3,849
  • 1
  • 24
  • 30
  • 1
    AIR only?? Amazing. Doesn't that class achieve same thing as Asker's AS3 code, anyway? eg: `checkStatus()` _"Attempts to load content from a URL in the background, to check for a returned HTTP status code."_ - Asker's problem is trying to validate by checking an empty string == does not work!! If his check function returned a number (ie: `200` or `404`) he will have recreated that URLMonitor. His shown code also works in browser or other non-AIR situations. – VC.One Oct 05 '16 at 21:17
0

Have you added the now required NSTransportSecurity XML to your iOS app descriptor? You need to specify all domains that you intend to communicate with.

This goes inside the iPhone node.

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>google.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>

    <key>another domain.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>
  </dict>

crooksy88
  • 3,849
  • 1
  • 24
  • 30
  • you mean i should add this to my app.xml file? – Elias Rahme Oct 18 '16 at 06:30
  • i am using flash CS6 , i've seen this format while using XCode, but is it the same for flash? where should i add it – Elias Rahme Oct 18 '16 at 06:32
  • i tried it, flash stated that there is an error in xml file, so i tried the edit above, and still the same thing, could you please advise – Elias Rahme Oct 18 '16 at 07:18
  • Yes you should add the xml to your app-descriptor.xml file, inside the iPhone node. For some reason the word iPhone was stripped out of my comment above? – crooksy88 Oct 18 '16 at 15:46