Android Question Testing Internet Connection

Cableguy

Expert
Licensed User
Longtime User
Hi... huh... It's me ... huh... again... huh.. I guess...

I've been searching the forum for an easy, bulletproof way of testing if an internet connection is available or not...

Saw a post that based it on a request to a server in order to retrieve it's own IP... not a bad solution but I dont have and don't want to implement my own server just for this...
Saw another that based it on a ping request... but it would block the main thread as long as the ping request was running...
Back in the Very Old Days of windows mobile, we had within the WebBrowser lib, a method that would return true if a page was accessible, like google or b4ppc... can't remember the exact name of the method dough...
Found the snipet in B4ppc
So, being that, most of the Android world apps use internet, and that low-end and mid-en devices only have WI-FI capabilities, what is the best way to go to test if an internet connection is possible?
 
Last edited:

Cableguy

Expert
Licensed User
Longtime User
Thanks Mark,

I guess it can't get any simpler than that.
 
Upvote 0

Gary Milne

Active Member
Licensed User
Longtime User
I was not happy with the things I found in regards to this so I wrote my own which tests the device to see if it is possible given the current configuration. If it is possible than it actually tests by pulling down a page. I prefer to do both because of the latency in timing out when you don't have a connection which can be minimized.

B4X:
#Region Internet Connection
    Sub Test_Internet_Connection()

        Dim p As Phone
        Dim overall_data_state As Int
        Dim cellular_data_state As Int
      
        '0 Disabled - 1 Enabled. May also return a 3 in enabled state but I can find no explanation of the return values
        'Note: Turning on airplane mode is not the same as disabling wifi
        Dim wifi As Int = p.GetSettings ("wifi_on")
        'Msgbox("Wi-Fi value is: " & wifi, "")
      
        Dim airplane_mode As Int = p.GetSettings ("airplane_mode_on")
        'Msgbox("Airplane mode value is: " & airplane_mode, "")
      
        'Test the Cellular State
        Select Case p.GetDataState
            Case "CONNECTED"
                cellular_data_state = 1

            Case Else
                'Captures the other possible states of "SUSPENDED" "DISCONNECTED" "CONNECTING"
                cellular_data_state = 0
        End Select
      
      
        'Check to see if airplane_mode is enabled. 1 means device is in airplane_mode, 0 means device is not in airplane_mode
        If airplane_mode = 1 Then
            'We know for sure the internet is disconnected
            overall_data_state = 0
        Else
            'Otherwise we know that the device is not in airplane_mode so check wifi and cellular
            If wifi = 0 AND cellular_data_state = 0 Then
                'Both the cellular and WiFi are disabled so we cannot have a connection (except some kind of tethering over blue-tooth)
                overall_data_state = 0
            Else
                'Either Wifi or cellular is active so it is possible to have a connection
                overall_data_state = 1
            End If
        End If
              
            'Test the connection if it is possible to have one
            If overall_data_state = 1 Then
      
            'Initially indicate that we do have a connection and the screen label will probably be correct.
            'We do this because of the potential latency in determining when a connection is not available.
            Internet_Connected(True)
          
            'Now we will test the connection and change it back to False if it fails
            Dim job1 As HttpJob
            job1.Initialize("Job1", Me)

            'Send a GET request
            job1.Download("http://www.google.com")
          
            'Once this completes the JobDone routine is executed and the labels are set to their true state.
          
        Else
            Internet_Connected(False)
        End If
      

    End Sub

    Sub JobDone (job As HttpJob )
        If job.Success = True Then
            Internet_Connected(True)
        Else
            Internet_Connected(False)
        End If
        job.Release
    End Sub

    Sub Internet_Connected (Flag As Boolean)
        If Flag = True Then
            InternetConnected = True
            lblInternetConnected.Text = Chr(ConnectedIcon)
            lblInternetConnected.TextColor = Colors.White
        Else
            InternetConnected = False
            lblInternetConnected.text = Chr(DisconnectedIcon)
            lblInternetConnected.TextColor = Colors.Red
        End If
    End Sub
#End Region

Requires the httputils2 library.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
You seem to have covered all possibilities... nice work
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I was not happy with the things I found in regards to this so I wrote my own which tests the device to see if it is possible given the current configuration. If it is possible than it actually tests by pulling down a page. I prefer to do both because of the latency in timing out when you don't have a connection which can be minimized.

B4X:
#Region Internet Connection
    Sub Test_Internet_Connection()

        Dim p As Phone
        Dim overall_data_state As Int
        Dim cellular_data_state As Int
     
        '0 Disabled - 1 Enabled. May also return a 3 in enabled state but I can find no explanation of the return values
        'Note: Turning on airplane mode is not the same as disabling wifi
        Dim wifi As Int = p.GetSettings ("wifi_on")
        'Msgbox("Wi-Fi value is: " & wifi, "")
     
        Dim airplane_mode As Int = p.GetSettings ("airplane_mode_on")
        'Msgbox("Airplane mode value is: " & airplane_mode, "")
     
        'Test the Cellular State
        Select Case p.GetDataState
            Case "CONNECTED"
                cellular_data_state = 1

            Case Else
                'Captures the other possible states of "SUSPENDED" "DISCONNECTED" "CONNECTING"
                cellular_data_state = 0
        End Select
     
     
        'Check to see if airplane_mode is enabled. 1 means device is in airplane_mode, 0 means device is not in airplane_mode
        If airplane_mode = 1 Then
            'We know for sure the internet is disconnected
            overall_data_state = 0
        Else
            'Otherwise we know that the device is not in airplane_mode so check wifi and cellular
            If wifi = 0 AND cellular_data_state = 0 Then
                'Both the cellular and WiFi are disabled so we cannot have a connection (except some kind of tethering over blue-tooth)
                overall_data_state = 0
            Else
                'Either Wifi or cellular is active so it is possible to have a connection
                overall_data_state = 1
            End If
        End If
             
            'Test the connection if it is possible to have one
            If overall_data_state = 1 Then
     
            'Initially indicate that we do have a connection and the screen label will probably be correct.
            'We do this because of the potential latency in determining when a connection is not available.
            Internet_Connected(True)
         
            'Now we will test the connection and change it back to False if it fails
            Dim job1 As HttpJob
            job1.Initialize("Job1", Me)

            'Send a GET request
            job1.Download("http://www.google.com")
         
            'Once this completes the JobDone routine is executed and the labels are set to their true state.
         
        Else
            Internet_Connected(False)
        End If
     

    End Sub

    Sub JobDone (job As HttpJob )
        If job.Success = True Then
            Internet_Connected(True)
        Else
            Internet_Connected(False)
        End If
        job.Release
    End Sub

    Sub Internet_Connected (Flag As Boolean)
        If Flag = True Then
            InternetConnected = True
            lblInternetConnected.Text = Chr(ConnectedIcon)
            lblInternetConnected.TextColor = Colors.White
        Else
            InternetConnected = False
            lblInternetConnected.text = Chr(DisconnectedIcon)
            lblInternetConnected.TextColor = Colors.Red
        End If
    End Sub
#End Region

Requires the httputils2 library.
Just for information: with my french Internet/phone provider (Free), I have a very fast ping to its own servers or to the Google servers, even when I'm unable to connect to everything else. I discovered this lately. I was totally unable to connect to many web sites where I was, while Google servers and Free servers were very responsive. So doing a test to reach Google.com learns me nothing about the ability to reach another server.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Just for information: with my french Internet/phone provider (Free), I have a very fast ping to its own servers or to the Google servers, even when I'm unable to connect to everything else. I discovered this lately. I was totally unable to connect to many web sites where I was, while Google servers and Free servers were very responsive. So doing a test to reach Google.com learns me nothing about the ability to reach another server.
That's a known problem for most intense mobile users...here in France.
I have two mobile providers, orange and SFR... On diferent devices, side by side, I can have an almost flawless connection with orange, and not even be able to register the mobile network on SFR... I haven't tested free nor bouygues, but assuming the pub is true, most 4G network was implemented by bouygues, so AFAIK, free uses the bouygues network while orange and SFR use their own...
 
Upvote 0

susu

Well-Known Member
Licensed User
Longtime User
I just want to add one thing: You can not access Google in China because the government built a great Firewall to censor it. My option is trying to reach Alibaba or Aliexpress.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
As I see it, the best way to use this code is to catch the web server we are trying to use, targeting, if possible, a lightweight text only page... Maybe even do some parsing, like, if the webpage provides a timestamp... Comparing it to current timestamp...
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
That's a known problem for most intense mobile users...here in France.
I have two mobile providers, orange and SFR... On diferent devices, side by side, I can have an almost flawless connection with orange, and not even be able to register the mobile network on SFR... I haven't tested free nor bouygues, but assuming the pub is true, most 4G network was implemented by bouygues, so AFAIK, free uses the bouygues network while orange and SFR use their own...
Free cannot use the Bouygues network (it would have to pay for that). It pays already a lot of money for using the Orange network everywhere there's no Free antenna.
 
Upvote 0

TheMightySwe

Active Member
Licensed User
Longtime User
You can check if you have a DNS-server or not.

B4X:
Sub InternetStatus As Boolean
If HasFeature("android.hardware.wifi") = False AND HasFeature("android.hardware.telephony") = False Then Return False

    GetPropInfo
   
    If sGate = "" Then Return False
    If sD1 = "" AND sD2 = "" Then Return False

    Return True

End Sub

Sub HasFeature(Feature As String) As Boolean
  Dim r As Reflector
  r.Target = r.GetContext
  r.Target = r.RunMethod("getPackageManager")
  Return r.RunMethod2("hasSystemFeature", Feature, "java.lang.String")
End Sub

Sub GetPropInfo

    sWifi = "wlan0"
    sIP = ""
    sD1 = ""
    sD2 = ""

   Dim P As Phone
   Dim sb As StringBuilder
   Dim i As Int
   Dim PropData() As String

   sb.Initialize
   P.Shell("getprop", Null, sb, Null)
   PropData = Regex.Split(CRLF,sb.ToString)
  
   For i = 0 To PropData.Length - 1
      ' What is the Wifi Interface called?
      If PropData(i).Contains("[wifi.interface]") Then
         sWifi = PropData(i)
         sWifi = sWifi.Replace("[","")
         sWifi = sWifi.Replace("]","")
         sWifi = sWifi.SubString(sWifi.IndexOf(" ")).Trim
         Exit
      End If
   Next

   If sWifi.Length > 0 Then

      For i = 0 To PropData.Length - 1

         If PropData(i).Contains("[dhcp." & sWifi & ".ipaddress]") Then
            sIP = PropData(i)
            sIP = sIP.Replace("[","")
            sIP = sIP.Replace("]","")
            sIP = sIP.SubString(sIP.IndexOf(" ")).Trim
         End If
        
         If PropData(i).Contains("[dhcp." & sWifi & ".mask]") Then
            sMask = PropData(i)
            sMask = sMask.Replace("[","")
            sMask = sMask.Replace("]","")
            sMask = sMask.SubString(sMask.IndexOf(" ")).Trim
         End If
        
         If PropData(i).Contains("[dhcp." & sWifi & ".gateway]") Then
            sGate = PropData(i)
            sGate = sGate.Replace("[","")
            sGate = sGate.Replace("]","")
            sGate = sGate.SubString(sGate.IndexOf(" ")).Trim
         End If
        
         If PropData(i).Contains("[dhcp." & sWifi & ".dns1]") Then
            sD1 = PropData(i)
            sD1 = sD1.Replace("[","")
            sD1 = sD1.Replace("]","")
            sD1 = sD1.SubString(sD1.IndexOf(" ")).Trim
         End If
        
         If PropData(i).Contains("[dhcp." & sWifi & ".dns2]") Then
            sD2 = PropData(i)
            sD2 = sD2.Replace("[","")
            sD2 = sD2.Replace("]","")
            sD2 = sD2.SubString(sD2.IndexOf(" ")).Trim
         End If
        
         DoEvents

      Next

    Else

        For i = 0 To PropData.Length - 1
       
            If PropData(i).Contains("[net.rmnet0.gw]") Then
                sGate = PropData(i)
                sGate = sGate.Replace("[","")
                sGate = sGate.Replace("]","")
                sGate = sGate.SubString(sGate.IndexOf(" ")).Trim
            End If
       
          If PropData(i).Contains("[net.rmnet0.dns1]") Then
             sD1 = PropData(i)
             sD1 = sD1.Replace("[","")
             sD1 = sD1.Replace("]","")
             sD1 = sD1.SubString(sD1.IndexOf(" ")).Trim
          End If
         
          ' What is the Wifi Interface called?
         
          If PropData(i).Contains("[net.rmnet0.dns2]") Then
             sD2 = PropData(i)
             sD2 = sD2.Replace("[","")
             sD2 = sD2.Replace("]","")
             sD2 = sD2.SubString(sD2.IndexOf(" ")).Trim
          End If
       
        DoEvents
       
        Next

   End If
  
End Sub

I use this, and if someone see any problem with this I would love to know. It seems to work really good for me.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
You can check if you have a DNS-server or not.

B4X:
Sub InternetStatus As Boolean
If HasFeature("android.hardware.wifi") = False AND HasFeature("android.hardware.telephony") = False Then Return False

    GetPropInfo
  
    If sGate = "" Then Return False
    If sD1 = "" AND sD2 = "" Then Return False

    Return True

End Sub

Sub HasFeature(Feature As String) As Boolean
  Dim r As Reflector
  r.Target = r.GetContext
  r.Target = r.RunMethod("getPackageManager")
  Return r.RunMethod2("hasSystemFeature", Feature, "java.lang.String")
End Sub

Sub GetPropInfo

    sWifi = "wlan0"
    sIP = ""
    sD1 = ""
    sD2 = ""

   Dim P As Phone
   Dim sb As StringBuilder
   Dim i As Int
   Dim PropData() As String

   sb.Initialize
   P.Shell("getprop", Null, sb, Null)
   PropData = Regex.Split(CRLF,sb.ToString)
 
   For i = 0 To PropData.Length - 1
      ' What is the Wifi Interface called?
      If PropData(i).Contains("[wifi.interface]") Then
         sWifi = PropData(i)
         sWifi = sWifi.Replace("[","")
         sWifi = sWifi.Replace("]","")
         sWifi = sWifi.SubString(sWifi.IndexOf(" ")).Trim
         Exit
      End If
   Next

   If sWifi.Length > 0 Then

      For i = 0 To PropData.Length - 1

         If PropData(i).Contains("[dhcp." & sWifi & ".ipaddress]") Then
            sIP = PropData(i)
            sIP = sIP.Replace("[","")
            sIP = sIP.Replace("]","")
            sIP = sIP.SubString(sIP.IndexOf(" ")).Trim
         End If
       
         If PropData(i).Contains("[dhcp." & sWifi & ".mask]") Then
            sMask = PropData(i)
            sMask = sMask.Replace("[","")
            sMask = sMask.Replace("]","")
            sMask = sMask.SubString(sMask.IndexOf(" ")).Trim
         End If
       
         If PropData(i).Contains("[dhcp." & sWifi & ".gateway]") Then
            sGate = PropData(i)
            sGate = sGate.Replace("[","")
            sGate = sGate.Replace("]","")
            sGate = sGate.SubString(sGate.IndexOf(" ")).Trim
         End If
       
         If PropData(i).Contains("[dhcp." & sWifi & ".dns1]") Then
            sD1 = PropData(i)
            sD1 = sD1.Replace("[","")
            sD1 = sD1.Replace("]","")
            sD1 = sD1.SubString(sD1.IndexOf(" ")).Trim
         End If
       
         If PropData(i).Contains("[dhcp." & sWifi & ".dns2]") Then
            sD2 = PropData(i)
            sD2 = sD2.Replace("[","")
            sD2 = sD2.Replace("]","")
            sD2 = sD2.SubString(sD2.IndexOf(" ")).Trim
         End If
       
         DoEvents

      Next

    Else

        For i = 0 To PropData.Length - 1
      
            If PropData(i).Contains("[net.rmnet0.gw]") Then
                sGate = PropData(i)
                sGate = sGate.Replace("[","")
                sGate = sGate.Replace("]","")
                sGate = sGate.SubString(sGate.IndexOf(" ")).Trim
            End If
      
          If PropData(i).Contains("[net.rmnet0.dns1]") Then
             sD1 = PropData(i)
             sD1 = sD1.Replace("[","")
             sD1 = sD1.Replace("]","")
             sD1 = sD1.SubString(sD1.IndexOf(" ")).Trim
          End If
        
          ' What is the Wifi Interface called?
        
          If PropData(i).Contains("[net.rmnet0.dns2]") Then
             sD2 = PropData(i)
             sD2 = sD2.Replace("[","")
             sD2 = sD2.Replace("]","")
             sD2 = sD2.SubString(sD2.IndexOf(" ")).Trim
          End If
      
        DoEvents
      
        Next

   End If
 
End Sub

I use this, and if someone see any problem with this I would love to know. It seems to work really good for me.
If you can reach a DNS, a Google server or your provider servers, but not the web site or the data server that you need, then I don't know if "connected" means something.
 
Upvote 0

TheMightySwe

Active Member
Licensed User
Longtime User
If you can reach a DNS, a Google server or your provider servers, but not the web site or the data server that you need, then I don't know if "connected" means something.

You can see if a connection exists before trying to reach your prefered destination, it's no point trying if the basic connection isn't there is it?
 
Upvote 0

Mark Read

Well-Known Member
Licensed User
Longtime User
As Cableguy posted in #9, what about using a time server, for example "http:\\time.is/just", this just delivers a web page with the current time which is stored in the field "<div id="twd">"?

Would be quick to parse and check against the pc clock. Just a thought.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
Free cannot use the Bouygues network (it would have to pay for that). It pays already a lot of money for using the Orange network everywhere there's no Free antenna.
I was under the impression that they only had their own fiber-optic network.. Didn't know they had gsm network too.
 
Upvote 0

Gary Milne

Active Member
Licensed User
Longtime User
Just for information: with my french Internet/phone provider (Free), I have a very fast ping to its own servers or to the Google servers, even when I'm unable to connect to everything else. I discovered this lately. I was totally unable to connect to many web sites where I was, while Google servers and Free servers were very responsive. So doing a test to reach Google.com learns me nothing about the ability to reach another server.

I chose Google because I'm using Google Charts. You could of course choose any web-site, or change it to access multiple web sites if you wished to make it more fault tolerant.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
You can see if a connection exists before trying to reach your prefered destination, it's no point trying if the basic connection isn't there is it?
If you want to reach Toto.com, what's the usefulness of testing a DNS before? Try to connect to Toto.com first (or just ping it). What can prove there's a connection to your server better than joining this server? If you have problems to reach the DNS you chose because a guy with a backhoe damaged an optical fiber out of the building hosting these domain name servers, can you conclude there's no connection to Internet?
 
Upvote 0

TheMightySwe

Active Member
Licensed User
Longtime User
If you want to reach Toto.com, what's the usefulness of testing a DNS before? Try to connect to Toto.com first (or just ping it). What can prove there's a connection to your server better than joining this server? If you have problems to reach the DNS you chose because a guy with a backhoe damaged an optical fiber out of the building hosting these domain name servers, can you conclude there's no connection to Internet?

The usefullness is that you can see if the problem is in the unit, the router, the ISP or something else. If a WIFI-router has lost it's DNS or is frozen maybe a basic restart is the only thing you need to do and the problem is solved. Sometimes it's worse, and its som problem at the customers ISP, not often but it happens. Then the only thing you can do is wait until they fix the problem. Or maybe it's our ISP that has some problem, or the GSM network is overloaded because there a shitload of people at the same place.

Or it can be a inhouse problem, like our servers can be frozen. It has not happend yet. *Knock on wood*

When a customers calls with a problem you want to rule out some simple stuff before you travel 100 km to fix something that is that basic.

For an application that is used as entertainment maybe its not that important to see where the problem is, but in business applications it's a bit more important to get the shit to work ASAP. And these small tests are important to rule out the basic most common network problems and saves tons of time and travel.

If you try to reach a thirdparty server, then maybe it's not that important. If the connection between your customer and you is broken in some way, you need to fix the problem ASAP. And a simple Connection Check, DNS Check and PING can tell you where in the chain the problem is. On the customers side, ISP or your own side.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
The usefullness is that you can see if the problem is in the unit, the router, the ISP or something else.

The question is not : how can I fix a network issue and diagnose what's going wrong? But: am I connected? And what I see in many forums is always the same answer: "try to connect to this server or this one", etc. But no one seems to realize that professionals like Microsoft, Google or Facebook NEVER do that in their own app. There's maybe a reason. Did you ever see your Chrome or IE browser trying to check whether there's an internet connection or not? You will get an error only when you enter an URL that is not accessible. And even in this case, your browser won't check whether it can join another URL. There's maybe a reason.
Let's see the three main scenarios in the Android world:
- My app needs to connect to a specific server;
- My app uses services or APIs that connect to a specific server but I don't know it;
- My app has to connect to an undefined number of servers and none is known in advance.
I discard the third case because it's the typical case of an Internet browser and I don't think that someone here is trying to make one. So either your app tries to connect to a specific server that you know and the only way to answer to the question "am I connected?" is to attempt to connect to this server, or your app makes a connection through an API (e.g. Google Maps, Google Play Game Services) and you have no idea of the server to test. Fortunately, in this case, the connection check is done by the functions that you call and you should get an error or an exception if the connection is not possible (typically that will be a "Network failure" with Google APIs).
So, what's the usefulness to check "google.com", a DNS or any other server? To inform the user? In this case, why Google or Microsoft do not do it?
Let's suppose that we are unable to join our server, so the app cannot be used and we want to do something to fix the issue. As a professional server manager, you don't need that a customer calls you to know whether your server is down or the WAN has troubles. You have tools to monitor that. On the client side, what information is useful for the user? According to Google, almost none. Open Chrome under Android, or the Google Play Store. If you have no connection to the Google servers, you will have a terse message like "Unable to connect, please retry". What can do the user? Turn the wifi on if he forgot. Move to another place if the signal strength is too weak. In these two cases, you can check all that on an Android device without connecting to anything. Checking that you can reach another server, that is not used by you app, is of no use for the final user. Are you going to show that in your app: "hey, you cannot download the data you need but you can reach youporn.com. Good news, isn't it?" ?
In your answer, you say that helps you to understand what's going wrong. So it's an information for you, but how do you get it ? As a professional server manager, I don't test anything on the user side because I don't need these informations. The first thing that I do is a "traceroute" or a "mtr" to the final user and to the server. If I can reach the server, I reissue the same commands to the user from the server. He disconnected his Internet box? I can see that easily from the other side. He has no WAN in his area? I can see that too. And when the problem is due to the server, which is down, or to the WAN, or to the Internet provider, then Google is right: the only relevant message to display to the user is "please retry later".
In brief, I really don't understand why everybody needs to know if they are connected to google.com or any server that is of no use to their app.
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
In brief, I really don't understand why everybody needs to know if they are connected to google.com or any server that is of no use to their app.
We don't want to know if we are connected to google or not, all we want to know is if a connection is at all possible.
Why? To save time to the user...
My scenario is, I will try to tap into a browser game...
This game in particular has a login page that can be accessed either by the root web address or by "/login.php". So before I try to connect to the server and wait for a timeout error or an impossible to parse page, I would prefer to be sure that a connection is possible, hardware wise, so that the info can be downloaded in the minor amount of time possible.
 
Upvote 0
Top