【问题标题】:How to get IP address of the device from code?如何从代码中获取设备的 IP 地址?
【发布时间】:2011-08-29 04:50:09
【问题描述】:

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

【问题讨论】:

标签: android ip-address


【解决方案1】:

这是我读取 IP 和 MAC 地址的帮助工具。实现是纯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 toConvert
     * @return hexValue
     */
    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 which to be converted
     * @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 which to be converted to string
     * @return String value of File
     * @throws java.io.IOException if error occurs
     */
    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 ignored){} 
        }
    }

    /**
     * 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 (byte aMac : mac) buf.append(String.format("%02X:",aMac));  
                if (buf.length()>0) buf.deleteCharAt(buf.length()-1);
                return buf.toString();
            }
        } catch (Exception ignored) { } // 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 useIPv4   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 ignored) { } // for now eat exceptions
        return "";
    }

}

免责声明:此 Utils 类的想法和示例代码来自 几个 SO 帖子和谷歌。我已经清理并合并了所有示例。

【讨论】:

  • 这需要 API 级别 9 及以上,因为 getHardwareAddress()。
  • 问题 - toUpperCase() 上的 lint 警告。捕捉Exception 总是很狡猾(无论如何,辅助方法都应该抛出,让调用者处理异常——虽然没有修改)。格式:不应超过 80 行。 getHardwareAddress() 的条件执行 - 补丁:github.com/Utumno/AndroidHelpers/commit/…。你说什么?
  • 如果您在本地网络上(例如 Wifi 或模拟器),您将获得一个私有 IP 地址。您可以通过对提供代理地址的特定网站的请求来获取代理 IP 地址,例如whatismyip.akamai.com
  • 这对我来说非常适合使用 Wifi 的真实设备。非常感谢,兄弟
  • 在尝试获取 IP 地址时,我在 Nexus 6 上得到了不好的结果。我有一个名为“name:dummy0 (dummy0)”的 NetworkInterface,它给出了一个格式为“/XX::XXXX:XXXX:XXXX:XXXX%dummy0”的地址,还有一个对应于 wlan0 的真实网络接口,但是因为“虚拟”首先发生,所以我总是得到那个虚拟地址
【解决方案2】:

AndroidManifest.xml 中声明的ACCESS_WIFI_STATE 许可:

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

可以使用WifiManager获取IP地址:

Context context = requireContext().getApplicationContext();
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

【讨论】:

  • 这个对我有用。但是,它需要“ACCESS_WIFI_STATE”权限,正如“Umair”所写,不需要列表使用。
  • formatIpAddress 出于某种原因已被弃用。应该改用什么?
  • 来自文档:使用getHostAddress(),它同时支持 IPv4 和 IPv6 地址。此方法不支持 IPv6 地址。
  • 如何使用 getHostAddress() 获取服务器和客户端 IP 地址@RyanR ?
  • 即使用户使用数据而不是wifi,这仍然有效吗?
【解决方案3】:
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地址。

【讨论】:

  • 拯救了我的一天!谢谢。这是三星 s7 edge 上唯一的代码
  • 这是真正的答案,而不是上面只获得WiFi接口的答案。
  • 这确实应该是正确答案,它适用于 WiFi 和移动网络,并且使用“getHostAddress”而不是自定义格式。
  • 但是,它获取了我的本地 IP,我需要我的公共 IP(因为我相信 OP 也需要)
  • 除了访问一些外部 REST 端点报告它所看到的公共 IP 之外,没有其他方法可以获取公共 IP,例如:api.ipify.org/?format=json。设备甚至不知道公共 IP 地址本身。
【解决方案4】:

我使用了以下代码: 我使用 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;
}

【讨论】:

  • getHostAddress() 将与您添加的格式化程序相同。
  • 使用 hashCode 是完全错误的,而且会返回废话。请改用 InetAddress.getHostAddress()。
  • 更改这部分: if (!inetAddress.isLoopbackAddress()) { String ip = Formatter.formatIpAddress(inetAddress.hashCode()); Log.i(TAG, "***** IP="+ ip);返回IP; } 与此: if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())) { return inetAddress .getHostAddress().toString(); } 这将为您提供正确的 ip 格式
  • 代码只返回第一个IP,手机可能同时有celluar、WIFI和BT地址
  • @Chuy47 它说 InetAddressUtils 找不到
【解决方案5】:

虽然有正确答案,但我在这里分享我的答案,希望这种方式更方便。

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

【讨论】:

  • 谢谢! Formatter 被弃用了,我真的不想写简单的位逻辑。
  • 效果很好,但需要 WIFI_STATE 权限:&lt;uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /&gt;
  • 我使用了格式化程序,但它不起作用。太好了!非常感谢。你能解释一下最后一行做了什么吗?我知道 %d.%d.%d.%d 但是其他人呢?谢谢
  • 不,这不是直接回答 OP。因为并非所有 Android 设备都使用 WiFi 连接到互联网。它可能在以太网上有 NATed LAN,或 BT 而不是 NATed WAN 连接等。
【解决方案6】:

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

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

编码愉快!!

【讨论】:

  • 嘿,这会返回一个不正确的值,例如:“fe80::f225:b7ff:fe8c:d357%wlan0”
  • @Jorgesys 检查 evertvandenbruel 的答案,他在其中添加了 inetAddress instanceof Inet4Address
  • 更改 if 条件以获取正确的 ip:if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address)
  • 代码只返回第一个IP,手机可能同时有celluar、WIFI和BT地址
  • 如果你有一个热点,你可能会得到多个 ip
【解决方案7】:

kotlin 极简版

fun getIpv4HostAddress(): String {
    NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
        networkInterface.inetAddresses?.toList()?.find {
            !it.isLoopbackAddress && it is Inet4Address
        }?.let { return it.hostAddress }
    }
    return ""
}

【讨论】:

    【解决方案8】:

    您不需要像目前提供的解决方案那样添加权限。以字符串形式下载本网站:

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

    http://www.telize.com/geoip

    可以使用java代码将网站下载为字符串:

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

    像这样解析 JSON 对象:

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

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

    【讨论】:

    • 这需要互联网连接。大问题
    • 为什么这是个大问题?当然,您需要互联网连接,因为 IP 地址在技术上与这种连接相关。如果您离开家去餐厅,您将使用另一个互联网连接,从而使用另一个 IP 地址。您不需要添加更多类似 ACCESS_NETWORK_STATE 或 ACCESS_WIFI_STATE 的内容。互联网连接是我提供的解决方案所需的唯一权限。
    • 哪个域?如果 ip-api.com 不起作用,您可以使用 telize.com 作为后备。否则,您可以使用 api.ipify.org 。它也可以在这里找到(不是 json):ip.jsontest.com/?callback=showIP。许多应用程序使用保证保持在线的域;这是正常的。但是,如果您使用回退,则不太可能出现问题。
    • 大卫的原点仍然成立。如果您在无法访问互联网的内部网络上怎么办。
    • 我从没想过这一点,因为我不知道肯定需要网络但应该在没有互联网的情况下工作的应用程序的任何实际用途(也许有,但我看不到移动设备)。
    【解决方案9】:
    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;
            }
    

    【讨论】:

    • 这会不会从wifi接口返回私网ip,比如192.168.0.x?还是它总是返回将在互联网上使用的外部 IP 地址?
    【解决方案10】:

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

    【讨论】:

      【解决方案11】:

      在您的活动中,以下函数 getIpAddress(context) 返回手机的 IP 地址:

      public static String getIpAddress(Context context) {
          WifiManager wifiManager = (WifiManager) context.getApplicationContext()
                      .getSystemService(WIFI_SERVICE);
      
          String ipAddress = intToInetAddress(wifiManager.getDhcpInfo().ipAddress).toString();
      
          ipAddress = ipAddress.substring(1);
      
          return ipAddress;
      }
      
      public static InetAddress intToInetAddress(int hostAddress) {
          byte[] addressBytes = { (byte)(0xff & hostAddress),
                      (byte)(0xff & (hostAddress >> 8)),
                      (byte)(0xff & (hostAddress >> 16)),
                      (byte)(0xff & (hostAddress >> 24)) };
      
          try {
              return InetAddress.getByAddress(addressBytes);
          } catch (UnknownHostException e) {
              throw new AssertionError();
          }
      }
      

      【讨论】:

      • 我得到 0.0.0.0
      • 您的手机连接到 wifi 网络了吗?如果调用 wifiManager.getConnectionInfo().getSSID() 会返回哪个值?
      • 它是否适用于连接到移动数据而不是 WiFi 的设备?
      • 否,此方法仅在设备连接到 WiFi 时有效
      【解决方案12】:

      这是对this answer 的重做,它去除了不相关的信息,添加了有用的 cmets,更清晰地命名变量,并改进了逻辑。

      不要忘记包含以下权限:

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

      InternetHelper.java:

      public class InternetHelper {
      
          /**
           * Get IP address from first non-localhost interface
           *
           * @param useIPv4 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 interface_ : interfaces) {
      
                      for (InetAddress inetAddress :
                              Collections.list(interface_.getInetAddresses())) {
      
                          /* a loopback address would be something like 127.0.0.1 (the device
                             itself). we want to return the first non-loopback address. */
                          if (!inetAddress.isLoopbackAddress()) {
                              String ipAddr = inetAddress.getHostAddress();
                              boolean isIPv4 = ipAddr.indexOf(':') < 0;
      
                              if (isIPv4 && !useIPv4) {
                                  continue;
                              }
                              if (useIPv4 && !isIPv4) {
                                  int delim = ipAddr.indexOf('%'); // drop ip6 zone suffix
                                  ipAddr = delim < 0 ? ipAddr.toUpperCase() :
                                          ipAddr.substring(0, delim).toUpperCase();
                              }
                              return ipAddr;
                          }
                      }
      
                  }
              } catch (Exception ignored) { } // if we can't connect, just return empty string
              return "";
          }
      
          /**
           * Get IPv4 address from first non-localhost interface
           *
           * @return address or empty string
           */
          public static String getIPAddress() {
              return getIPAddress(true);
          }
      
      }
      

      【讨论】:

        【解决方案13】:
        WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
        String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();
        

        【讨论】:

          【解决方案14】:

          最近,getLocalIpAddress()虽然断网(无服务指示灯)仍返回一个IP地址。这意味着设置>关于手机>状态中显示的IP地址与应用程序的想法不同。

          我之前通过添加此代码实现了一种解决方法:

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

          这会给任何人敲响警钟吗?

          【讨论】:

            【解决方案15】:

            只需使用 Volley 从this 站点获取 ip

            RequestQueue queue = Volley.newRequestQueue(this);    
            String urlip = "http://checkip.amazonaws.com/";
            
                StringRequest stringRequest = new StringRequest(Request.Method.GET, urlip, new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        txtIP.setText(response);
            
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        txtIP.setText("didnt work");
                    }
                });
            
                queue.add(stringRequest);
            

            【讨论】:

            • 这是获取一个公共 ip,并且依赖于亚马逊的 aws check ip 服务,该服务最终可能会在某一天改变或消失,并且只有在设备可以访问互联网时才有效。在本地网络上或离线时,它将无法正常工作。此外,请注意 checkip 服务并不安全,因此可能会被中间人伪造。要获取设备的IP地址列表,我们需要查询设备的网络接口列表(蜂窝,wifi等...),并获取非本地地址。
            【解决方案16】:

            在 Kotlin 中,没有格式化程序

            private fun getIPAddress(useIPv4 : Boolean): String {
                try {
                    var interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
                    for (intf in interfaces) {
                        var addrs = Collections.list(intf.getInetAddresses());
                        for (addr in addrs) {
                            if (!addr.isLoopbackAddress()) {
                                var sAddr = addr.getHostAddress();
                                var isIPv4: Boolean
                                isIPv4 = sAddr.indexOf(':')<0
                                if (useIPv4) {
                                    if (isIPv4)
                                        return sAddr;
                                } else {
                                    if (!isIPv4) {
                                        var delim = sAddr.indexOf('%') // drop ip6 zone suffix
                                        if (delim < 0) {
                                            return sAddr.toUpperCase()
                                        }
                                        else {
                                            return sAddr.substring(0, delim).toUpperCase()
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (e: java.lang.Exception) { }
                return ""
            }
            

            【讨论】:

              【解决方案17】:

              一台设备可能有多个 IP 地址,而在特定应用中使用的 IP 地址可能不是接收请求的服务器将看到的 IP。事实上,一些用户使用 VPN 或代理,例如 Cloudflare Warp

              如果您的目的是获取从您的设备接收请求的服务器显示的 IP 地址,那么最好使用其 Java 查询 IP 地理定位服务,例如 Ipregistry(免责声明:我为该公司工作)客户:

              https://github.com/ipregistry/ipregistry-java

              IpregistryClient client = new IpregistryClient("tryout");
              RequesterIpInfo requesterIpInfo = client.lookup();
              requesterIpInfo.getIp();
              

              除了使用起来非常简单之外,您还可以获得额外的信息,例如国家、语言、货币、设备 IP 的时区,并且您可以识别用户是否正在使用代理。

              【讨论】:

                【解决方案18】:

                这是互联网上存在的最简单、最简单的方法... 首先,将此权限添加到您的清单文件中...

                1. “互联网”

                2. “ACCESS_NETWORK_STATE”

                将此添加到Activity的onCreate文件中..

                    getPublicIP();
                

                现在将此函数添加到您的 MainActivity.class。

                    private void getPublicIP() {
                ArrayList<String> urls=new ArrayList<String>(); //to read each line
                
                        new Thread(new Runnable(){
                            public void run(){
                                //TextView t; //to show the result, please declare and find it inside onCreate()
                
                                try {
                                    // Create a URL for the desired page
                                    URL url = new URL("https://api.ipify.org/"); //My text file location
                                    //First open the connection
                                    HttpURLConnection conn=(HttpURLConnection) url.openConnection();
                                    conn.setConnectTimeout(60000); // timing out in a minute
                
                                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                
                                    //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
                                    String str;
                                    while ((str = in.readLine()) != null) {
                                        urls.add(str);
                                    }
                                    in.close();
                                } catch (Exception e) {
                                    Log.d("MyTag",e.toString());
                                }
                
                                //since we are in background thread, to post results we have to go back to ui thread. do the following for that
                
                                PermissionsActivity.this.runOnUiThread(new Runnable(){
                                    public void run(){
                                        try {
                                            Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
                                        }
                                        catch (Exception e){
                                            Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                });
                
                            }
                        }).start();
                
                    }

                【讨论】:

                • urls.get(0) 包含您的公共 IP 地址。
                • 您必须在活动文件中声明如下: ArrayList urls=new ArrayList(); //读取每一行
                • 在连接到手机互联网时不起作用。在这种情况下如何获取公共 ip?
                【解决方案19】:
                public static String getdeviceIpAddress() {
                    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;
                }
                

                【讨论】:

                  【解决方案20】:

                  这是@Nilesh 和@anaargund 的kotlin 版本

                    fun getIpAddress(): String {
                      var ip = ""
                      try {
                          val wm = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
                          ip = Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
                      } catch (e: java.lang.Exception) {
                  
                      }
                  
                      if (ip.isEmpty()) {
                          try {
                              val en = NetworkInterface.getNetworkInterfaces()
                              while (en.hasMoreElements()) {
                                  val networkInterface = en.nextElement()
                                  val enumIpAddr = networkInterface.inetAddresses
                                  while (enumIpAddr.hasMoreElements()) {
                                      val inetAddress = enumIpAddr.nextElement()
                                      if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                                          val host = inetAddress.getHostAddress()
                                          if (host.isNotEmpty()) {
                                              ip =  host
                                              break;
                                          }
                                      }
                                  }
                  
                              }
                          } catch (e: java.lang.Exception) {
                  
                          }
                      }
                  
                     if (ip.isEmpty())
                        ip = "127.0.0.1"
                      return ip
                  }
                  

                  【讨论】:

                  • 如果这是您在实际项目中的代码风格,我建议您阅读 robert martin 的“干净代码”
                  【解决方案21】:

                  编译一些想法,以更好的 kotlin 解决方案从WifiManager 获取 wifi ip:

                  private fun getWifiIp(context: Context): String? {
                    return context.getSystemService<WifiManager>().let {
                       when {
                        it == null -> "No wifi available"
                        !it.isWifiEnabled -> "Wifi is disabled"
                        it.connectionInfo == null -> "Wifi not connected"
                        else -> {
                          val ip = it.connectionInfo.ipAddress
                          ((ip and 0xFF).toString() + "." + (ip shr 8 and 0xFF) + "." + (ip shr 16 and 0xFF) + "." + (ip shr 24 and 0xFF))
                        }
                      }
                    }
                  }
                  

                  您也可以通过NetworkInterface获取ip4环回设备的IP地址:

                  fun getNetworkIp4LoopbackIps(): Map<String, String> = try {
                    NetworkInterface.getNetworkInterfaces()
                      .asSequence()
                      .associate { it.displayName to it.ip4LoopbackIps() }
                      .filterValues { it.isNotEmpty() }
                  } catch (ex: Exception) {
                    emptyMap()
                  }
                  
                  private fun NetworkInterface.ip4LoopbackIps() =
                    inetAddresses.asSequence()
                      .filter { !it.isLoopbackAddress && it is Inet4Address }
                      .map { it.hostAddress }
                      .filter { it.isNotEmpty() }
                      .joinToString()
                  

                  【讨论】:

                    【解决方案22】:

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

                    【讨论】:

                      【解决方案23】:

                      请检查此代码...使用此代码。我们将从移动互联网获取 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();
                                          }
                                      }
                                  }
                      

                      【讨论】:

                        【解决方案24】:

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

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

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

                        Google 会比您的应用程序存在的时间更长。

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

                        祝你好运

                        【讨论】:

                        • 有趣!我敢打赌,谷歌有某种 API 调用会返回你的 IP,这将比扫描 HTML 更稳定。
                        【解决方案25】:

                        你可以这样做

                        String stringUrl = "https://ipinfo.io/ip";
                        //String stringUrl = "http://whatismyip.akamai.com/";
                        // Instantiate the RequestQueue.
                        RequestQueue queue = Volley.newRequestQueue(MainActivity.instance);
                        //String url ="http://www.google.com";
                        
                        // Request a string response from the provided URL.
                        StringRequest stringRequest = new StringRequest(Request.Method.GET, stringUrl,
                                new Response.Listener<String>() {
                                    @Override
                                    public void onResponse(String response) {
                                        // Display the first 500 characters of the response string.
                                        Log.e(MGLogTag, "GET IP : " + response);
                        
                                    }
                                }, new Response.ErrorListener() {
                            @Override
                            public void onErrorResponse(VolleyError error) {
                                IP = "That didn't work!";
                            }
                        });
                        
                        // Add the request to the RequestQueue.
                        queue.add(stringRequest);
                        

                        【讨论】:

                          【解决方案26】:
                           //    @NonNull
                              public static String getIPAddress() {
                                  if (TextUtils.isEmpty(deviceIpAddress))
                                      new PublicIPAddress().execute();
                                  return deviceIpAddress;
                              }
                          
                              public static String deviceIpAddress = "";
                          
                              public static class PublicIPAddress extends AsyncTask<String, Void, String> {
                                  InetAddress localhost = null;
                          
                                  protected String doInBackground(String... urls) {
                                      try {
                                          localhost = InetAddress.getLocalHost();
                                          URL url_name = new URL("http://bot.whatismyipaddress.com");
                                          BufferedReader sc = new BufferedReader(new InputStreamReader(url_name.openStream()));
                                          deviceIpAddress = sc.readLine().trim();
                                      } catch (Exception e) {
                                          deviceIpAddress = "";
                                      }
                                      return deviceIpAddress;
                                  }
                          
                                  protected void onPostExecute(String string) {
                                      Lg.d("deviceIpAddress", string);
                                  }
                              }
                          

                          【讨论】:

                            【解决方案27】:

                            老实说,我对代码安全只是一点点熟悉,所以这可能是 hack-ish。但对我来说,这是最通用的方法:

                            package com.my_objects.ip;
                            
                            import java.net.InetAddress;
                            import java.net.UnknownHostException;
                            
                            public class MyIpByHost 
                            {
                              public static void main(String a[])
                              {
                               try 
                                {
                                  InetAddress host = InetAddress.getByName("nameOfDevice or webAddress");
                                  System.out.println(host.getHostAddress());
                                } 
                               catch (UnknownHostException e) 
                                {
                                  e.printStackTrace();
                                }
                            } }
                            

                            【讨论】:

                            • InetAddress会返回当前设备所连接设备的IP,而不是当前设备的IP吗?
                            【解决方案28】:

                            根据我的测试,这是我的建议

                            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) {}
                               }
                            }
                            

                            【讨论】:

                              猜你喜欢
                              • 2013-07-02
                              • 1970-01-01
                              • 2018-08-05
                              • 2013-06-29
                              • 2015-02-26
                              • 2021-04-04
                              • 1970-01-01
                              相关资源
                              最近更新 更多