Android Question Check Internet Access

barx

Well-Known Member
Licensed User
Longtime User
I have looked through the relevant threads on the forum regarding checking connections. I have decided that the most reliable way will be to actually load a site (Like Erel has mentioned in a couple of threads, loading Google). To keep speed up and bandwidth down I have created a simple page on the Site that my app interacts that simply states 'OK'.

I'm trying to think how best to create a 'CanConnect' sub.

So Far I have

B4X:
Sub CanConnect() As Boolean
    Dim HttpAction As HttpJob
    HttpAction.Initialize("CheckConnection", Me)
    HttpAction.Download(Shared.GetSetting("h") & "/test/con.php")
   
End Sub

but then obviously the returned data gets dealt with in the JobDone event and so no way to test that and return true / false.....

What am I missing and how can I make this work?

cheers
 

dealsmonkey

Active Member
Licensed User
Longtime User
Here is what I do to check my apps for Internet connection.

I have a c# api server that has many api calls I use in my various apps. One of these calls just returns a value that you send to it via a http get request. I then just check the return value in Job Done Sub and if it is the value I sent, all is good, else not connected :)

The code is below. Everyone is welcome to use this call, the server has a 99.9% uptime :)

B4X:
Sub Globals
    Dim Job1 as HttpJob
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Initialise the HttpJob to Check the server.
    Job1.Initialize("Job1",Me)     
    'Do the Http Request.
    Job1.Download2("http://api.exg.me/api/Jobs",Array As String("passkey","10897"))
End Sub

Sub JobDone (Job As HttpJob)
    Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
        If Job.Success = True Then       
            Select Job.JobName
                Case "Job1"           
                    If Job.GetString.Contains("10897") Then   
                         'Correct Value From Server, We are Connected.
                    Else
                         'Something Else returned, We are not Connected.
                    End If           
            End Select   
       
        Else
                      'Success not returned by server, could be server problem or Conenction Problem.                   
        End If
       
End Sub
 
Upvote 0

JOTHA

Well-Known Member
Licensed User
Longtime User
Hi dealsmonkey,
Everyone is welcome to use this call, the server has a 99.9% uptime :)
thank you very much, it works!
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I have looked through the relevant threads on the forum regarding checking connections. I have decided that the most reliable way will be to actually load a site (Like Erel has mentioned in a couple of threads, loading Google). To keep speed up and bandwidth down I have created a simple page on the Site that my app interacts that simply states 'OK'.

I'm trying to think how best to create a 'CanConnect' sub.

So Far I have

B4X:
Sub CanConnect() As Boolean
    Dim HttpAction As HttpJob
    HttpAction.Initialize("CheckConnection", Me)
    HttpAction.Download(Shared.GetSetting("h") & "/test/con.php")
  
End Sub

but then obviously the returned data gets dealt with in the JobDone event and so no way to test that and return true / false.....

What am I missing and how can I make this work?

cheers
In my Google Play Services library, I test the connection with that simple code:
B4X:
/** Returns whether the currently active default data network is connected. */
public boolean IsConnected()
{
        NetworkInfo ni = _CM.getActiveNetworkInfo();
        if (ni == null)
            return false;
        else
            return ni.isConnected();
}
I tried to stop the wifi source (without touching anything on the device) and the loss of connection was detected, same result when I lose the signal with a mobile connection, so I don't really need more. But it's maybe not enough for your needs.
 
Upvote 0

ggpanta

Member
Licensed User
Longtime User
I think a more "proper" way is to just ask the OS to provide that info, android provides an intent exactly for this reason
<actionandroid:name="android.net.conn.CONNECTIVITY_CHANGE"/>

I believe it is better to get the internet connectivity status (including type of connection etc) from the event since there are many reasons where an http request would fail (dns, port blocking, IDS block due to numerous connections etc).


I use BroadcastReceiver to register as receiver and monitor network connection (using this method you can know when the connection is down since it fires a broadcast event).

Example follows

1st we register our receiver and set the intent filter we want to use

B4X:
Sub Activity_Create(FirstTime As Boolean)
  
    Broadcast.Initialize("BroadcastReceiver")
  
    Broadcast.addAction("android.net.conn.CONNECTIVITY_CHANGE")
    Broadcast.SetPriority(2147483647)
    Broadcast.registerReceiver("")
  
    Dim debugLbl As Label

    Activity.Initialize("Main")
    debugLbl.Initialize("")
  
    Activity.AddView(debugLbl,0,0,100%x, 100%y)
End Sub

2nd we just listen for the event and do whatever we need there

B4X:
Sub BroadcastReceiver_OnReceive (Action As String, i As Object)
   Dim retIn As Intent
   Dim tmpLbl As Label
   retIn = i
 
   tmpLbl =  Activity.GetView(0)
   tmpLbl.Text = retIn.ExtrasToString
 
   Broadcast.AbortBroadcast
End Sub

I hope this helps :)
 
Upvote 0

inakigarm

Well-Known Member
Licensed User
Longtime User
Well, thinking quickly I like best Informatix or ggpanta, but doesn't cover one situation: when your'e connected to the mobile or wifi network (ex: AP or repeater) but you don't have Internet Access (and/or to your server)

If I'd want to check Internet access, I'd try to ping an Public Server,-ex: Google DNS-(using httpputils2 seems like "killing flies with canons" - like we say in Spain) but the problem is that Ping (using ph.Shell) use the Main Thread ...

For all these arguments, first option will be find if it's possible to implement Ping on a separate Thread and second use httputils2 solution
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
I think a more "proper" way is to just ask the OS to provide that info, android provides an intent exactly for this reason
<actionandroid:name="android.net.conn.CONNECTIVITY_CHANGE"/>

I believe it is better to get the internet connectivity status (including type of connection etc) from the event since there are many reasons where an http request would fail (dns, port blocking, IDS block due to numerous connections etc).


I use BroadcastReceiver to register as receiver and monitor network connection (using this method you can know when the connection is down since it fires a broadcast event).

Example follows

1st we register our receiver and set the intent filter we want to use

B4X:
Sub Activity_Create(FirstTime As Boolean)
 
    Broadcast.Initialize("BroadcastReceiver")
 
    Broadcast.addAction("android.net.conn.CONNECTIVITY_CHANGE")
    Broadcast.SetPriority(2147483647)
    Broadcast.registerReceiver("")
 
    Dim debugLbl As Label

    Activity.Initialize("Main")
    debugLbl.Initialize("")
 
    Activity.AddView(debugLbl,0,0,100%x, 100%y)
End Sub

2nd we just listen for the event and do whatever we need there

B4X:
Sub BroadcastReceiver_OnReceive (Action As String, i As Object)
   Dim retIn As Intent
   Dim tmpLbl As Label
   retIn = i

   tmpLbl =  Activity.GetView(0)
   tmpLbl.Text = retIn.ExtrasToString

   Broadcast.AbortBroadcast
End Sub

I hope this helps :)
I added this also to my Google Play Services lib but in a much simpler way.
Here's the Java code:
B4X:
    /**
     *Sets an event to be notified of connectivy changes.
     *The event will return the type of network (one of the NETWORK constants) affected by the change and whether this network is connected or not.
     */
    public static void SetConnectivityEvent(BA ba, String EventName)
    {
        _CNR = new ConnectivityChangeReceiver(ba, EventName);
        ba.context.registerReceiver(_CNR, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
    }

    private static class ConnectivityChangeReceiver extends BroadcastReceiver
    {
        private BA _ba;
        private String _evtName;

        public ConnectivityChangeReceiver(BA ba, String EventName)
        {
            _ba = ba;
            _evtName = EventName.toLowerCase(BA.cul);
        }

        @Override
        public void onReceive(Context context, Intent intent)
        {
            Bundle extras = intent.getExtras();
            NetworkInfo ni = (NetworkInfo) extras.get(ConnectivityManager.EXTRA_NETWORK_INFO);
            _ba.raiseEvent2(this, true, _evtName, false, new Object[] { ni.getType(), ni.isConnected() });
        }
    }
In B4A, there's nothing to add to the manifest. When connected, the user just calls:
NI.SetConnectivityEvent("NI_onConnectivityChange")
and gets the event with:
Sub NI_onConnectivityChange(NetworkType As Int, IsConnected As Boolean)

I will publish probably tomorrow my lib with the complete source code.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Well, thinking quickly I like best Informatix or ggpanta, but doesn't cover one situation: when your'e connected to the mobile or wifi network (ex: AP or repeater) but you don't have Internet Access (and/or to your server)
There are also cases where you want to be sure of the connection quality and speed; that's why my Unix servers check the connection to a machine dedicated to this (to ensure a keep-alive connection) but depending on what you want to do, checking the connectivity is enough.
 
Upvote 0

ggpanta

Member
Licensed User
Longtime User
Well, thinking quickly I like best Informatix or ggpanta, but doesn't cover one situation: when your'e connected to the mobile or wifi network (ex: AP or repeater) but you don't have Internet Access (and/or to your server)

If I'd want to check Internet access, I'd try to ping an Public Server,-ex: Google DNS-(using httpputils2 seems like "killing flies with canons" - like we say in Spain) but the problem is that Ping (using ph.Shell) use the Main Thread ...

For all these arguments, first option will be find if it's possible to implement Ping on a separate Thread and second use httputils2 solution


The intent will report internet access not just connectivity, google does this using an internal ping on its own service (not an icmp ping, its a hello message(tcp)) so in the reply you get in the extras you get, type of connection, connection status and internet status, quality(its a latency thing between the phone and google services) etc.

Run the example and check out the messages :)
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
The intent will report internet access not just connectivity, google does this using an internal ping on its own service (not an icmp ping, its a hello message(tcp)) so in the reply you get in the extras you get, type of connection, connection status and internet status, quality(its a latency thing between the phone and google services) etc.

Run the example and check out the messages :)
EDIT: You can check this with two devices: one serves as a wifi hotspot for the second. If you stop the hotspot, this is detected by the second device. But if you stop the data connection of the hotspot, that goes unnoticed by the second device, so I'm not sure they do a ping or anything else to a server. Anyway, that does not ensure that you have a good and usable connection to the server that you want to reach. Only a test to that server will give you a valid answer.
 
Last edited:
Upvote 0

ggpanta

Member
Licensed User
Longtime User
EDIT: You can check this with two devices: one serves as a wifi hotspot for the second. If you stop the hotspot, this is detected by the second device. But if you stop the data connection of the hotspot, that goes unnoticed by the second device, so I'm not sure they do a ping or anything else to a server. Anyway, that does not ensure that you have a good and usable connection to the server that you want to reach. Only a test to that server will give you a valid answer.

The msg is send in a lazy way so in some cases it will not detect the internet connection issue, thats true ofc and you need to check your server as Informatix says for various other reasons (its even cheaper if you actually need to do a call to the server anyway (ie access an API or something))

As always defensive coding while accessing remote services is the best option, make sure your app will survive timeouts and no net access for the best user experience :)
 
Upvote 0
Top