2014-02-15 50 views
10

我需要在主持热点时查找设备的IP地址。我目前使用此代码:Android在主持热点时查找设备的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名在某些设备上的不同。所以我必须首先找到该设备的名称(为其热点)。我怎样才能找到这个名字?还是有更好的方法来找到设备的IP地址?

///查找由MAC正确的IP地址也似乎不工作

回答

8

最近,我想通了,在WifiAP IP地址采用的是Android硬编码。除非用户手动更改此值(我认为这种情况非常少见),但使用硬编码值是绝对足够的。我认为这是最好的选择。 IP地址是“192.168.43.1”:https://github.com/CyanogenMod/android_frameworks_base/blob/cm-10.1/wifi/java/android/net/wifi/WifiStateMachine.java?source=c#L1299

+1

没有为我工作(在HTC One上)。当我设置一个Wifi热点时,我的手机的IP为192.168.1.1。我通过连接到Windows盒子的热点并通过'ipconfig/all'检查Wi-Fi网关IP,发现了这一点。 –

0

intf.getDisplayName()取代intf.getName(),然后尝试。

+0

引用自文档“返回此网络接口的人类可读名称**在Android上,这与getName()返回的字符串相同**” – flx

11

起初我试着去取WiFi接口的MAC地址,把它与每个接口的MAC地址进行比较。但事实证明,至少在运行CM的N4上,打开热点时,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

其它可能的解决方案:

走线槽一些最常用的接口的名字,并试图找到它们在列表中:在oncreat

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; 
    } 

写代码:new String[] { "wlan0", "eth0", ...];

+0

感谢代码共享。它拯救了我的一天。 –

+2

这个答案应该是被接受的答案 –

+0

即使我的hotsopt处于活动状态,这仍然会引发套接字异常。 – 2016-10-02 17:11:21

0

一旦试试这个代码检查,热点启用不是.....

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(); 
     } 
2

这可以帮助你。

制作的外壳打电话,要求网络适配器和检查,你需要像在这种情况下是无线局域网的那些所以按照这个代码

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(); 

附加注释

This image is the output of the command on the shell. 或者您可以使用Play商店中的Android Terminal Emulator来在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)); 
} 
+0

这不提供任何好处。它只缓存名为'wlanX'的设备。有设备命名那里wifi接口'ethX'。 – flx

+0

如果你需要别人,你只需要删除正则表达式中的wlan,但是如果你正确读取它,他需要wifi接口的名称。所以我很喜欢在它里面提到wlan。 – cafebabe1991

+0

好吧,问题是:我如何知道**哪些设备是wifi接口**。您的列表仅提供了通过'NetworkInterface.getNetworkInterfaces()'并查找以'wlan'开头的设备。但是这已经在OP中。 – 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

user2224350说:“我最近想通了,在WifiAP IP地址采用的是Android硬编码。”

除非用户手动更改此值(我认为这种情况非常罕见),但使用硬编码值是绝对足够的。我认为这是最好的选择。 IP地址是“192.168.43.1”,as seen here

这适用于我的三星A3和华为PRA-LX1,但HTC Desires 530也返回192.168.1.1