17

As the title says... I'm trying to be able to get the IP of the wifi iface when it is configured as hotspot. 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.

Luckily, I've been able to get the IPs of all the interfaces by doing this:

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). The main problem is that I don't find a way to identify the WiFi interface. This is an issue since some phones have multiple interfaces (WiMax, etc). 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).
  • 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.

Any suggestions?

mjs
  • 2,837
  • 4
  • 28
  • 48
sirlion
  • 287
  • 2
  • 4
  • 11

7 Answers7

12

Here's what I did to get the wifi hotspot 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. If you're connected to another wifi network (meaning you're not in hotspot mode), it'll return an IP.

You should check if you are in AP mode first or not. You can use this class for that: http://www.whitebyte.info/android/android-wifi-hotspot-manager-class

ajma
  • 12,106
  • 12
  • 71
  • 90
  • Hi @ajma, Thanks for sharing this valuable code, this is working and give me ip address for both "WiFi simple router network" & " WiFi Tethering or hotspot". – VISHAL VIRADIA Apr 14 '13 at 06:01
  • 3
    This is not 100% correct. I've found out that the network interface name varies a lot. HTC Desire Z: wl0.1; Prestigio 3540: ap0; Nexus 5/Samsung DUOS: wlan0. On the other hand, in all cases there has been only one device listed (no loopback etc). – Miro Kropacek Feb 19 '14 at 10:32
  • 3
    this code doesn't work on some devices where the interface is named ap0. i suggest the following correction: if ((intf.getName().contains("wlan")) ||(intf.getName().contains("ap"))) { on my phone there is a interface wlan0 but it has no inet address because the ip address is on the ap0. I also have the loopback interface in my case. when It is connected to a wifi router it uses the wlan0. – Gaucho Oct 11 '15 at 19:50
3

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;

}
Waheed Abbas
  • 187
  • 1
  • 4
  • 18
navid_gh
  • 1,863
  • 3
  • 17
  • 30
0

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. Also the ip address changes.

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.

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.

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

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());
Littm
  • 4,923
  • 4
  • 30
  • 38
Rit Man
  • 51
  • 2
0
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;
}
yiteng lin
  • 31
  • 2
0

I use the solution of ajma, changing intf.getName().contains("wlan") to 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.

kbridge4096
  • 901
  • 1
  • 11
  • 22
0

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.

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

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.

NOTE: ensure you have already created a successful connection to an access point (e.g. hotspot) via WiFi before querying for the server ip. You only need the SSID and preSharedkey (if it's secure) to create a successful connection and not the server ip.

Udo E.
  • 2,665
  • 2
  • 21
  • 33
0

Here is a possible solution that utilizes WiFiManager ConnectionInfo to find corresponding NetworkInterface.

If you just need the IP then you can use:

WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
tenorsax
  • 21,123
  • 9
  • 60
  • 107
  • 3
    I'm sorry but that's not the solution. As I said before, WifiManager is useless when the iface is in AP mode. Android "thinks" that Wifi is disabled. On the other hand, I tried something similar to the solution you provide, but using the MAC address instead of the IP. But as I already pointed, it does not work. For some reason, the mac address of the wifi iface is null (in some devices). – sirlion Mar 05 '12 at 21:44
  • 2
    Yep, it is. Trust me, that approach does not work. You can try it if you want.. :/ – sirlion Mar 05 '12 at 23:47
  • hello, my solution is open hotspot with show "fake dialog" to notify user, then dismiss when got ipaddress :) – kemdo Feb 05 '17 at 12:08