Android,在网络共享和连接到接入点时检测WiFi的本地IP和子网掩码 [英] Android, detect local IP and subnet mask for WiFi, both while tethering and connected to access point

查看:315
本文介绍了Android,在网络共享和连接到接入点时检测WiFi的本地IP和子网掩码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Android设备上检测WiFi网络上的本地IP地址和子网掩码(为了正确计算本地子网的UDP广播地址)。



当设备连接到接入点时,以下功能正常:

  //仅在不绑定时使用
WifiManager wifi =(WifiManager)context.getSystemService(Context.WIFI_SERVICE);

DhcpInfo dhcp = wifi.getDhcpInfo();
if(dhcp == null)
抛出新的IOException(WiFi端没有DHCPInfo。);

foo(dhcp.ipAddress,dhcp.netmask);

但是当它通过网络共享提供接入点的Android设备时它不起作用:DhcpInfo似乎包含当Android设备是其客户端时由DCHP服务器设置的信息,而不是当Android设备本身提供DHCP服务时。在束缚时,我能找到的最有希望的解决方案是:

  //无法获得子网掩码
WifiManager wifi =(WifiManager)context.getSystemService(Context.WIFI_SERVICE);

WifiInfo info = wifi.getConnectionInfo();
if(info == null)
抛出新的IOException(WiFi端没有连接信息。);

foo(info.getIpAddress(),info。??? / * netmask * /);

编辑:错误,在我的测试中,即使这只适用于不绑定。虽然网络绑定总是为0。



但是没有像 WifiInfo.getNetMask(),我怎么能得到在那种情况下的子网掩码? (这种缺席让我觉得非常奇怪,因为那里有太多的其他信息。我错过了一些明显的东西吗?)



另外,理想情况下我想要一个解决方案不需要区分Android设备是否提供网络共享,只需在WiFi网络上获取本地IP地址和子网掩码,无论如何,无论是Android设备提供还是接入点的客户端。 / p>

即使是标准的Java(即不是特定于Android的) NetworkInterface.getNetworkInterfaces(),似乎也没有获得子网掩码的方法(除了不允许区分哪个对应于WiFi)。我缺少什么?

解决方案

我现在找到的最佳解决方案:



令我感到困惑的是,关于网络共享的信息/界面是如此繁琐/隐藏得到,但是当你从 WifiManager ConnectivityManager :只有当不在网络共享中时才会起作用。我实际上已经失去了调查分支。



我目前发现的最佳解决方案是使用标准Java NetworkInterface.getNetworkInterfaces(),而不是任何Android API。



从实验上来说,Android似乎足够聪明,可以为外部移动网络的网络接口设置为空广播即可。它实际上很有意义,因为Android默默地丢弃涉及外部移动网络的UDP广播。

  //这适用于网络共享和何时连接到接入点

枚举< NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

while(interfaces.hasMoreElements())
{
NetworkInterface networkInterface = interfaces.nextElement();

if(networkInterface.isLoopback())
继续; //不想广播到loopback接口

for(InterfaceAddress interfaceAddress:networkInterface.getInterfaceAddresses())
{
InetAddress broadcast = interfaceAddress.getBroadcast();

// InetAddress ip = interfaceAddress.getAddress();
// interfaceAddress.getNetworkPrefixLength()是表达子网掩码的另一种方式

// Android似乎很聪明,设置为
//外部移动网络的广播。这是有道理的,因为Android
//默默地丢弃涉及外部移动网络的UDP广播。
如果(广播== null)
继续;

... //使用广播
}
}

对于子网掩码, getNetworkPrefixLength()的结果可以强制转换为子网掩码。我直接使用 getBroadcast(),因为这是我的最终目标。



这似乎不需要特殊权限代码(没有 ACCESS_WIFI_STATE 也不是 NETWORK ,只是 INTERNET )。



代码片段的主要参考: http://enigma2eureka.blogspot.it/2009/08/finding-your-ip-v4-broadcast-address.html


I need to detect the local IP address and subnet mask on the WiFi network, on an Android device (in order to proper calculate the UDP broadcast address strictly for the local subnet).

When the device is connected to an Access Point, the following is properly working:

// Only works when NOT tethering
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

DhcpInfo dhcp = wifi.getDhcpInfo();
if (dhcp == null)
    throw new IOException("No DHCPInfo on WiFi side.");

foo(dhcp.ipAddress, dhcp.netmask);

But it doesn't work when it's the android device providing an Access Point though tethering: DhcpInfo seem to contain info set by the DCHP server when the Android device is a client of it, not when it's the Android device itself providing the DHCP service. When in tethering, the most promising solution I could find is:

// No way to get subnet mask
WifiManager wifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

WifiInfo info = wifi.getConnectionInfo();
if (info == null)
   throw new IOException("No connection info on WiFi side.");

foo(info.getIpAddress(), info.??? /* netmask*/ );

EDIT: WRONG, in my tests even this only works when NOT tethering. While tethering the IP is always 0.

But there's nothing like WifiInfo.getNetMask(), how can I get the subnet mask in that case? (This absence strikes me as really strange, since there's a plethora of other info there. Am I missing something obvious?)

Also, ideally I'd like a solution that doesn't need to discriminate if the Android device is providing tethering, and just get the local IP address and subnet mask, on the WiFi network, in any case, both when the Android device is providing or a client of an Access Point.

Even standard Java (i.e. not Android-specific) NetworkInterface.getNetworkInterfaces(), don't seem to have a way to get the subnet mask (apart from not allowing to discriminate which corresponds to the WiFi). What am I missing?

解决方案

Best solution I found at the moment:

It baffles me how info/interface about tethering is so cumbersome/hidden to get, and yet not taken into consideration when you get info from WifiManager, or ConnectivityManager for the Wifi type: it all works only when NOT in tethering. I'm actually lost to that branch of investigation.

Best solution I found at the moment is using standard Java NetworkInterface.getNetworkInterfaces(), instead of any Android API.

Experimentally, Android seems smart enough to set to null broadcast for network interfaces to the external mobile network. It actually makes lot of sense since Android silently drop UDP broadcasts involving external mobile network.

    // This works both in tethering and when connected to an Access Point

    Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();

    while (interfaces.hasMoreElements()) 
    {
        NetworkInterface networkInterface = interfaces.nextElement();

        if (networkInterface.isLoopback())
            continue; // Don't want to broadcast to the loopback interface

        for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) 
        {
                InetAddress broadcast = interfaceAddress.getBroadcast();

                // InetAddress ip = interfaceAddress.getAddress();                  
                // interfaceAddress.getNetworkPrefixLength() is another way to express subnet mask

                // Android seems smart enough to set to null broadcast to
                //  the external mobile network. It makes sense since Android
                //  silently drop UDP broadcasts involving external mobile network.
                if (broadcast == null)
                    continue;

                ... // Use the broadcast                
        }
    }

As for subnet mask, the result from getNetworkPrefixLength() can be coerced into a subnet mask. I used getBroadcast() directly since that was my ultimate goal.

No special permissions seem to be needed for this code (no ACCESS_WIFI_STATE nor NETWORK, just INTERNET).

Primary reference for the code snippet: http://enigma2eureka.blogspot.it/2009/08/finding-your-ip-v4-broadcast-address.html

这篇关于Android,在网络共享和连接到接入点时检测WiFi的本地IP和子网掩码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆