So something to consider is that Formatter.formatIpAddress(int) is being deprecated:
This method was deprecated in API level 12.
Use getHostAddress(), which supports both IPv4 and IPv6 addresses. This method does not support IPv6 addresses.
So using formatIpAddress(int)
is likely not a good long term solution, although it will work.
Here is a potential solution if you are looking to absolutely on get the IP address for the WiFi interface:
protected String wifiIpAddress(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
int ipAddress = wifiManager.getConnectionInfo().getIpAddress();
// Convert little-endian to big-endianif needed
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) {
Log.e("WIFIIP", "Unable to get host address.");
ipAddressString = null;
}
return ipAddressString;
}
As stated in previous responses, you need to set the following in your AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Note that this is only an example solution. You should take time to check for null values and so on to make sure that the UX is smooth.
The irony is that on one hand Google is deprecating formatIpAddress(int)
, but still has getIpAddress() still returns an integer value. The IP address being an int also rules it out for being IPv6 compliant.
Next is the fact that endianness may or may not be an issue. I have only tested three devices and they have all been little-endian. It seems like endianness can vary depending on the hardware, even though we are running in VMs this can still be an issue. So to be on the safe side I added an endian check in the code.
getByAddress(byte[]) appears to want the integer value to be big endian. From researching this it appears that network byte order is big-endian. Makes sense since an address like 192.168.12.22 is a big-endian number.
Check out HammerNet GitHub project. It implements the code above along with a bunch of sanity checks, ability to handle defaults for AVDs, unit tests, and other things. I had to implement this for an app of mine and decided to open source the library.