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.

Tags:

Android