How to check programmatically whether the Wifi network the phone is connected to has internet access ?
I cannot use "ping google.com" type solutions because it does not work on some devices such as Honor 10
How to check programmatically whether the Wifi network the phone is connected to has internet access ?
I cannot use "ping google.com" type solutions because it does not work on some devices such as Honor 10
Well, in order to decide whether a device is connected to the internet we have to define what "connected to the internet" actually means. As far as I know, the Android SDK doesn't offer any way to check that and I think that is because you have to ping a specific address after all, in order to see if it is reachable.
On my Android device, the WiFi indicator in the status bar shows an exclamation point whenever I am connected to the WiFi network but my internet connection is down. I am not sure, but I think it pings a google server (like 8.8.8.8
) behind the scenes in order to find out.
I think the best approach is not to ping Google, rather ping the specific address that you use in your app, for example if you use Last.fm API, ping that instead, because you could get in a situation where the Google server is reachable but the Last.fm API is down. This is just a general example, but the solution depends on your goal.
Just try connecting to whatever it is that you need to talk to, and handle failures in a graceful way.
Pinging something (even the server you want to talk to) isn't reliable, as the server, or some part of the network may block PING.
Pinging something "well known" (like Google's name-server on 8.8.8.8
) isn't reliable because it only tells you that it is up, not necessarily that you can reach the server you want to talk to. (Or, it might even be that the "well known" entity is down or unreachable, but your server is working OK).
Doing something other than just trying to connect to what you want risks introducing TOCTOU (Time-of-check to time-of-use) errors.
I've found a solution that is quick and does not require using ping command or having to load a page.
The solution uses Volley, Android's HTTP library:
public static void isInternetAccessWorking(Context context, final InternetAccessListener listener) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, "https://www.google.com",
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
listener.hasInternet(true);
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
listener.hasInternet(false);
}
});
Volley.newRequestQueue(context).add(stringRequest);
}
This method is not blocking: the activity or fragment calling isInternetAccessWorking() has to provide a parameter implementing InternetAccessListener that will receive the response
public interface InternetAccessListener {
void hasInternet(Boolean result);
}