Cómo hacer ping a IP externa desde Java Android

Estoy desarrollando una aplicación Ping para Android 2.2.

Intento mi código y funciona, pero solo en direcciones IP locales, ese es mi problema. También quiero hacer ping a servidores externos.

Aquí está mi código:

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) -> Tiempo de espera

Puse la siguiente línea en Manifest XML también:

  

¿Alguien puede sugerirme dónde estoy haciendo mal?

Intenté seguir el código, que funciona para mí.

 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; } 

Ejecute la utilidad ping en el comando de Android y analice la salida (suponiendo que tenga permisos de root)

Vea el siguiente fragmento de código Java:

 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 ""; } 

En mi caso, el ping funciona desde el dispositivo pero no desde el emulador. Encontré esta documentación: http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking

Sobre el tema de “Limitaciones de redes locales” dice:

“Dependiendo del entorno, es posible que el emulador no sea compatible con otros protocolos (como ICMP, que se usa para” ping “). Es posible que el emulador no admita IGMP o multicast.”

Más información: http://groups.google.com/group/android-developers/browse_thread/thread/8657506be6819297

esta es una limitación conocida de la stack de red de modo de usuario QEMU. Citando del documento original: tenga en cuenta que el ping no es compatible de manera confiable con Internet, ya que requeriría privilegios de administrador. Significa que solo puede hacer ping al enrutador local (10.0.2.2).

Este es un simple ping que uso en uno de los proyectos:

 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; } 

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

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

Ping para el servidor de google o cualquier otro servidor

 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; } 

Tal vez los paquetes ICMP están bloqueados por su proveedor (móvil). Si este código no funciona en el emulador intente olfatear a través de wireshark o cualquier otro sniffer y eche un vistazo en el cable cuando dispare el método isReachable ().

También puede encontrar información en el registro de su dispositivo.

Esto es lo que implementé yo mismo, que devuelve la latencia promedio:

 /* 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; } 

esto funcionó para mí, sin raíz, Android 6.0, Android Studio, Acatel U3:

  private boolean Ping(String IP){ System.out.println("executeCommand"); Runtime runtime = Runtime.getRuntime(); try { Process mIpAddrProcess = runtime.exec("/system/bin/ping -c 1 " + IP); 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; } 

Use este código: este método funciona en 4.3+ y también para versiones inferiores.

  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);