2010-10-11 22 views
42

Estoy desarrollando una aplicación Ping para Android 2.2.Cómo hacer ping a IP externa desde Java Android

Intento mi código y funciona, pero solo en las 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) -> Time Out

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

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

¿Alguien me puede sugerir dónde? estoy haciendo mal?

+0

Más información demasiado ^^ ¿Prueba en el emulador o en un dispositivo real? ¿Tienes conexión a internet habilitada? es decir, en un dispositivo real, asegúrese de que la "red móvil" esté activada y de que tenga una conexión a Internet – Tseng

+0

que probé en el emulador y en un dispositivo real conectado a internet. Gracias. – Luks89

+0

¿Has acertado con este problema? Estoy teniendo el mismo problema. Si resolviste este problema, también podrías aconsejarme. Saludos Sanjay –

Respuesta

1

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.

+0

He probado en una tableta Android 2.2 conectada a través de WiFi. No uso ningún proveedor de Momile. . Gracias. – Luks89

+0

Luego su próximo paso debería ser olfatear el tráfico (no) generado por su dispositivo. Hay muchas cosas que podrían salir mal aquí ... – Luminger

+0

Es poco probable que sea causa de ICMP bloqueado, ya que la documentación de Android dice que 'InetAddress.isReachable' primero intenta hacer ping a través de ICMP si eso falla, intenta hacer ping en el puerto TCP 7 (Eco) – Tseng

7

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

Sobre el tema de "Redes limitaciones locales" que dice:

"Dependiendo del entorno, el emulador puede no ser capaz de soportar otras protocolos (como ICMP , usado para "ping") podría no ser compatible con . Actualmente, el emulador no admite IGMP o multidifusión. "

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

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

8

ejecute la utilidad de ping al mando de Android y analizan la salida (suponiendo que tiene permisos de root)

Véase el siguiente código Java fragmento:

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

} 
+0

Estoy haciendo ping -c 10 (promedios de 10 pings) ¿Sería posible mostrar línea por línea? Intenté que se agregara a un TextView donde normalmente se agregaría s a res pero eso no funcionó. – sajattack

+0

Esto funcionó para mí. Gracias – wolfaviators

43

He intentado siguiente 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; 
    } 
+0

Encontré que esta es la única manera confiable de comprobar el eco ICMP en 4.1. – pipacs

+1

¿Necesita permisos especiales para ejecutar esto? – htellez

+0

No olvides agregar permiso Internet:

-1

Utilice este código: este método funciona en 4.3+ y también para las versiones siguientes.

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

Esto es lo que he implementado a mí mismo, que devuelve la latencia media:

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

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

Desde qué versión de Android este código ¿trabajo? ¿Funcionará en Android 4.1+ – Arshad

+0

? Esta no es una solución universal, ya que depende de la utilidad externa. – arts777

4

Se trata de un simple ping utilizo 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"}

Cuestiones relacionadas