简体   繁体   English

如何在Android中获取wifi热点的IP?

[英]how to get the IP of the wifi hotspot in Android?

As the title says... I'm trying to be able to get the IP of the wifi iface when it is configured as hotspot.正如标题所说......当它被配置为热点时,我试图能够获得wifi iface的IP。 Ideally, I would like to find something that works for all the phones.理想情况下,我想找到适用于所有手机的东西。

Of course, the WifiManager is useless when it comes to get info from the AP.当然,WifiManager 在从 AP 获取信息时是无用的。

Luckily, I've been able to get the IPs of all the interfaces by doing this:幸运的是,通过这样做,我已经能够获得所有接口的 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;
}

This chunk of code will print all the IP of all the interfaces (Wifi hotspot included).这段代码将打印所有接口的所有 IP(包括 Wifi 热点)。 The main problem is that I don't find a way to identify the WiFi interface.主要问题是我没有找到识别WiFi接口的方法。 This is an issue since some phones have multiple interfaces (WiMax, etc).这是一个问题,因为某些电话具有多个接口(WiMax 等)。 This is what I've tried so far:这是我迄今为止尝试过的:

  • Filtering by the wifi iface display name: it's not a good approach because the display name changes from one device to another (wlan0, eth0, wl0.1, etc).按 wifi iface 显示名称过滤:这不是一个好方法,因为显示名称从一个设备更改为另一个(wlan0、eth0、wl0.1 等)。
  • Filtering by its mac address: almost work, but on some devices the hotspot iface does not have a MAC address ( iface.getHardwareAddress() returns null)...so not a valid solution.按其 mac 地址过滤:几乎可以工作,但在某些设备上,热点 iface 没有 MAC 地址( iface.getHardwareAddress() 返回 null)...所以不是有效的解决方案。

Any suggestions?有什么建议?

Here's what I did to get the wifi hotspot ip:这是我为获取 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;
}

This will give you the IP address of any wifi device, which means it's not just for the hotspot.这将为您提供任何wifi 设备的 IP 地址,这意味着它不仅适用于热点。 If you're connected to another wifi network (meaning you're not in hotspot mode), it'll return an IP.如果您连接到另一个 wifi 网络(意味着您未处于热点模式),它将返回一个 IP。

You should check if you are in AP mode first or not.您应该先检查您是否处于 AP 模式。 You can use this class for that: http://www.whitebyte.info/android/android-wifi-hotspot-manager-class你可以使用这个类: http : //www.whitebyte.info/android/android-wifi-hotspot-manager-class

You can use this.你可以用这个。

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

Full Code完整代码

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;

}

When the Wifi is not setup as a hotspot, it has a name android-xx7632x324x32423 home when hotspot is turned on, that name is gone.当 Wifi 未设置为热点时,当热点打开时,它的名称为android-xx7632x324x32423 home,该名称消失了。 Also the ip address changes. ip地址也变了。

So if you are able to get the Wifi config before enabling the hotspot, first of all you can use intf.getName() to get a reference to it.因此,如果您能够在启用热点之前获取 Wifi 配置,首先您可以使用intf.getName()获取对它的引用。

Second, the ip changed, so if you know which interface the wifi is in CONNECTED mode, you can use that info to identify it later on after enabling the hotspot.其次,ip 改变了,所以如果你知道 wifi 处于CONNECTED模式的哪个接口,你可以在启用热点后使用该信息来识别它。

Below is some code I used for debugging.下面是我用于调试的一些代码。 I just spit out everything I can find, make a huge mess then clean it up when I figured my problem out.我只是吐出我能找到的所有东西,弄得一团糟,然后在我解决问题时将其清理干净。 GL GL

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

I use the solution of ajma, changing intf.getName().contains("wlan") to intf.getName().contains("wl") || intf.getName().contains("ap")我使用ajma的解决方案,将intf.getName().contains("wlan")改为intf.getName().contains("wl") || intf.getName().contains("ap") intf.getName().contains("wl") || intf.getName().contains("ap") . intf.getName().contains("wl") || intf.getName().contains("ap") And it works for many mobile phones.它适用于许多手机。

But it returns null when you just connected to a WiFi.但是当您刚刚连接到 WiFi 时它返回 null。

With the number of new phones coming out every year from new manufacturers simply identifying the name of the wireless interface is bound to fail in the nearest future.随着新制造商每年推出的新手机数量不断增加,仅仅识别无线接口的名称在不久的将来肯定会失败。 The following method can get the remote server ip from the integer ip returned by getDhcpInfo().serverAddress.下面的方法可以从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 "";
}

Then you can use it like this from the activity where you use the WiFi service然后您可以在使用 WiFi 服务的活动中像这样使用它

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

This should show you the IP of the connected server.这应该会显示所连接服务器的 IP。

NOTE: ensure you have already created a successful connection to an access point (eg hotspot) via WiFi before querying for the server ip.注意:在查询服务器 IP 之前,请确保您已经通过 WiFi 成功创建了到接入点(例如热点)的连接。 You only need the SSID and preSharedkey (if it's secure) to create a successful connection and not the server ip.您只需要 SSID 和 preSharedkey(如果它是安全的)来创建成功的连接,而不是服务器 ip。

Here is a possible solution that utilizes WiFiManager ConnectionInfo to find corresponding NetworkInterface .这是一个可能的解决方案,它利用WiFiManager ConnectionInfo来查找相应的NetworkInterface

If you just need the IP then you can use:如果您只需要IP,那么您可以使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM