返回Android NetworkInterface的内部IP

3

我正在使用代码获取我的设备正在使用的IPv4地址:

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().toUpperCase();
                    boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr); 
                    if (useIPv4) {
                        if (isIPv4) 
                            return sAddr;
                    } else {
                        if (!isIPv4) {
                            int delim = sAddr.indexOf('%'); // drop ip6 port suffix
                            return delim<0 ? sAddr : sAddr.substring(0, delim);
                        }
                    }
                }
            }
        }
    } catch (Exception ex) { } // for now eat exceptions
    return "";
}

我的三星Galaxy Express已连接WiFi,并带有启用蜂窝数据的sim卡。
上面代码返回的IP地址是10.地址,这表明手机正在使用蜂窝信号,而我需要它使用网络可用的192.地址。
是否有一种方法可以修改上面的代码以选择可用的192.地址?还是手机出了问题?
我尝试过禁用移动网络,将其置于飞行模式等等。
唯一有效的方法是拆下SIM卡! 我不能指望用户这样做只是为了获取内部地址?
谢谢

1
嗯,你有没有尝试检查所有接口?除非那是回环接口,否则你的代码会忽略除第一个以外的任何内容。 - CommonsWare
我现在有一段代码,可以将所有IP地址放入一个列表中,其中包括192.地址。但是,如果可用,我想自动挑选出这个IP。有许多方法可以在数组中查找项目的索引,但我想根据半匹配来查找该项。例如,我希望在数组中搜索“192”不会返回-1,而是返回完整的192地址所在的位置,这样说您明白吗? - Dan
不好意思,那并没有什么意义。我在解释你的问题时遇到了一些困难。 - CommonsWare
1
@DanJamesPalmer - 如果您在代码中硬编码了对值“192”的依赖,那么这是错误的做法。一些WiFi路由器使用“10.x.y.z”地址范围,而其他一些则使用“172.x.y.z”。我在下面给出了一些代码来识别wlan0适配器的IP地址。您可能需要修改它以过滤掉要避免的接口,而不是尝试猜测WiFi适配器。但是让我问一下:您真正想做什么?也就是说,为什么您需要首先发现自己的本地IP地址?可能有更好的方法来获得您所需的内容。 - selbie
请注意,如果有活动的WiFi连接,您的应用程序的互联网操作将通过WiFi进行,因此您不需要IP地址。 - CommonsWare
1个回答

4

我很想知道是否有更好的方法...

但现在,寻找"wlan0"地址。此外,下面的代码将为您过滤掉回环地址。

List<NetworkInterface> interfaces;
try {
    interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
    for (NetworkInterface ni : interfaces)
    {
        if ((ni.isLoopback() == false) && ni.isUp() && (ni.getName().equals("wlan0")))
        {

            // enumerate ip addresses on this network interface (e.g. ni.getInetAddresses()

            // return the first one that is is Ipv4

        }
    }

你需要将上述代码与 android.net.ConnectivityManager 的调用结合起来确认你是否连接到 wifi。

请注意,该算法在使用以太网(例如 OUYA、Android TV)等设备和其他场景时可能会出现问题。依赖于 wlan0 是正确的名称是有风险的。话虽如此,我不知道是否有更好的解决方案。 - CommonsWare
@CommonsWare - 我完全同意。理想情况下,找到最佳接口(和IP)的最好方法是枚举路由表并查找所有目标地址列中为0.0.0.0的行,并选择具有最低度量值的行(并使用该选择的IFace列)。这可以通过降级到NDK并进行所有常规的Linux / Unix系统调用来实现。 - selbie
但是楼主说他想要Wifi地址,不一定是最佳地址。我已经在他的问题评论中询问了楼主他真正想做什么。 - selbie

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