2010-10-11 105 views
42

我正在为Android 2.2开发Ping应用程序。如何从Java中Ping外部IP Android

我尝试我的代码,它的工作原理,但只在本地IP,这是我的问题,我想ping外部服务器也。

这里是我的代码:

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

平127.0.0.1 - >确定
平8.8.8.8(谷歌DNS) - >超时

我把下面的行在清单XML太:

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

任何人都可以建议我在哪里我做错了吗?

+0

更多信息过于^^你在模拟器或者实际设备上测试它?你有互联网连接启用?即在真实设备上确保“移动网络”已激活,并且您已连接互联网 – Tseng 2010-10-11 10:41:35

+0

我在仿真器和连接到互联网的实际设备上进行了测试。谢谢。 – Luks89 2010-10-11 10:44:22

+0

你是否正确地解决了这个问题?我有同样的问题。如果你解决了这个问题,你能不能告诉我。问候 Sanjay – 2011-06-10 16:09:02

回答

1

也许ICMP数据包被您的(移动)提供商阻止。如果这段代码在模拟器上不起作用,请尝试通过wireshark或任何其他嗅探器进行嗅探,并在启动isReachable()方法时查看线路上的情况。

您也可以在设备日志中找到一些信息。

+0

我已经在通过Wifi连接的Android 2.2平板电脑测试,我不使用任何的妈妈提供者。谢谢。 – Luks89 2010-10-11 11:08:25

+0

然后,您的下一步应该是嗅探您的设备生成的流量(非)。有很多事情可能在这里出错...... – Luminger 2010-10-11 11:12:50

+0

这不太可能是由ICMP阻塞引起的,因为Android文档称“InetAddress.isReachable”首先尝试通过ICMP进行ping操作,如果该操作失败,它将尝试ping TCP端口7 (Echo) – Tseng 2010-10-11 13:37:22

7

在我的情况下,ping可以从设备上运行,但不能从模拟器运行。我发现这个文档: http://developer.android.com/guide/developing/devices/emulator.html#emulatornetworking

“本地网络限制”它说的话题:

“根据不同的环境中,仿真可能不能支持其他 协议(如ICMP ,用于“ping”)可能不支持 。目前,仿真器不支持IGMP或 多播。“

进一步的信息: http://groups.google.com/group/android-developers/browse_thread/thread/8657506be6819297

这是QEMU用户模式网络堆栈的已知的限制。 从原始文档中引用:请注意,ping不可靠地连接到因特网,因为它需要root权限 。它 意味着你只能ping本地路由器(10.0.2.2)。

8

在Android的命令来运行Ping实用程序和解析输出(假设你有root权限)

请参见下面的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 ""; 

} 
+0

我正在执行ping -c 10(平均10个ping)是否可以逐行显示?我试图让它附加到一个TextView,它通常会附加s到res,但没有奏效。 – sajattack 2012-08-21 23:43:36

+0

这对我有效。谢谢 – wolfaviators 2015-05-18 20:07:57

43

我尝试下面的代码,这对我的作品。

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

我发现这是在4.1上检查ICMP回显的唯一可靠方法。 – pipacs 2014-02-01 11:38:17

+1

您是否需要特殊权限才能运行此操作? – htellez 2015-10-31 05:02:22

+0

不要忘记添加权限互联网: 2015-12-26 08:22:11

-1

使用此代码:此方法适用于4.3+,也适用于以下版本。

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

这就是我实现了我自己,它返回的平均延迟:

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

平为谷歌的服务器或任何其他服务器

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

从这个代码的Android版本工作?它会在Android 4.1+上工作 – Arshad 2016-06-24 06:32:27

+0

这不是一个通用的解决方案,因为它依赖于外部工具。 – arts777 2017-06-16 14:53:05

4

这是一个简单的ping我用在其中一个项目中:

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

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

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