Android:在设备作为热点时查找其IP地址

10

当设备作为热点主机时,我需要找到设备的IP地址。到目前为止,我已经使用了以下代码:

//if is using Hotspot
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
    NetworkInterface intf = en.nextElement();
    if (intf.getName().contains("wlan")) {
        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
            InetAddress inetAddress = enumIpAddr.nextElement();
            if (!inetAddress.isLoopbackAddress() && (inetAddress.getAddress().length == 4)) {
                return inetAddress.getHostAddress();
            }
        }
    }
}

这个方法运行良好,但是在某些设备上wifi的NetworkInterface名称不同。因此我需要先找到设备的wifi NetworkInterface名称(用于其热点)。我该如何找到这个名称?或者有更好的方法来查找设备的IP地址吗?

/// 通过MAC地址查找正确的IP地址似乎也行不通。

7个回答

12

一开始,我试图获取WiFi接口的MAC地址,以将其与每个接口的MAC地址进行比较。但事实证明,在我的N4上运行CM时,打开热点时WiFi接口的MAC地址会发生变化。

因此,我编写了一些代码来遍历设备列表,找到用于识别WiFi接口的内容。这段代码在我的N4上完美运行:

private String getWifiIp() throws SocketException {
    for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
            en.hasMoreElements(); ) {
        NetworkInterface intf = en.nextElement();
        if (intf.isLoopback()) {
            continue;
        }
        if (intf.isVirtual()) {
            continue;
        }
        if (!intf.isUp()) {
            continue;
        }
        if (intf.isPointToPoint()) {
            continue;
        }
        if (intf.getHardwareAddress() == null) {
            continue;
        }
        for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses();
                enumIpAddr.hasMoreElements(); ) {
            InetAddress inetAddress = enumIpAddr.nextElement();
            if (inetAddress.getAddress().length == 4) {
                return inetAddress.getHostAddress();
            }
        }
    }
    return null;
}

只有一个接口符合所有条件:wlan0

可能的其他解决方案:

遍历一些最常见的接口名称,并尝试在列表中查找它们:new String[] {"wlan0", "eth0", ...};


即使我的热点处于活动状态,它仍会抛出套接字异常。 - user6649667

10

1
对我没用(在HTC One上)。当我设置一个Wifi热点时,我的手机获得了IP 192.168.1.1。我通过从Windows桌面连接到热点并通过“ipconfig / all”检查Wi-Fi网关IP来发现这一点。 - Adriaan Koster

2

这可以帮助你解决问题。

调用shell以请求网络适配器并检查需要的适配器,例如此例中的wlan,请按照以下代码操作:

Process p=Runtime.getRuntime().exec("ip link show | grep -o \": wlan[0-9]:\" ");

BufferedReader readCommandOutput = 
    new BufferedReader(new InputStreamReader(p.getInputStream()));

String line=null;
while((line=readCommandOutput.readLine())!=null){
    // Lines containing wlan will be returned
    // parse to get the name of that interface.
    String interface=line.split(":")[1];
    //this is the interface you need.
}

if (line==null){
    //nothing was found.
}

readCommandOutput.close();

附注

这张图片是在shell命令行上的输出。 或者你可以使用来自Play商店的Android终端模拟器,以便在Android shell中运行此命令。

获取IP地址

WifiManager wifi=(WifiManager)getSystemService(WIFI_SERVICE);
int address=wifi.getDhcpInfo().ipAddress;
Toast.makeText(this,intToIP(address),1).show();         


public String intToIP(int i) {
    return ((i & 0xFF) 
            + "." + ((i >> 8) & 0xFF)
            + "." + ((i >> 16) & 0xFF)
            + "." + ((i >> 24) & 0xFF));
 }

这并没有提供任何好处。它只缓存名为 wlanX 的设备。有些设备会将其无线接口命名为 ethX - flx
如果你需要其他的,只需在正则表达式中删除"wlan"即可。但是,如果你仔细阅读问题,他需要WiFi接口的名称。所以我在其中提到了"wlan"。 - cafebabe1991
好的,问题是:我如何知道哪个设备是wifi接口。您的列表只提供了通过NetworkInterface.getNetworkInterfaces()遍历并查找以wlan开头的设备。但这已经在OP中提到了。 - flx
这样回答可以帮助他找到“仅限WiFi接口”的解决方案。这就是我以wlan开头的原因。 - cafebabe1991
你的回答提供了与原帖完全相同的信息:以“wlan”开头的网络设备的IPv4地址。 - flx

1
这个解决方案适用于想要获取热点设备的IP地址,但不知道如何在连接的设备上获取时使用。通常服务器的IP地址为192.168.43.1,你可以通过硬编码来完成工作。
 public void serverip()

    {
     DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();
            if (dhcpInfo==null){
                Toast.makeText(MainActivity.this, "No ip for server", Toast.LENGTH_SHORT).show();
            }else{

                Toast.makeText(MainActivity.this, "ip of server "+android.text.format.Formatter.formatIpAddress(dhcpInfo.gateway), Toast.LENGTH_SHORT).show();
    }


            }

0

尝试这段代码:

public String getLocalIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {

                        String ip = Formatter.formatIpAddress(inetAddress.hashCode());
                        Toast.makeText(getApplicationContext(), "***** IP="+ ip, 1).show();

                        return ip;
                    }
                }
            }
        } catch (SocketException ex) {
            Toast.makeText(getApplicationContext(), "***** IP="+ex.toString(), 1).show();

        }
        return null;
    }

在onCreate中编写代码以检查热点是否已启用.....

WifiManager wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); 
        wifiManager.setWifiEnabled(true);
        wifiManager.setWifiEnabled(false);
        boolean wifiEnabled = wifiManager.isWifiEnabled();
        if (wifiEnabled) {
            Toast.makeText(getApplicationContext(),"on",Toast.LENGTH_SHORT).show();
            getLocalIpAddress();
        }else {
                Toast.makeText(getApplicationContext(),"off",Toast.LENGTH_SHORT).show();
        }

0
请将 intf.getName() 替换为 intf.getDisplayName() 然后再试一下。

文档中的引用:“返回此网络接口的可读名称。在Android上,这个字符串与getName()返回的字符串相同。” - flx

0

user2224350说:“我最近发现Android中的WifiAP IP地址是硬编码的。”

除非用户手动更改了此值(我认为这很少见),否则使用硬编码值绝对足够。我认为这是最好的方法。IP地址为“192.168.43.1”,如此看到

这在我的三星A3和华为PRA-LX1上有效,但HTC Desires 530也返回192.168.1.1


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