Android API-23: InetAddressUtils替代方案

19

转向Android Marshmallow API后,我在代码中使用org.apache.http.conn.util.InetAddressUtilsInetAddressUtils.isIPv4Address(ipAddress)来列出设备中的所有IP地址。

作为API-23更改的一部分,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;
    }
}

1
你想做什么?如果你只是想知道一个IP地址是否为IPv6,你可以检查 inetAddress instanceof Inet6Address 或者 inetAddress instanceof Inet4Address - rekire
我正在尝试用适用于Android API-23的代码替换InetAddressUtils.isIPv4Address(ipAddress) - shkschneider
如其名称所示:返回IP地址是否为IPv4 https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/conn/util/InetAddressUtils.html#isIPv4Address(java.lang.String) 此方法在Android API-23中已不再可用。我只想替换它,但目前还不知道有什么替代方案。 - shkschneider
5个回答

26

根据评论所解释的,您可以使用以下比较替换该函数:

inetAddress instanceof Inet4Address

所以你的代码应该以此结束:

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

2020年更新:
请注意,您的用户可能还启用了IPv6。在这种情况下,您还需要检查Inet6Address


1
确实,InetAddressUtils 已经从 Android 的 API-23 中删除了,但 Inet4Address 并没有。感谢提供解决方法。 - shkschneider
或者你也可以这样做:Inet4Address.class.isInstance(inetAddress)。 - Bostone
@maňish:import java.net.Inet4Address - cesargastonec

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

android { useLibrary 'org.apache.http.legacy' }

这将使用“org.apache.http.legacy”库,以便在应用程序中使用HTTP客户端功能。

4
我找不到比转换为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 继承而来的。 - shkschneider

3
在SDK 23中使用此库,请在项目的build.gradle文件中添加以下行:
useLibrary 'org.apache.http.legacy'

这也可以让旧代码工作。但是我正在寻找一种替代方案,而不是依赖整个遗留系统来实现此功能。其他人可能正在寻找这个解决方案,已经点赞了。 - shkschneider

1

使用try catch作为逻辑是可怕的实践,只有在绝对避免不了的情况下才应该这样做。

相反,应该使用类似于以下的方法:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接