How to Ping External IP from Java Android

JavaAndroid

Java Problem Overview


I am developing a Ping application for Android 2.2.

I try my code and it works, but only in local IPs, that's my problem I want to do ping to external servers too.

Here is my code:

  private OnClickListener milistener = new OnClickListener() {
	public void onClick(View v) {
		TextView info = (TextView) findViewById(R.id.info);
		EditText edit = (EditText) findViewById(R.id.edit);
		Editable host = edit.getText();
		InetAddress in;
		in = null;
		// Definimos la ip de la cual haremos el ping
		try {
			in = InetAddress.getByName(host.toString());
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// Definimos un tiempo en el cual ha de responder
		try {
			if (in.isReachable(5000)) {
				info.setText("Responde OK");
			} else {
				info.setText("No responde: Time out");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			info.setText(e.toString());
		}
	}
};

> Ping 127.0.0.1 -> OK
> Ping 8.8.8.8 (Google DNS) -> Time Out

I put the following line at Manifest XML too:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

Can anyone suggest me where I'm doing wrong?

Java Solutions


Solution 1 - Java

I tried following code, which works for me.

private boolean executeCommand(){
		System.out.println("executeCommand");
		Runtime runtime = Runtime.getRuntime();
		try
		{
			Process  mIpAddrProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
			int mExitValue = mIpAddrProcess.waitFor();
			System.out.println(" mExitValue "+mExitValue);
			if(mExitValue==0){
				return true;
			}else{
				return false;
			}
		}
		catch (InterruptedException ignore)
		{
			ignore.printStackTrace();
			System.out.println(" Exception:"+ignore);
		} 
		catch (IOException e) 
		{
			e.printStackTrace();
			System.out.println(" Exception:"+e);
		}
		return false;
	}

Solution 2 - Java

This is a simple ping I use in one of the projects:

public static class Ping {
    public String net = "NO_CONNECTION";
    public String host = "";
    public String ip = "";
    public int dns = Integer.MAX_VALUE;
    public int cnt = Integer.MAX_VALUE;
}

public static Ping ping(URL url, Context ctx) {
    Ping r = new Ping();
    if (isNetworkConnected(ctx)) {
        r.net = getNetworkType(ctx);
        try {
            String hostAddress;
            long start = System.currentTimeMillis();
            hostAddress = InetAddress.getByName(url.getHost()).getHostAddress();
            long dnsResolved = System.currentTimeMillis();
            Socket socket = new Socket(hostAddress, url.getPort());
            socket.close();
            long probeFinish = System.currentTimeMillis();
            r.dns = (int) (dnsResolved - start);
            r.cnt = (int) (probeFinish - dnsResolved);
            r.host = url.getHost();
            r.ip = hostAddress;
        }
        catch (Exception ex) {
            Timber.e("Unable to ping");
        }
    }
    return r;
}

public static boolean isNetworkConnected(Context context) {
    ConnectivityManager cm =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}

@Nullable
public static String getNetworkType(Context context) {
    ConnectivityManager cm =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork != null) {
        return activeNetwork.getTypeName();
    }
    return null;
}

Usage: ping(new URL("https://www.google.com:443/"), this);

Result: {"cnt":100,"dns":109,"host":"www.google.com","ip":"212.188.10.114","net":"WIFI"}

Solution 3 - Java

Run the ping utility in Android's command and parse output (assuming you have root permissions)

See the following Java code snippet:

executeCmd("ping -c 1 -w 1 google.com", false);

public static String executeCmd(String cmd, boolean sudo){
	try {

		Process p;
		if(!sudo)
			p= Runtime.getRuntime().exec(cmd);
		else{
			p= Runtime.getRuntime().exec(new String[]{"su", "-c", cmd});
		}
		BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

		String s;
		String res = "";
		while ((s = stdInput.readLine()) != null) {
			res += s + "\n";
		}
		p.destroy();
		return res;
	} catch (Exception e) {
		e.printStackTrace();
	}
	return "";

}

Solution 4 - Java

In my case ping works from device but not from the emulator. I found this documentation: http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking

On the topic of "Local Networking Limitations" it says: > "Depending on the environment, the emulator may not be able to support > other protocols (such as ICMP, used for "ping") might not be > supported. Currently, the emulator does not support IGMP or > multicast."

Further information: http://groups.google.com/group/android-developers/browse_thread/thread/8657506be6819297

> this is a known limitation of the QEMU user-mode network stack. > Quoting from the original doc: Note that ping is not supported > reliably to the internet as it would require root privileges. It > means you can only ping the local router (10.0.2.2).

Solution 5 - Java

Ping for the google server or any other server

public boolean isConecctedToInternet() {

    Runtime runtime = Runtime.getRuntime();
    try {
        Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
        int     exitValue = ipProcess.waitFor();
        return (exitValue == 0);
    } catch (IOException e)          { e.printStackTrace(); }
    catch (InterruptedException e) { e.printStackTrace(); }
    return false;
}

Solution 6 - Java

I implemented "ping" in pure Android Java and hosted it on gitlab. It does the same thing as the ping executable, but is much easier to configure. It's has a couple useful features like being able to bind to a given Network.

https://github.com/dburckh/AndroidPing

Solution 7 - Java

This is what I implemented myself, which returns the average latency:

/*
Returns the latency to a given server in mili-seconds by issuing a ping command.
system will issue NUMBER_OF_PACKTETS ICMP Echo Request packet each having size of 56 bytes
every second, and returns the avg latency of them.
Returns 0 when there is no connection
 */
public double getLatency(String ipAddress){
    String pingCommand = "/system/bin/ping -c " + NUMBER_OF_PACKTETS + " " + ipAddress;
    String inputLine = "";
    double avgRtt = 0;

    try {
        // execute the command on the environment interface
        Process process = Runtime.getRuntime().exec(pingCommand);
        // gets the input stream to get the output of the executed command
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

        inputLine = bufferedReader.readLine();
        while ((inputLine != null)) {
            if (inputLine.length() > 0 && inputLine.contains("avg")) {  // when we get to the last line of executed ping command
                break;
            }
            inputLine = bufferedReader.readLine();
        }
    }
    catch (IOException e){
        Log.v(DEBUG_TAG, "getLatency: EXCEPTION");
        e.printStackTrace();
    }

    // Extracting the average round trip time from the inputLine string
    String afterEqual = inputLine.substring(inputLine.indexOf("="), inputLine.length()).trim();
    String afterFirstSlash = afterEqual.substring(afterEqual.indexOf('/') + 1, afterEqual.length()).trim();
    String strAvgRtt = afterFirstSlash.substring(0, afterFirstSlash.indexOf('/'));
    avgRtt = Double.valueOf(strAvgRtt);

    return avgRtt;
}

Solution 8 - Java

Maybe ICMP packets are blocked by your (mobile) provider. If this code doesn't work on the emulator try to sniff via wireshark or any other sniffer and have a look whats up on the wire when you fire the isReachable() method.

You may also find some info in your device log.

Solution 9 - Java

To get the boolean value for the hit on the ip

public Boolean getInetAddressByName(String name)
    {
        AsyncTask<String, Void, Boolean> task = new AsyncTask<String, Void, Boolean>()
        {

            @Override
            protected Boolean doInBackground(String... params) {
                try
                {
                    return InetAddress.getByName(params[0]).isReachable(2000);
                }
                catch (Exception e)
                {
                    return null;
                }
            }
        };
        try {
            return task.execute(name).get();
        }
        catch (InterruptedException e) {
            return null;
        }
        catch (ExecutionException e) {
            return null;
        }

    }

Solution 10 - Java

Use this Code: this method works on 4.3+ and also for below versions too.

   try {
    
    	 Process process = null;
    	 
    	if(Build.VERSION.SDK_INT <= 16) {
    		// shiny APIS 
    		   process = Runtime.getRuntime().exec(
 	                "/system/bin/ping -w 1 -c 1 " + url);
    		 
    		 
    	} 
    	else 
    	{

    			   process = new ProcessBuilder()
    	         .command("/system/bin/ping", url)
    	         .redirectErrorStream(true)
    	         .start();
    			 
    		}
    	
   
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(
        		process.getInputStream()));
       
        StringBuffer output = new StringBuffer();
        String temp;
        
        while ( (temp = reader.readLine()) != null)//.read(buffer)) > 0)
        {
            output.append(temp);
            count++;
        }
        
        reader.close();

         
        if(count > 0)
        	str = output.toString();
       
        process.destroy();
     } catch (IOException e) {
         e.printStackTrace();
    }
   
    Log.i("PING Count", ""+count);
    Log.i("PING String", str);

Solution 11 - Java

Pink ip Address

  public static int pingHost(String host, int timeout) throws IOException,
		InterruptedException {
	Runtime runtime = Runtime.getRuntime();
	timeout /= 1000;
	String cmd = "ping -c 1 -W " + timeout + " " + host;
	Process proc = runtime.exec(cmd);
	Log.d(TAG, cmd);
	proc.waitFor();
	int exit = proc.exitValue();
	return exit;
}
   Ping a host and return an int value of 0 or 1 or 2 0=success, 1=fail,
   * 2=error

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLuks89View Question on Stackoverflow
Solution 1 - Javakrishna5688View Answer on Stackoverflow
Solution 2 - JavaAlexander MayatskyView Answer on Stackoverflow
Solution 3 - JavaJim HuangView Answer on Stackoverflow
Solution 4 - JavaEugene van der MerweView Answer on Stackoverflow
Solution 5 - JavaPawan Kumar BaranwalView Answer on Stackoverflow
Solution 6 - JavaDustinView Answer on Stackoverflow
Solution 7 - Javasorry_I_wontView Answer on Stackoverflow
Solution 8 - JavaLumingerView Answer on Stackoverflow
Solution 9 - Javaaditya kanratView Answer on Stackoverflow
Solution 10 - JavaAhmad ArslanView Answer on Stackoverflow
Solution 11 - JavaSunil TaleView Answer on Stackoverflow