Can someone provide better and faster way to check if Google is available in Android? I have observed that connectiontimeout doesnot stop in given time_out. rather it takes more
Additionally to @astral-projection's solution, you may simply declare a Socket
. I use the following code on many of my projects and the timeout definitely works.
Socket socket;
final String host = "www.google.com";
final int port = 80;
final int timeout = 30000; // 30 seconds
try {
socket = new Socket();
socket.connect(new InetSocketAddress(host, port), timeout);
}
catch (UnknownHostException uhe) {
Log.e("GoogleSock", "I couldn't resolve the host you've provided!");
}
catch (SocketTimeoutException ste) {
Log.e("GoogleSock", "After a reasonable amount of time, I'm not able to connect, Google is probably down!");
}
catch (IOException ioe) {
Log.e("GoogleSock", "Hmmm... Sudden disconnection, probably you should start again!");
}
This might be tricky, though. Precisely on UnknownHostException
s, it may take longer to timeout, about 45 seconds - but on the other side, this usually happens when you cannot resolve the host, so that would morelike mean that your internet access has missconfigured DNS resolution (which is not probable).
Anyway, if you want to hedge your bets, you could solve this by two ways:
Don't use a host, use an IP address instead. You may get several Google's IPs just using ping
several times on the host. For instance:
shut-up@i-kill-you ~/services $ ping www.google.com
PING www.google.com (173.194.40.179) 56(84) bytes of data.
Another workaround would be starting a WatchDog
thread and finish the connection attempt after the required time. Evidently, forcely finishing would mean no success, so in your case, Google would be down.
---- EDIT ----
I'm adding an example of how would a watchdog be implemented in this case. Keep in mind it's a workaround to a situation that doesn't even need to happen, but it should do the trick if you really need to. I'm leaving the original code so you may see the differences:
Socket socket;
// You'll use this flag to check wether you're still trying to connect
boolean is_connecting = false;
final String host = "www.google.com";
final int port = 80;
final int timeout = 30000; // 30 seconds
// This method will test whether the is_connecting flag is still set to true
private void stillConnecting() {
if (is_connecting) {
Log.e("GoogleSock", "The socket is taking too long to establish a connection, Google is probably down!");
}
}
try {
socket = new Socket();
is_connecting = true;
socket.connect(new InetSocketAddress(host, port), timeout);
// Start a handler with postDelayed for 30 seconds (current timeout value), it will check whether is_connecting is still true
// That would mean that it won't probably resolve the host at all and the connection failed
// postDelayed is non-blocking, so don't worry about your thread being blocked
new Handler().postDelayed(
new Runnable() {
public void run() {
stillConnecting();
}
}, timeout);
}
catch (UnknownHostException uhe) {
is_connecting = false;
Log.e("GoogleSock", "I couldn't resolve the host you've provided!");
return;
}
catch (SocketTimeoutException ste) {
is_connecting = false;
Log.e("GoogleSock", "After a reasonable amount of time, I'm not able to connect, Google is probably down!");
return;
}
catch (IOException ioe) {
is_connecting = false;
Log.e("GoogleSock", "Hmmm... Sudden disconnection, probably you should start again!");
return;
}
// If you've reached this point, it would mean that the socket went ok, so Google is up
is_connecting = false;
Note: I'm assuming you're doing this where you should (I mean, not in the main UI) and that this is going within a Thread (you can use AsyncTask, a Thread, a Thread within a Service...).
A broadcast receiver might come handy:
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getActivity(), "Connection reset, rolling back", Toast.LENGTH_LONG).show();
}
};
It is also battery friendly.
Also dont forget to unregister it: (onDestroy())
getActivity().unregisterReceiver(networkStateReceiver);
As Astral said, you can use BroadcastReceiver to get the status of internet connection and thats the best way to check for internet connection; but if the server you are trying to connect is down or is not responding then just to be on the safe side create a timeout loop. If there's no reply back from the server in specific time then cancel request and show error message to the user.