【问题标题】:how to get the IP of the wifi hotspot in Android?如何在Android中获取wifi热点的IP?
【发布时间】:2012-03-23 07:28:27
【问题描述】:

正如标题所说...当wifi iface配置为热点时,我试图能够获取它的IP。理想情况下,我想找到适用于所有手机的东西。

当然,WifiManager 在从 AP 获取信息时是无用的。

幸运的是,我已经能够通过这样做获得所有接口的 IP:

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()) {
                    Log.d("IPs", inetAddress.getHostAddress() );
                }
            }
        }
    } catch (SocketException ex) {
        Log.e(LOG_TAG, ex.toString());
    }
    return null;
}

这段代码将打印所有接口的所有 IP(包括 Wifi 热点)。主要问题是我没有找到识别WiFi接口的方法。这是一个问题,因为有些电话有多个接口(WiMax 等)。这是我迄今为止尝试过的:

  • 按 wifi iface 显示名称过滤:这不是一个好方法,因为显示名称会从一个设备更改为另一个设备(wlan0、eth0、wl0.1 等)。
  • 按其 MAC 地址过滤:几乎可以工作,但在某些设备上,热点 iface 没有 MAC 地址(iface.getHardwareAddress() 返回 null)...所以不是有效的解决方案。

有什么建议吗?

【问题讨论】:

    标签: java android wifi android-wifi


    【解决方案1】:

    你可以用这个。

    ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE)).getDhcpInfo().serverAddress
    

    完整代码

    private String getHotspotIPAddress() {
    
        int ipAddress = mContext.getSystemService(Context.WIFI_SERVICE)).getDhcpInfo().serverAddress;
    
        if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
            ipAddress = Integer.reverseBytes(ipAddress);
        }
    
        byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray();
    
        String ipAddressString;
        try {
            ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress();
        } catch (UnknownHostException ex) {
            ipAddressString = "";
        }
    
        return ipAddressString;
    
    }
    

    【讨论】:

      【解决方案2】:

      随着新制造商每年推出的新手机数量不断增加,仅仅识别无线接口的名称在不久的将来肯定会失败。下面的方法可以从getDhcpInfo().serverAddress返回的整数ip中获取远程服务器ip。

      public String getIPv4Address(int ipAddress) {
          // convert integer ip to a byte array
          byte[] tempAddress = BigInteger.valueOf(ipAddress).toByteArray();
          int size = tempAddress.length;
          // reverse the content of the byte array
          for(int i = 0; i < size/2; i++) {
              byte temp = tempAddress[size-1-i];
              tempAddress[size-1-i] = tempAddress[i];
              tempAddress[i] = temp;
          }
          try {
              // get the IPv4 formatted ip from the reversed byte array
              InetAddress inetIP = InetAddress.getByAddress(tempAddress);
              return inetIP.getHostAddress();
          } catch (UnknownHostException e) {
              e.printStackTrace();
          }
          return "";
      }
      

      那么你就可以在你使用WiFi服务的activity中这样使用它了

      WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
      String serverIp = getIPv4Address(wifi.getDhcpInfo().serverAddress);
      Log.v("Server Ip", serverIp);
      

      这应该会显示连接服务器的 IP。

      注意:在查询服务器 IP 之前,请确保您已经通过 WiFi 创建了与接入点(例如热点)的成功连接。您只需要 SSID 和 preSharedkey(如果它是安全的)来创建成功的连接,而不是服务器 ip。

      【讨论】:

        【解决方案3】:

        我使用ajma的解决方案,将intf.getName().contains("wlan")改为intf.getName().contains("wl") || intf.getName().contains("ap")。它适用于许多手机。

        但当您刚刚连接到 WiFi 时,它会返回 null。

        【讨论】:

          【解决方案4】:
          private static byte[] convert2Bytes(int hostAddress) {
              byte[] addressBytes = { (byte)(0xff & hostAddress),
                      (byte)(0xff & (hostAddress >> 8)),
                      (byte)(0xff & (hostAddress >> 16)),
                      (byte)(0xff & (hostAddress >> 24)) };
              return addressBytes;
          }
          
          public static String getApIpAddr(Context context) {
              WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
              DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();
              byte[] ipAddress = convert2Bytes(dhcpInfo.serverAddress);
              try {
                  String apIpAddr = InetAddress.getByAddress(ipAddress).getHostAddress();
                  return apIpAddr;
              } catch (UnknownHostException e) {
                  e.printStackTrace();
              }
              return null;
          }
          

          【讨论】:

          • 为代码添加一些解释会很棒
          【解决方案5】:

          这是我为获取 wifi 热点 ip 所做的:

          public String getWifiApIpAddress() {
              try {
                  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)) {
                                  Log.d(TAG, inetAddress.getHostAddress());
                                  return inetAddress.getHostAddress();
                              }
                          }
                      }
                  }
              } catch (SocketException ex) {
                  Log.e(TAG, ex.toString());
              }
              return null;
          }
          

          这将为您提供任何 wifi 设备的IP 地址,这意味着它不仅适用于热点。如果您连接到另一个 wifi 网络(意味着您未处于热点模式),它将返回一个 IP。

          您应该先检查您是否处于 AP 模式。你可以使用这个类:http://www.whitebyte.info/android/android-wifi-hotspot-manager-class

          【讨论】:

          • 嗨@ajma,感谢分享这个有价值的代码,这是有效的,并为我提供“WiFi 简单路由器网络”和“WiFi 网络共享或热点”的 IP 地址。
          • 这不是 100% 正确的。我发现网络接口名称变化很大。 HTC Desire Z:wl0.1;声望 3540:ap0; Nexus 5/三星 DUOS:wlan0。另一方面,在所有情况下都只列出了一个设备(没有环回等)。
          • 此代码不适用于接口命名为 ap0 的某些设备。我建议进行以下更正: if ((intf.getName().contains("wlan")) ||(intf.getName().contains("ap"))) { 在我的手机上有一个接口 wlan0 但它没有inet地址,因为ip地址在ap0上。在我的情况下,我也有环回接口。当它连接到 wifi 路由器时,它使用 wlan0。
          【解决方案6】:

          当 Wifi 没有设置为热点时,它有一个名称android-xx7632x324x32423home 打开热点后,该名称就消失了。 ip地址也会改变。

          因此,如果您能够在启用热点之前获取 Wifi 配置,首先您可以使用intf.getName() 获取对它的引用。

          其次,ip改变了,所以如果你知道wifi在CONNECTED模式下的哪个接口,你可以在启用热点之后使用该信息来识别它。

          以下是我用于调试的一些代码。我只是吐出我能找到的所有东西,弄得一团糟,然后当我发现我的问题时清理它。总账

          import java.net.InetAddress;
          import java.net.NetworkInterface;
          import java.util.Collections;
          import android.net.ConnectivityManager;
          
          textStatus = (TextView) findViewById(R.id.textStatus);
          
          try {
            for (NetworkInterface intf : Collections.list(NetworkInterface.getNetworkInterfaces())) {
              for (InetAddress addr : Collections.list(intf.getInetAddresses())) {
                if (!addr.isLoopbackAddress()){
                  textStatus.append("\n\n IP Address: " + addr.getHostAddress() );
                  textStatus.append("\n" + addr.getHostName() );
                  textStatus.append("\n" + addr.getCanonicalHostName() );
                  textStatus.append("\n\n" + intf.toString() );
                  textStatus.append("\n\n" + intf.getName() );
                  textStatus.append("\n\n" + intf.isUp() );
                } 
              }
            }
          } catch (Exception ex) {
            textStatus.append("\n\n Error getting IP address: " + ex.getLocalizedMessage() );
          }
          
          
          connectivity = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
          allInfo = connectivity.getAllNetworkInfo();
          mobileInfo = connectivity.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
          
          textStatus.append("\n\n TypeName: " + mobileInfo.getTypeName());
          textStatus.append("\n State: " + mobileInfo.getState());
          textStatus.append("\n Subtype: " + mobileInfo.getSubtype());
          textStatus.append("\n SubtypeName: " + mobileInfo.getSubtypeName());
          textStatus.append("\n Type: " + mobileInfo.getType());
          textStatus.append("\n ConnectedOrConnecting: " + mobileInfo.isConnectedOrConnecting());
          textStatus.append("\n DetailedState: " + mobileInfo.getDetailedState());
          textStatus.append("\n ExtraInfo: " + mobileInfo.getExtraInfo());
          textStatus.append("\n Reason: " + mobileInfo.getReason());
          textStatus.append("\n Failover: " + mobileInfo.isFailover());
          textStatus.append("\n Roaming: " + mobileInfo.isRoaming()); 
          
          textStatus.append("\n\n 0: " + allInfo[0].toString());
          textStatus.append("\n\n 1: " + allInfo[1].toString());
          textStatus.append("\n\n 2: " + allInfo[2].toString());
          

          【讨论】:

            【解决方案7】:

            这是一个可能的solution,它利用WiFiManager ConnectionInfo 来查找对应的NetworkInterface

            如果你只需要IP,那么你可以使用:

            WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            int ipAddress = wifiInfo.getIpAddress();
            

            【讨论】:

            • 很抱歉,但这不是解决方案。正如我之前所说,当iface处于AP模式时,WifiManager是无用的。 Android“认为”Wifi被禁用。另一方面,我尝试了与您提供的解决方案类似的方法,但使用的是 MAC 地址而不是 IP。但正如我已经指出的那样,它不起作用。由于某种原因,wifi iface 的 mac 地址为空(在某些设备中)。
            • 是的,是的。相信我,这种方法行不通。如果你愿意,你可以试试.. :/
            • 你好,我的解决方案是打开热点并显示“假对话框”来通知用户,然后在获得 ipaddress 时关闭 :)
            猜你喜欢
            • 2011-09-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-04
            • 1970-01-01
            • 1970-01-01
            • 2011-11-27
            • 1970-01-01
            相关资源
            最近更新 更多