【问题标题】:Android API-23: InetAddressUtils replacementAndroid API-23:InetAddressUtils 替换
【发布时间】:2015-11-15 11:38:31
【问题描述】:

切换到 Android Marshmallow API,我在代码中使用 org.apache.http.conn.util.InetAddressUtils 代替 InetAddressUtils.isIPv4Address(ipAddress) 来列出设备中的所有 IP。

作为API-23 changes 的一部分,InetAddressUtils 类现已消失。

我现在如何替换下面的代码?

public static String ipAddress() {
    try {
        for (final Enumeration<NetworkInterface> enumerationNetworkInterface = NetworkInterface.getNetworkInterfaces(); enumerationNetworkInterface.hasMoreElements();) {
            final NetworkInterface networkInterface = enumerationNetworkInterface.nextElement();
            for (Enumeration<InetAddress> enumerationInetAddress = networkInterface.getInetAddresses(); enumerationInetAddress.hasMoreElements();) {
                final InetAddress inetAddress = enumerationInetAddress.nextElement();
                final String ipAddress = inetAddress.getHostAddress();
                if (! inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ipAddress)) {
                    return ipAddress;
                }
            }
        }
        return null;
    }
    catch (final Exception e) {
        LogHelper.wtf(null, e);
        return null;
    }
}

【问题讨论】:

  • 你想做什么?如果您只是想知道 IP 是否为 IPv6,您可以检查 inetAddress instancof Inet6AddressinetAddress instancof Inet4Address
  • 我正在尝试用适用于 Android API-23 的代码替换 InetAddressUtils.isIPv4Address(ipAddress)
  • 正如它的名字所说:如果IP地址是IPv4或者不是IPv4返回hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…这个方法现在在Android API-23中不可用。我只是想替换它,但我还不知道任何替代品。

标签: android android-networking android-6.0-marshmallow


【解决方案1】:

就像我从 cmets 中解释的那样,您可以用这个比较替换那个函数:

inetAddress instanceof Inet4Address

所以你的代码将以:

结尾
if(!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {

2020 年更新
请记住,您的用户也可以启用 IPv6。在这种情况下,您也需要检查 Inet6Address

【讨论】:

  • 嗯,确实InetAddressUtils 已从Android 的API-23 中消失,但Inet4Address 没有。感谢您的解决方法。
  • 或者你也可以这样做:Inet4Address.class.isInstance(inetAddress)
  • @maňish: 导入 java.net.Inet4Address
【解决方案2】:

我找不到比转换为 Inet4Address 或 Inet6Address 更好的方法

public boolean isValidIp4Address(final String hostName) {
      try {
         return Inet4Address.getByName(hostName) != null;
     } catch (UnknownHostException ex) {
         return false;
     } 
}

public boolean isValidIp6Address(final String hostName) {
      try {
         return Inet6Address.getByName(hostName) != null;
     } catch (UnknownHostException ex) {
         return false;
     } 
}

请注意,getHostByName 实际上会进行查找,这并不总是可取的。

或者,您可以获得InetAddessUtils 的来源,与getByName() 不同,它不进行查找,但只接受点地址。代码真的很小。它使用 Android 支持的正则表达式类。只需删除不重要的 Immutable 注解,它就会编译!

【讨论】:

  • getByName() 在我看来就像继承自 InetAddress
【解决方案3】:

使用 try catch 作为逻辑是可怕的做法,只有在完全不可避免的情况下才应该这样做..

改用这样的东西:

if (inetAddress instanceof Inet4Address){
    //do something
}  

【讨论】:

    【解决方案4】:

    要在 SDK 23 中使用此库,请在项目的 build.gradle 文件中添加以下行:

    useLibrary 'org.apache.http.legacy'
    

    【讨论】:

    • 这也将使遗留代码工作。但是,我正在寻找替代品,而不必依赖整个遗产来实现此功能。其他人可能正在寻找此解决方案,但已投票赞成。
    【解决方案5】:

    将以下内容添加到您的 build.gradle(Module:app) 文件中,

    机器人{ useLibrary 'org.apache.http.legacy' }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多