【问题标题】:Get my wifi ip address Android获取我的 wifi ip 地址 Android
【发布时间】:2013-05-19 19:17:14
【问题描述】:

在wifi下连接手机如何获取ip地址?

我找到了一个方法 here,但即使我在 wifi 下,它也会返回类似 24.182.239.255 的内容,并且我期望类似 192.168.1.10 的内容。

我想要类似的东西:

if (you are under wifi)
    String ip4 = getWifiIP()
else
    String ip4 = getIPAddress with the method linked before

非常感谢!

【问题讨论】:

标签: android ip android-wifi android-networking


【解决方案1】:

如果您想在连接到 Wi-Fi 时获取设备的私有 IP 地址,可以试试这个。

WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
String ipAddress = Formatter.formatIpAddress(ip);

一定要添加权限

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

到您的清单。

【讨论】:

  • formatIpAddress() 已弃用。请参阅下面 Digital Rounin 的解决方案,改用 InetAddress.getHostAddress()。
  • 仅限新手:应该是getSystemService(Context.WIFI_SERVICE)
  • Endiannes 是一个重要的考虑因素,上面的代码将在 Little Endian 硬件上返回反向 IP。检查下面数字鲁宁的答案以获取正确的方法。或stackoverflow.com/questions/29937433/… 用于更短的方法(将 ip 作为 int 返回,但顺序正确)。
  • 在下面查看我的答案。它将获取活动链接的 ip 地址,无论是 wifi 还是移动端
  • 感谢您的回答,它也解决了我的问题。我正在寻求相同的答案,但与科尔多瓦。要使用 Cordova 获取设备 IP 地址,请尝试使用以下模块:npmjs.com/package/cordova-plugin-android-wifi-manager
【解决方案2】:

所以要考虑的是 Formatter.formatIpAddress(int) 已被弃用:

此方法在 API 级别 12 中已弃用。 使用 getHostAddress(),它支持 IPv4 和 IPv6 地址。此方法不支持 IPv6 地址。

因此使用formatIpAddress(int) 可能不是一个好的长期解决方案,尽管它会起作用。

如果您绝对希望获得 WiFi 接口的 IP 地址,这是一个潜在的解决方案:

protected String wifiIpAddress(Context context) {
    WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
    int ipAddress = wifiManager.getConnectionInfo().getIpAddress();

    // Convert little-endian to big-endianif needed
    if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
        ipAddress = Integer.reverseBytes(ipAddress);
    }

    byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray();

    String ipAddressString;
    try {
        ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress();
    } catch (UnknownHostException ex) {
        Log.e("WIFIIP", "Unable to get host address.");
        ipAddressString = null;
    }

    return ipAddressString;
}

如之前的回复所述,您需要在 AndroidManifest.xml 中设置以下内容:

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

请注意,这只是一个示例解决方案。您应该花时间检查空值等,以确保 UX 流畅。

具有讽刺意味的是,一方面 Google 弃用了 formatIpAddress(int),但仍有 getIpAddress() 仍然返回一个整数值。 IP 地址是 int 也排除了它与 IPv6 兼容。

接下来是字节顺序可能是也可能不是问题的事实。我只测试了三个设备,它们都是小端的。看起来字节序可能因硬件而异,即使我们在 VM 中运行,这仍然是一个问题。所以为了安全起见,我在代码中添加了字节序检查。

getByAddress(byte[]) 似乎希望整数值是大端。从对此的研究看来,网络字节顺序是大端的。这是有道理的,因为像 192.168.12.22 这样的地址是一个大端数。


查看HammerNet GitHub 项目。它实现了上面的代码以及一堆健全性检查、处理 AVD 的默认值、单元测试和其他东西的能力。我必须为我的一个应用程序实现这一点,并决定开源该库。

【讨论】:

  • 无法在 Android Studio 中导入 BigInteger。我知道这很奇怪,但它确实发生了。
  • 字节序转换实际上对于 Nexus 5 及更多设备非常重要。谢谢!
  • "WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE)" 还是好一点的。
  • 这会导致反向 IP 地址...还有其他人吗?
  • @ElliotM 不,结果是正确的人类可读 IP 地址。您是否在特定/奇异的设备上进行了测试?
【解决方案3】:

这将为您提供 WiFi IPv4、IPv6 或两者。

public static Enumeration<InetAddress> getWifiInetAddresses(final Context context) {
    final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    final WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    final String macAddress = wifiInfo.getMacAddress();
    final String[] macParts = macAddress.split(":");
    final byte[] macBytes = new byte[macParts.length];
    for (int i = 0; i< macParts.length; i++) {
        macBytes[i] = (byte)Integer.parseInt(macParts[i], 16);
    }
    try {
        final Enumeration<NetworkInterface> e =  NetworkInterface.getNetworkInterfaces();
        while (e.hasMoreElements()) {
            final NetworkInterface networkInterface = e.nextElement();
            if (Arrays.equals(networkInterface.getHardwareAddress(), macBytes)) {
                return networkInterface.getInetAddresses();
            }
        }
    } catch (SocketException e) {
        Log.wtf("WIFIIP", "Unable to NetworkInterface.getNetworkInterfaces()");
    }
    return null;
}

@SuppressWarnings("unchecked")
public static<T extends InetAddress> T getWifiInetAddress(final Context context, final Class<T> inetClass) {
    final Enumeration<InetAddress> e = getWifiInetAddresses(context);
    while (e.hasMoreElements()) {
        final InetAddress inetAddress = e.nextElement();
        if (inetAddress.getClass() == inetClass) {
            return (T)inetAddress;
        }
    }
    return null;
}

用法:

final Inet4Address inet4Address = getWifiInetAddress(context, Inet4Address.class);
final Inet6Address inet6Address = getWifiInetAddress(context, Inet6Address.class);

别忘了:

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

【讨论】:

    【解决方案4】:

    如果终端中安装了 adb,则执行以下操作:

    Runtime.getRuntime.exec("adb", "shell", "getprop", "dhcp.wlan0.ipaddress");
    

    【讨论】:

    • 原因:java.io.IOException:无法运行程序“adb”:错误=2,没有这样的文件或目录
    • 安装安卓sdk
    • 在哪里?在智能手机上?在没有 sdk 的计算机上强制编译应用程序。
    【解决方案5】:

    根据我的崩溃日志,似乎并非所有设备都返回 WiFi mac 地址。

    这是最受欢迎的回复的更简洁版本。

    final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    final ByteBuffer byteBuffer = ByteBuffer.allocate(4);
    byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
    byteBuffer.putInt(wifiInfo.getIpAddress());
    try {
    final InetAddress inetAddress = InetAddress.getByAddress(null, byteBuffer.array());
    } catch (UnknownHostException e) {
        //TODO: Return null?
    }
    

    【讨论】:

    • 缺少 WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    【解决方案6】:

    Formatter.formatIpAddress(int) 已弃用:

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

    【讨论】:

    • 是的。它不支持 IPv6。
    【解决方案7】:

    添加以下权限。

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

    WifiManager 在 onCreate 中初始化。

     WifiManager wifiMgr = (WifiManager) getContext().getSystemService(context.WIFI_SERVICE);
    

    使用以下函数。

     public void WI-FI_IP() {
        WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
        int ip = wifiInfo.getIpAddress();
        String ipAddress = Formatter.formatIpAddress(ip);
        }
    

    【讨论】:

      【解决方案8】:

      找到了这个不错的答案,https://gist.github.com/stickupkid/1250733

      WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
      WifiInfo wifiInfo = wifiManager.getConnectionInfo();
      int ipAddress = wifiInfo.getIpAddress();
      String ipString = String.format(“%d.%d.%d.%d”, (ip & 0xff), (ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff));
      

      【讨论】:

        【解决方案9】:

        以下代码来自 AOSP 设置。它获取活动链接的 ip,无论是 wifi 还是移动设备。这是最常见的方式。

        http://androidxref.com/8.0.0_r4/xref/packages/apps/Settings/src/com/android/settings/deviceinfo/Status.java#251

        /**  
         * Returns the default link's IP addresses, if any, taking into account IPv4 and IPv6 style
         * addresses.
         * @param context the application context
         * @return the formatted and newline-separated IP addresses, or null if none.
         */
        public static String getDefaultIpAddresses(ConnectivityManager cm) {                                                                      
            LinkProperties prop = cm.getActiveLinkProperties();
            return formatIpAddresses(prop);
        }    
        
        private static String formatIpAddresses(LinkProperties prop) {
            if (prop == null) return null;
            Iterator<InetAddress> iter = prop.getAllAddresses().iterator();
            // If there are no entries, return null
            if (!iter.hasNext()) return null;
            // Concatenate all available addresses, comma separated
            String addresses = "";
            while (iter.hasNext()) {
                addresses += iter.next().getHostAddress();
                if (iter.hasNext()) addresses += "\n";
            }
            return addresses;
        }
        

        【讨论】:

          猜你喜欢
          • 2014-05-25
          • 2013-12-14
          • 2023-03-03
          • 2012-05-27
          • 1970-01-01
          • 1970-01-01
          • 2010-10-29
          • 1970-01-01
          • 2011-12-20
          相关资源
          最近更新 更多