Best method for detecting an internet connection

The way I’m detecting an internet connection now is like this:

 local http = require("socket.http")  
 local ltn12 = require("ltn12")  
 local network = false  
 local r,e= http.request( "http://www.microsoft.com" )  
 if(r) then  
 network = true  
 end  

I used microsoft.com because they have the best uptime of anyone I could think of on short notice, and they wouldn’t be blocked in any countries (as far as i know…).

But of course making an entire get request to someone else’s domain and then reading the whole http response (60kb in this case) seems like a pretty hacky solution.

I see that the network api has the following method: network.setStatusListener(), but this does not seem suitable because I want to know if the user has a connection in the first place (Not if their connection status changes in the future).

Anyone have a better way? [import]uid: 135827 topic_id: 33471 reply_id: 333471[/import]

Hi George,
You’re basically on the right track. Testing for connectivity to a proven site is actually not a “bad” method, at least not that I’ve ever seen.

I do it slightly differently, as follows:

local function connectStatus( event ) --network status listener  
 --print( "address", event.address )  
 --print( "isReachable", event.isReachable )  
 --print( "IsReachableViaCellular", event.isReachableViaCellular )  
 --print( "IsReachableViaWiFi", event.isReachableViaWiFi )  
 if ( event.isReachable == true and event.isReachableViaWiFi == true ) then  
 network.setStatusListener( "www.microsoft.com", nil ) -- turn off the listener!  
 --do something! (call a function, whatever)  
 end  
end  
  
if ( network.canDetectNetworkStatusChanges ) then  
 network.setStatusListener( "www.microsoft.com", connectStatus )  
end  

There might be a better way, but this is my method and it seems to work without any issues on test devices.

Brent [import]uid: 200026 topic_id: 33471 reply_id: 133037[/import]

Hi George,
You’re basically on the right track. Testing for connectivity to a proven site is actually not a “bad” method, at least not that I’ve ever seen.

I do it slightly differently, as follows:

local function connectStatus( event ) --network status listener  
 --print( "address", event.address )  
 --print( "isReachable", event.isReachable )  
 --print( "IsReachableViaCellular", event.isReachableViaCellular )  
 --print( "IsReachableViaWiFi", event.isReachableViaWiFi )  
 if ( event.isReachable == true and event.isReachableViaWiFi == true ) then  
 network.setStatusListener( "www.microsoft.com", nil ) -- turn off the listener!  
 --do something! (call a function, whatever)  
 end  
end  
  
if ( network.canDetectNetworkStatusChanges ) then  
 network.setStatusListener( "www.microsoft.com", connectStatus )  
end  

There might be a better way, but this is my method and it seems to work without any issues on test devices.

Brent [import]uid: 200026 topic_id: 33471 reply_id: 133037[/import]

Hey, Brent, I’m wondering why in line 6 you have and in it:

-- copied from the line 6 of Brent's code above:  
if ( event.isReachable == true and event.isReachableViaWiFi == true ) then  

When I’m testing if a device can connect to internet, I’d imagine checking event.isReachable might be enough? No? If not, why?

Naomi
[import]uid: 67217 topic_id: 33471 reply_id: 139199[/import]

Hi Naomi,
You’re absolutely right… I pasted this code from one of my apps that I use “internally” as a level editor on the iPad, and I need it to transmit some files via WiFi (it’s not a 4G-enabled iPad). So, I put that in there as an additional check. No reason you should have to include it… and probably no reason I need to include it either, but it works and I kept it there. :slight_smile:

Brent [import]uid: 200026 topic_id: 33471 reply_id: 139214[/import]

Thank you, Brent. I appreciate you getting back to me. I’m thinking, for tiny text data upload/download (which is the case with my app), it shouldn’t be necessary to check if WiFi is enabled. After all, mobile phone users tend not to worry about how many text messages they send & receive. (Edit: but may be some mobile plans tightly limit the usage, and maybe checking WiFi is important to some… dunno if I should make it so that my app won’t talk to the server unless WiFi is working…)

BTW, I wonder what’s the true need for detecting network status changes using network.canDetectNetworkStatusChanges API. Whenever my app needs the internet connectivity, I feel checking the event.isReachable would be good enough. No? I wonder if I’m overlooking something important. Any thoughts?

Thanks again.

Naomi [import]uid: 67217 topic_id: 33471 reply_id: 139226[/import]

Hi Naomi,
This is a tough call. I think you should “ignore” WiFi-only. If anybody is on a limited, strict phone data plan, they probably shouldn’t be playing data-intensive games. :slight_smile: But, it’s up to you. If you restrict it to WiFi only, you’re going to alienate a lot of users with phone data plans.

As for “network.canDetectNetworkStatusChanges”, I just followed the code example, and added it as a sort of “pre-check” on whether the device should start a network listener on the selected host. If it can’t, I just take a different direction (report to the user)… but then, “event.isReachable” should do a similar check and fail if it can’t connect to the host.
http://docs.coronalabs.com/api/library/network/canDetectNetworkStatusChanges.html

Best of luck!
Brent [import]uid: 200026 topic_id: 33471 reply_id: 139288[/import]

Thanks, Brent. I think I’ll simply go with checking the connectivity. It makes most sense for my app. Perhaps canDetectNetworkStatusChanges is useful for some apps that require constant and/or extended period of connection to internet, but for my game app that doesn’t need to talk to server(s) or website(s) constantly or require heavy-duty (and therefore quite lengthy) connection, I see no need to monitor the status changes.

Thanks again for giving this some more thoughts.

Naomi

Edit: Just confirmed that canDetectNetworkStatusChanges is for constantly monitoring the network connectivity. So, in my case, the best way to go appears to be checking the socket connection after all. [import]uid: 67217 topic_id: 33471 reply_id: 139290[/import]

Hey, Brent, I’m wondering why in line 6 you have and in it:

-- copied from the line 6 of Brent's code above:  
if ( event.isReachable == true and event.isReachableViaWiFi == true ) then  

When I’m testing if a device can connect to internet, I’d imagine checking event.isReachable might be enough? No? If not, why?

Naomi
[import]uid: 67217 topic_id: 33471 reply_id: 139199[/import]

Hi Naomi,
You’re absolutely right… I pasted this code from one of my apps that I use “internally” as a level editor on the iPad, and I need it to transmit some files via WiFi (it’s not a 4G-enabled iPad). So, I put that in there as an additional check. No reason you should have to include it… and probably no reason I need to include it either, but it works and I kept it there. :slight_smile:

Brent [import]uid: 200026 topic_id: 33471 reply_id: 139214[/import]

Thank you, Brent. I appreciate you getting back to me. I’m thinking, for tiny text data upload/download (which is the case with my app), it shouldn’t be necessary to check if WiFi is enabled. After all, mobile phone users tend not to worry about how many text messages they send & receive. (Edit: but may be some mobile plans tightly limit the usage, and maybe checking WiFi is important to some… dunno if I should make it so that my app won’t talk to the server unless WiFi is working…)

BTW, I wonder what’s the true need for detecting network status changes using network.canDetectNetworkStatusChanges API. Whenever my app needs the internet connectivity, I feel checking the event.isReachable would be good enough. No? I wonder if I’m overlooking something important. Any thoughts?

Thanks again.

Naomi [import]uid: 67217 topic_id: 33471 reply_id: 139226[/import]

Hi Naomi,
This is a tough call. I think you should “ignore” WiFi-only. If anybody is on a limited, strict phone data plan, they probably shouldn’t be playing data-intensive games. :slight_smile: But, it’s up to you. If you restrict it to WiFi only, you’re going to alienate a lot of users with phone data plans.

As for “network.canDetectNetworkStatusChanges”, I just followed the code example, and added it as a sort of “pre-check” on whether the device should start a network listener on the selected host. If it can’t, I just take a different direction (report to the user)… but then, “event.isReachable” should do a similar check and fail if it can’t connect to the host.
http://docs.coronalabs.com/api/library/network/canDetectNetworkStatusChanges.html

Best of luck!
Brent [import]uid: 200026 topic_id: 33471 reply_id: 139288[/import]

Thanks, Brent. I think I’ll simply go with checking the connectivity. It makes most sense for my app. Perhaps canDetectNetworkStatusChanges is useful for some apps that require constant and/or extended period of connection to internet, but for my game app that doesn’t need to talk to server(s) or website(s) constantly or require heavy-duty (and therefore quite lengthy) connection, I see no need to monitor the status changes.

Thanks again for giving this some more thoughts.

Naomi

Edit: Just confirmed that canDetectNetworkStatusChanges is for constantly monitoring the network connectivity. So, in my case, the best way to go appears to be checking the socket connection after all. [import]uid: 67217 topic_id: 33471 reply_id: 139290[/import]

Apparently network.canDetectNetworkStatusChanges doesn’t work on Android – is there a good way to test for a connection on Kindle Fire and the like?

Jay

network.canDetectNetworkStatusChanges does work on Android. It returns false. The purpose of the API is not to check network status but if the APIs are supported on the current platform. The network status check uses the iOS Reachability APIs, which are only available on iOS devices. 

There a new network API call that checks to see if you are capable of an Internet connection (either cellular or wifi).

[lua]

local status = network.getConnectionStatus()

if status.isConnected then

    – device is currently connected to a network

    if status.isMobile then

        – device is connected to cellular

    else

        – device is connected to wifi

    end

end

[/lua]

This will NOT tell you that you have Internet access, only you capable of connecting.

Tom, thanks for the code and the clarification. That code you posted now allows my Kindle Fire version to work.
 
I’d say the docs need to be more clear about it not working on Android. Yes, I know, it *does* work on Android but always returns false. That’s not “working” by any real definition. Neither canDetectNetworkStatusChanges nor setStatusListener() say anything about being useless for Android.

 Jay

Jay, I agree with you. I looked at the API and saw that it really doesn’t say that Reachability is a iOS-only feature. It’s on my list for an update.

Thanks,

Tom

Apparently network.canDetectNetworkStatusChanges doesn’t work on Android – is there a good way to test for a connection on Kindle Fire and the like?

Jay

I am using this:

function isNetworkOn() local status = network.getConnectionStatus() return status.isConnected end

Is there some minus in using this?

It works perfect as far as I can tell.

network.canDetectNetworkStatusChanges does work on Android. It returns false. The purpose of the API is not to check network status but if the APIs are supported on the current platform. The network status check uses the iOS Reachability APIs, which are only available on iOS devices. 

There a new network API call that checks to see if you are capable of an Internet connection (either cellular or wifi).

[lua]

local status = network.getConnectionStatus()

if status.isConnected then

    – device is currently connected to a network

    if status.isMobile then

        – device is connected to cellular

    else

        – device is connected to wifi

    end

end

[/lua]

This will NOT tell you that you have Internet access, only you capable of connecting.