Checking Host Reachability/Availability in Android
A Faster Solution
Instead of opening a complete socket connection you could use inetAddress.isReachable(int timeout)
. That would make the check faster but also more imprecise because this method just builds upon an echo request:
A typical implementation will use ICMP ECHO REQUESTs if the privilege can be obtained, otherwise it will try to establish a TCP connection on port 7 (Echo) of the destination host.
For my use case I had to establish a connection to a web server. Therefore it was necessary to me that the service on the server was up and running. So a socket connection was my preferred choice over a simple echo request.
Standard Solution
Java 7 and above
That's the code that I'm using for any Java 7 and above project:
/**
* Check if host is reachable.
* @param host The host to check for availability. Can either be a machine name, such as "google.com",
* or a textual representation of its IP address, such as "8.8.8.8".
* @param port The port number.
* @param timeout The timeout in milliseconds.
* @return True if the host is reachable. False otherwise.
*/
public static boolean isHostAvailable(final String host, final int port, final int timeout) {
try (final Socket socket = new Socket()) {
final InetAddress inetAddress = InetAddress.getByName(host);
final InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, port);
socket.connect(inetSocketAddress, timeout);
return true;
} catch (java.io.IOException e) {
e.printStackTrace();
return false;
}
}
Below Java 7
The try-catch-resource
block from the code above works only with Java 7 and a newer version. Prior to version 7 a finally
-block is needed to ensure the resource is closed correctly:
public static boolean isHostAvailable(final String host, final int port, final int timeout) {
final Socket socket = new Socket();
try {
... // same as above
} catch (java.io.IOException e) {
... // same as above
} finally {
if (socket != null) {
socket.close(); // this will throw another exception... just let the function throw it
}
}
}
Usage
host
can either be a machine name, such as "google.com", or an IP address, such as "8.8.8.8".
if (isHostAvailable("google.com", 80, 1000)) {
// do you work here
}
Further reading
Android Docs:
- Socket
- InetSocketAddress
- InetAddress.getByName()
- InetAddress.isReachable()
Stackoverflow:
- Preferred Java way to ping an HTTP URL for availability
It's not pretty but this is how I did it:
boolean exists = false;
try {
SocketAddress sockaddr = new InetSocketAddress(ip, port);
// Create an unbound socket
Socket sock = new Socket();
// This method will block no more than timeoutMs.
// If the timeout occurs, SocketTimeoutException is thrown.
int timeoutMs = 2000; // 2 seconds
sock.connect(sockaddr, timeoutMs);
exists = true;
} catch(IOException e) {
// Handle exception
}
To check connectivity you could use:
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
If it reports a connection, you could also then check via trying to do a http get to an address and then checking the status code that is returned. if no status code is returned it's pretty certain the host is unreachable.