如何从Java Android平台的外部IP
我正在开发Android 2.2的Ping应用程序。
我尝试我的代码,它的工作原理,但只在本地的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()); } } };
Ping 127.0.0.1 – >确定
Ping 8.8.8.8(Google DNS) – >超时
我也在Manifest XML中join了以下内容:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
任何人都可以build议我在哪里做错了?
我尝试了下面的代码,这对我很有用。
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; }
在Android的命令中运行ping实用程序并parsing输出(假设您拥有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 ""; }
在我的情况下,ping从设备工作,但不是从模拟器。 我发现这个文档: http : //developer.android.com/guide/developing/devices/emulator.html#emulatornetworking
关于“本地networking限制”这个话题,它说:
“根据环境的不同,仿真器可能无法支持其他协议(如ICMP,用于”ping“)可能不被支持,目前,仿真器不支持IGMP或组播。
更多信息: http : //groups.google.com/group/android-developers/browse_thread/thread/8657506be6819297
这是QEMU用户模式networking堆栈的已知限制。 从原始文档引用:请注意,ping不可靠地支持互联网,因为它需要root权限。 这意味着你只能ping本地路由器(10.0.2.2)。
这是我在一个项目中使用的一个简单的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"}
Ping为谷歌服务器或任何其他服务器
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; }
也许ICMP数据包被你的(移动)提供商阻止。 如果这个代码在仿真器上不起作用,可以尝试通过wireshark或任何其他嗅探器进行嗅探,并在启动isReachable()方法时查看线路上的情况。
您也可以在设备日志中find一些信息。
这是我自己实现的,它返回平均延迟:
/* 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; }
使用此代码:此方法适用于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);