Android获取提供热点的设备的IP地址

24

我目前正在使用

public static String getLocalIPAddress(WifiManager wm){
    return Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
}

获取执行设备的IP地址。如果该设备连接到“常规”无线局域网,或者连接到由其他Android设备通过热点提供的Wifi网络,则可以正常工作。如果该设备未连接到任何Wifi网络,则返回“0.0.0.0”(正确)。但是,如果该设备通过提供热点来托管Wifi网络,则该方法仍然返回“0.0.0.0”。如何在其自己的Wifi网络中获取提供热点的设备的真实IP地址?

谢谢 & 问候

6个回答

35

你几乎是正确的,热点的默认IP地址是192.168.43.1(如果设备制造商没有更改)。

您可以检查Android框架(AOSP)的源代码。

/ frameworks / base / services / java / com / android / server / connectivity / Tethering.java / frameworks / base / wifi / java / android / net / wifi / WifiStateMachine.java

在Tethering.java文件中,

private static final String USB_NEAR_IFACE_ADDR      = "192.168.42.129";
private static final int USB_PREFIX_LENGTH        = 24;

// USB is  192.168.42.1 and 255.255.255.0
// Wifi is 192.168.43.1 and 255.255.255.0
// BT is limited to max default of 5 connections. 192.168.44.1 to 192.168.48.1
// with 255.255.255.0

private String[] mDhcpRange;
private static final String[] DHCP_DEFAULT_RANGE = {
    "192.168.42.2", "192.168.42.254", "192.168.43.2", "192.168.43.254",
    "192.168.44.2", "192.168.44.254", "192.168.45.2", "192.168.45.254",
    "192.168.46.2", "192.168.46.254", "192.168.47.2", "192.168.47.254",
    "192.168.48.2", "192.168.48.254",
};

另外,在WifiStateMachine.java文件中

private boolean startTethering(ArrayList<String> available) {                                 

    boolean wifiAvailable = false;                                                            

    checkAndSetConnectivityInstance();                                                        

    String[] wifiRegexs = mCm.getTetherableWifiRegexs();                                      

    for (String intf : available) {                                                           
        for (String regex : wifiRegexs) {                                                     
            if (intf.matches(regex)) {                                                        

                InterfaceConfiguration ifcg = null;                                           
                try {                                                                         
                    ifcg = mNwService.getInterfaceConfig(intf);                               
                    if (ifcg != null) {                                                       
                        /* IP/netmask: 192.168.43.1/255.255.255.0 */                          
                        ifcg.setLinkAddress(new LinkAddress(                                  
                                NetworkUtils.numericToInetAddress("192.168.43.1"), 24));      
                        ifcg.setInterfaceUp();                                                

                        mNwService.setInterfaceConfig(intf, ifcg);                            
                    }                                                                         
                } catch (Exception e) {                                                       
                    loge("Error configuring interface " + intf + ", :" + e);                  
                    return false;                                                             
                }                                                                             

                if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {           
                    loge("Error tethering on " + intf);                                       
                    return false;                                                             
                }                                                                             
                mTetherInterfaceName = intf;                                                  
                return true;                                                                  
            }                                                                                 
        }                                                                                     
    }                                                                                         
    // We found no interfaces to tether                                                       
    return false;                                                                             
}   
因此,默认值为 192.168.43.1

1
@Gaucho,是的,它不能解决问题,但是对于这个问题没有官方API。即使使用反射技术,几乎不可能在几乎所有设备上访问该方法。因此,我们需要选择最可能的硬编码IP地址。 - Seongeun So
2
@SeongeunSo 在motoG设备上默认值运行良好,但在nexus上会有所不同。您能告诉我如何评估wifi热点的ip地址吗? - Ramesh Akula
1
@RameshAkula,你找到答案了吗?我也遇到了同样的问题,Moto E可以正常工作,但Nexus就不行。 - Rohit Singh

18

我测试了几个不同的设备,似乎提供热点的设备在其网络中始终具有IP 192.168.43.1。请有人检查/确认这个假设吗?


1
是的,默認的IP地址就是你提到的那一个,请也查看這個註釋。 - Lucky
1
是的,这是为提供Android设备热点的默认IP地址。 - Mutai Mwiti
1
是的,我用几个设备检查过了。默认IP非常完美。 - Vrajesh
是的,默認 IP 與您提到的相同。 - ANUJ TAYAL
1
不,对我来说它总是在变化。它的格式为192.168.43.*。 - Lokesh
在Android 9之前,IP地址是硬编码的。但是之后,它是随机的。来源:此答案 - s.ouchene

10

虽然这是一个老问题,但这可能会帮助到某些人。只要你打开了热点,它将返回您设备的IP地址。

private String getIpAddress() {
    String ip = "";
    try {
        Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
                .getNetworkInterfaces();
        while (enumNetworkInterfaces.hasMoreElements()) {
            NetworkInterface networkInterface = enumNetworkInterfaces
                    .nextElement();
            Enumeration<InetAddress> enumInetAddress = networkInterface
                    .getInetAddresses();
            while (enumInetAddress.hasMoreElements()) {
                InetAddress inetAddress = enumInetAddress.nextElement();

                if (inetAddress.isSiteLocalAddress()) {
                    ip += "SiteLocalAddress: "
                            + inetAddress.getHostAddress() + "\n";
                }
            }
        }

    } catch (SocketException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        ip += "Something Wrong! " + e.toString() + "\n";
    }
    return ip;
}

这个解决方案可行。我现在在我的应用程序中使用它,只做了一些小修改。 - Umer Farooq

3
热点很可能作为DHCP服务器。因此,

在连接到热点后,调用远程客户端的方法以获取wifi热点的IP地址(服务器)

intToInetAddress(wifiManager.getDhcpInfo().serverAddress);// get hotspot ip

然后
public InetAddress intToInetAddress(int hostAddress) 
{
    byte[] addressBytes = {(byte) (0xff & hostAddress),
            (byte) (0xff & (hostAddress >> 8)),
            (byte) (0xff & (hostAddress >> 16)),
            (byte) (0xff & (hostAddress >> 24))};

    try 
    {
        return InetAddress.getByAddress(addressBytes);
    } 
    catch (UnknownHostException e) 
    {
        throw new AssertionError();
    }
}

将返回已连接热点的IP地址,大多数默认的热点IP地址是192.168.43.1


9
楼主询问如何获取热点的本地Wifi IP地址。从客户端调用getDhcpInfo没有帮助。 - Jinghao Shi
1
前面的发言者所说的话。 - varnie

3
打开 Termux 并运行
ip -4 route get 8.8.8.8 | grep via

你将看到类似于这样的内容:
8.8.8.8 via 192.168.43.248 dev wlan0 table 1030 src 192.168.43.20 uid 12345

不需要安装net-tools来使用ifconfig命令..但是因为使用termux而+1 :) - Krishna
@सत्यमेवजयते 不错的观点... 但 ifconfig 可能会从未来版本的 Android 中删除。我没有看到 iproute2 被删除的情况... 我已经更新了它并使用了 iproute2。我真爱安卓。 - Ray Foss
这真的很有用。谢谢。 - imperial-lord

0

我也检查了几个设备,所有设备的IP地址都是192.168.43.1。你可以尝试使用这个地址,但在Android Pie中它变成了192.168.43.68。


我的 Android 6 设备使用 192.168.43.163。 - Juanpa

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