如何从代码获取设备的IP地址?

是否有可能使用一些代码获取设备的IP地址?

这是我的帮手util读取IP和MAC地址。 实现是pure-java,但是我在getMACAddress()有一个注释块,它可以从特殊的linux(android)文件中读取值。 我只在几个设备和模拟器上运行这个代码,但是如果你发现奇怪的结果让我知道。

 // AndroidManifest.xml permissions <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> // test functions Utils.getMACAddress("wlan0"); Utils.getMACAddress("eth0"); Utils.getIPAddress(true); // IPv4 Utils.getIPAddress(false); // IPv6 

Utils.java

 import java.io.*; import java.net.*; import java.util.*; //import org.apache.http.conn.util.InetAddressUtils; public class Utils { /** * Convert byte array to hex string * @param bytes * @return */ public static String bytesToHex(byte[] bytes) { StringBuilder sbuf = new StringBuilder(); for(int idx=0; idx < bytes.length; idx++) { int intVal = bytes[idx] & 0xff; if (intVal < 0x10) sbuf.append("0"); sbuf.append(Integer.toHexString(intVal).toUpperCase()); } return sbuf.toString(); } /** * Get utf8 byte array. * @param str * @return array of NULL if error was found */ public static byte[] getUTF8Bytes(String str) { try { return str.getBytes("UTF-8"); } catch (Exception ex) { return null; } } /** * Load UTF8withBOM or any ansi text file. * @param filename * @return * @throws java.io.IOException */ public static String loadFileAsString(String filename) throws java.io.IOException { final int BUFLEN=1024; BufferedInputStream is = new BufferedInputStream(new FileInputStream(filename), BUFLEN); try { ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFLEN); byte[] bytes = new byte[BUFLEN]; boolean isUTF8=false; int read,count=0; while((read=is.read(bytes)) != -1) { if (count==0 && bytes[0]==(byte)0xEF && bytes[1]==(byte)0xBB && bytes[2]==(byte)0xBF ) { isUTF8=true; baos.write(bytes, 3, read-3); // drop UTF8 bom marker } else { baos.write(bytes, 0, read); } count+=read; } return isUTF8 ? new String(baos.toByteArray(), "UTF-8") : new String(baos.toByteArray()); } finally { try{ is.close(); } catch(Exception ex){} } } /** * Returns MAC address of the given interface name. * @param interfaceName eth0, wlan0 or NULL=use first interface * @return mac address or empty string */ public static String getMACAddress(String interfaceName) { try { List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface intf : interfaces) { if (interfaceName != null) { if (!intf.getName().equalsIgnoreCase(interfaceName)) continue; } byte[] mac = intf.getHardwareAddress(); if (mac==null) return ""; StringBuilder buf = new StringBuilder(); for (int idx=0; idx<mac.length; idx++) buf.append(String.format("%02X:", mac[idx])); if (buf.length()>0) buf.deleteCharAt(buf.length()-1); return buf.toString(); } } catch (Exception ex) { } // for now eat exceptions return ""; /*try { // this is so Linux hack return loadFileAsString("/sys/class/net/" +interfaceName + "/address").toUpperCase().trim(); } catch (IOException ex) { return null; }*/ } /** * Get IP address from first non-localhost interface * @param ipv4 true=return ipv4, false=return ipv6 * @return address or empty string */ public static String getIPAddress(boolean useIPv4) { try { List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); for (NetworkInterface intf : interfaces) { List<InetAddress> addrs = Collections.list(intf.getInetAddresses()); for (InetAddress addr : addrs) { if (!addr.isLoopbackAddress()) { String sAddr = addr.getHostAddress(); //boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr); boolean isIPv4 = sAddr.indexOf(':')<0; if (useIPv4) { if (isIPv4) return sAddr; } else { if (!isIPv4) { int delim = sAddr.indexOf('%'); // drop ip6 zone suffix return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase(); } } } } } } catch (Exception ex) { } // for now eat exceptions return ""; } } 

免责声明:这个工具类的想法和示例代码来自几个SO职位和谷歌。 我清理并合并了所有的例子。

这对我工作:

 WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE); String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress()); 

我使用下面的代码:我使用hashCode的原因是因为当我使用getHostAddress时,我得到了一些附加到IP地址的垃圾值。 但是hashCode对我来说工作得非常好,因为我可以使用Formatter来获取正确格式的IP地址。

以下是输出示例:

1.使用getHostAddress: ***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2.使用hashCodeFormatter***** IP=238.194.77.212

正如你所看到的第二种方法给了我我需要的东西。

 public String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { String ip = Formatter.formatIpAddress(inetAddress.hashCode()); Log.i(TAG, "***** IP="+ ip); return ip; } } } } catch (SocketException ex) { Log.e(TAG, ex.toString()); } return null; } 

虽然有一个正确的答案,我在这里分享我的答案,并希望这样会更方便。

 WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); WifiInfo wifiInf = wifiMan.getConnectionInfo(); int ipAddress = wifiInf.getIpAddress(); String ip = String.format("%d.%d.%d.%d", (ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff)); 
 public static String getLocalIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) { return inetAddress.getHostAddress(); } } } } catch (SocketException ex) { ex.printStackTrace(); } return null; } 

我添加了inetAddress instanceof Inet4Address来检查它是否是一个ipv4地址。

下面的代码可能会帮助你..不要忘记添加权限..

 public String getLocalIpAddress(){ try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); } } } } catch (Exception ex) { Log.e("IP Address", ex.toString()); } return null; } 

在清单文件中添加下面的权限。

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

快乐的编码!

您不需要像迄今为止提供的解决scheme那样添加权限。 下载这个网站作为string:

http://www.ip-api.com/json

要么

http://www.telize.com/geoip

将网站作为string下载可以用java代码完成:

http://www.itcuties.com/java/read-url-to-string/

像这样parsingJSON对象:

https://stackoverflow.com/a/18998203/1987258

json属性“query”或“ip”包含IP地址。

 private InetAddress getLocalAddress()throws IOException { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { //return inetAddress.getHostAddress().toString(); return inetAddress; } } } } catch (SocketException ex) { Log.e("SALMAN", ex.toString()); } return null; } 

如果你有一个壳; ifconfig eth0也适用于x86设备

最近, getLocalIpAddress()仍然返回一个IP地址,尽pipe它与networking断开(没有服务指示符)。 这意味着设置>关于手机>状态中显示的IP地址与应用程序的想法不同。

我已经通过添加以下代码实现了一个解决方法:

 ConnectivityManager cm = getConnectivityManager(); NetworkInfo net = cm.getActiveNetworkInfo(); if ((null == net) || !net.isConnectedOrConnecting()) { return null; } 

这对任何人都是一个钟声吗?

 WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE); String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString(); 

请检查此代码…使用此代码。 我们将从移动互联网获得IP …

 for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface intf = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); } } } 

我不做Android,但是我会以完全不同的方式来解决这个问题。

向Google发送查询,如下所示: https : //www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

并参考发布响应的HTML字段。 您也可以直接查询来源。

谷歌最喜欢在那里比你的应用程序更长的时间。

请记住,这可能是您的用户此时没有互联网,您希望发生什么!

祝你好运

方法getDeviceIpAddress返回设备的IP地址,如果连接的话,则优先使用wifi接口地址。

  @NonNull private String getDeviceIpAddress() { String actualConnectedToNetwork = null; ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); if (connManager != null) { NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI); if (mWifi.isConnected()) { actualConnectedToNetwork = getWifiIp(); } } if (TextUtils.isEmpty(actualConnectedToNetwork)) { actualConnectedToNetwork = getNetworkInterfaceIpAddress(); } if (TextUtils.isEmpty(actualConnectedToNetwork)) { actualConnectedToNetwork = "127.0.0.1"; } return actualConnectedToNetwork; } @Nullable private String getWifiIp() { final WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); if (mWifiManager != null && mWifiManager.isWifiEnabled()) { int ip = mWifiManager.getConnectionInfo().getIpAddress(); return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "." + ((ip >> 24) & 0xFF); } return null; } @Nullable public String getNetworkInterfaceIpAddress() { try { for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { NetworkInterface networkInterface = en.nextElement(); for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { InetAddress inetAddress = enumIpAddr.nextElement(); if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) { String host = inetAddress.getHostAddress(); if (!TextUtils.isEmpty(host)) { return host; } } } } } catch (Exception ex) { Log.e("IP Address", "getLocalIpAddress", ex); } return null; } 

根据我所testing的,这是我的build议

 import java.net.*; import java.util.*; public class hostUtil { public static String HOST_NAME = null; public static String HOST_IPADDRESS = null; public static String getThisHostName () { if (HOST_NAME == null) obtainHostInfo (); return HOST_NAME; } public static String getThisIpAddress () { if (HOST_IPADDRESS == null) obtainHostInfo (); return HOST_IPADDRESS; } protected static void obtainHostInfo () { HOST_IPADDRESS = "127.0.0.1"; HOST_NAME = "localhost"; try { InetAddress primera = InetAddress.getLocalHost(); String hostname = InetAddress.getLocalHost().getHostName (); if (!primera.isLoopbackAddress () && !hostname.equalsIgnoreCase ("localhost") && primera.getHostAddress ().indexOf (':') == -1) { // Got it without delay!! HOST_IPADDRESS = primera.getHostAddress (); HOST_NAME = hostname; //System.out.println ("First try! " + HOST_NAME + " IP " + HOST_IPADDRESS); return; } for (Enumeration<NetworkInterface> netArr = NetworkInterface.getNetworkInterfaces(); netArr.hasMoreElements();) { NetworkInterface netInte = netArr.nextElement (); for (Enumeration<InetAddress> addArr = netInte.getInetAddresses (); addArr.hasMoreElements ();) { InetAddress laAdd = addArr.nextElement (); String ipstring = laAdd.getHostAddress (); String hostName = laAdd.getHostName (); if (laAdd.isLoopbackAddress()) continue; if (hostName.equalsIgnoreCase ("localhost")) continue; if (ipstring.indexOf (':') >= 0) continue; HOST_IPADDRESS = ipstring; HOST_NAME = hostName; break; } } } catch (Exception ex) {} } }