456

Is it possible to get the IP address of the device using some code?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Nilesh Tupe
  • 7,655
  • 5
  • 25
  • 30
  • 6
    Don't forget that this is a collection of size N, and you can't assume that N == ( 0 || 1 ). In other words, don't assume that a device only has one way of talking to a network and don't assume that it has any way to talk to a network at all. – James Moore Aug 15 '12 at 19:15
  • Related: http://stackoverflow.com/questions/9481865/how-to-get-ip-address-of-current-machine-using-java – AlikElzin-kilaka Jun 11 '14 at 09:45
  • 2
    non programmatic version http://android.stackexchange.com/questions/2984/how-can-i-see-what-ip-address-my-android-phone-has – Ciro Santilli OurBigBook.com Mar 01 '16 at 12:11
  • You should get it from an external service http://ipof.in/txt is one such service – vivekv Sep 28 '16 at 18:24
  • is it possible to get it programatically in android? – Tanmay Sahoo Nov 08 '16 at 09:54
  • See my answer in https://stackoverflow.com/questions/16730711/get-my-wifi-ip-address-android/50871614#50871614 – Yong Jun 15 '18 at 08:23

31 Answers31

483

This is my helper util to read IP and MAC addresses. Implementation is pure-java, but I have a comment block in getMACAddress() which could read the value from the special Linux(Android) file. I've run this code only on few devices and Emulator but let me know here if you find weird results.

// AndroidManifest.xml permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

// test functions
Utils.getMACAddress("wlan0");
Utils.getMACAddress("eth0");
Utils.getIPAddress(true); // IPv4
Utils.getIPAddress(false); // IPv6 

Utils.java

import java.io.*;
import java.net.*;
import java.util.*;   
//import org.apache.http.conn.util.InetAddressUtils;

public class Utils {

    /**
     * Convert byte array to hex string
     * @param bytes toConvert
     * @return hexValue
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sbuf = new StringBuilder();
        for(int idx=0; idx < bytes.length; idx++) {
            int intVal = bytes[idx] & 0xff;
            if (intVal < 0x10) sbuf.append("0");
            sbuf.append(Integer.toHexString(intVal).toUpperCase());
        }
        return sbuf.toString();
    }

    /**
     * Get utf8 byte array.
     * @param str which to be converted
     * @return  array of NULL if error was found
     */
    public static byte[] getUTF8Bytes(String str) {
        try { return str.getBytes("UTF-8"); } catch (Exception ex) { return null; }
    }

    /**
     * Load UTF8withBOM or any ansi text file.
     * @param filename which to be converted to string
     * @return String value of File
     * @throws java.io.IOException if error occurs
     */
    public static String loadFileAsString(String filename) throws java.io.IOException {
        final int BUFLEN=1024;
        BufferedInputStream is = new BufferedInputStream(new FileInputStream(filename), BUFLEN);
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFLEN);
            byte[] bytes = new byte[BUFLEN];
            boolean isUTF8=false;
            int read,count=0;           
            while((read=is.read(bytes)) != -1) {
                if (count==0 && bytes[0]==(byte)0xEF && bytes[1]==(byte)0xBB && bytes[2]==(byte)0xBF ) {
                    isUTF8=true;
                    baos.write(bytes, 3, read-3); // drop UTF8 bom marker
                } else {
                    baos.write(bytes, 0, read);
                }
                count+=read;
            }
            return isUTF8 ? new String(baos.toByteArray(), "UTF-8") : new String(baos.toByteArray());
        } finally {
            try{ is.close(); } catch(Exception ignored){} 
        }
    }

    /**
     * Returns MAC address of the given interface name.
     * @param interfaceName eth0, wlan0 or NULL=use first interface 
     * @return  mac address or empty string
     */
    public static String getMACAddress(String interfaceName) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                if (interfaceName != null) {
                    if (!intf.getName().equalsIgnoreCase(interfaceName)) continue;
                }
                byte[] mac = intf.getHardwareAddress();
                if (mac==null) return "";
                StringBuilder buf = new StringBuilder();
                for (byte aMac : mac) buf.append(String.format("%02X:",aMac));  
                if (buf.length()>0) buf.deleteCharAt(buf.length()-1);
                return buf.toString();
            }
        } catch (Exception ignored) { } // for now eat exceptions
        return "";
        /*try {
            // this is so Linux hack
            return loadFileAsString("/sys/class/net/" +interfaceName + "/address").toUpperCase().trim();
        } catch (IOException ex) {
            return null;
        }*/
    }

    /**
     * Get IP address from first non-localhost interface
     * @param useIPv4   true=return ipv4, false=return ipv6
     * @return  address or empty string
     */
    public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
                for (InetAddress addr : addrs) {
                    if (!addr.isLoopbackAddress()) {
                        String sAddr = addr.getHostAddress();
                        //boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
                        boolean isIPv4 = sAddr.indexOf(':')<0;

                        if (useIPv4) {
                            if (isIPv4) 
                                return sAddr;
                        } else {
                            if (!isIPv4) {
                                int delim = sAddr.indexOf('%'); // drop ip6 zone suffix
                                return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase();
                            }
                        }
                    }
                }
            }
        } catch (Exception ignored) { } // for now eat exceptions
        return "";
    }

}

Disclaimer: Ideas and example code to this Utils class came from several SO posts and Google. I have cleaned and merged all examples.

exploitr
  • 843
  • 1
  • 14
  • 27
Whome
  • 10,181
  • 6
  • 53
  • 65
  • 19
    This requires API level 9 and above because of getHardwareAddress(). – Calvin Dec 28 '12 at 02:54
  • 2
    Problems - lint warnings on `toUpperCase()`. Catching `Exception` is always dodgy (and helper methods should throw anyway and let the caller deal with the Exception - did not amend this though). Formatting : should be no more than 80 lines. Conditional execution for `getHardwareAddress()` - patch : https://github.com/Utumno/AndroidHelpers/commit/b285df75ab6dd1e724e1985d480d18be3a8692a7. What you say ? – Mr_and_Mrs_D Sep 05 '13 at 19:33
  • 6
    If you are on a local network (e.g. Wifi or emulator), you will get a private IP address. You can get the proxy IP address through a request to a specific website which gives you the proxy address, e.g. http://whatismyip.akamai.com/ – Julien Kronegg Sep 20 '13 at 13:07
  • Get very strange IP address in Genymotion/in virtual box emulator: 10.0.3.15 . Pinging does not work because the IP is invalid? – Codebeat May 05 '14 at 01:19
  • Erwinus: Both the 10.x.x.x and 192.168.x.x are private IPs. Relates to virtual box guestOS network routing. I know nothing about Genymotion but I guess there is options to open(port forward) private ips to hostOS. – Whome May 05 '14 at 09:53
  • Why do you need the `toUpperCase()`? – AlikElzin-kilaka Jun 10 '14 at 11:16
  • kilaka: toUpperCase is to force IP6 address to uppercase. You can leave it out if want use any case device platform is returning. – Whome Jun 11 '14 at 19:50
  • In which cases should we use the IP6 format? is it useful for WIFI network (LAN ) ? – android developer Jun 16 '14 at 21:21
  • Hi,I get the default gateway instead of IP address . :( – Sukan Jul 14 '14 at 10:08
  • This doesnt work for me in Android 4.4 emulator. Is this code need real device – Meiyappan Kannappa Jul 21 '15 at 11:31
  • 1
    This works perfect for me with real device using Wifi. Thanks a lot, bro – Neo Sep 14 '15 at 06:25
  • @Holame: thx for notifying sdk change, I have modified an example code not to use an obsolete helper class. It should work for old and new sdk profiles. – Whome Nov 02 '15 at 15:24
  • Thanks for this. Does anyone know if the Android 6 changes affect this approach? See this link: https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id – Bill Apr 21 '16 at 23:54
  • 8
    I'm getting bad results from this on a Nexus 6 when trying to get an IP address. I have a NetworkInterface with name "name:dummy0 (dummy0)" that gives an address with the format "/XX::XXXX:XXXX:XXXX:XXXX%dummy0", there is also a real network interface that corresponds to wlan0, but since the "dummy" happens first I always get that dummy address – Julian Suarez Jul 27 '16 at 20:55
  • works great.. thanks. I would +2 if I could for handling ethernet connections, and not just wifi. – Seth Aug 04 '16 at 20:39
  • @Seth You could merge getMACAddress+getIPAddress functions to have that feature. Loop for interface objects by given name (eth0 or similar, debug.print all names first), read IP address from that interface object. – Whome Aug 05 '16 at 17:05
  • Works, thanks, there are various other posts, some are short, depend on WifiManager but they fail to get the ip of the phone carrier, they only get the one of the local wifi network. – arntg Nov 16 '16 at 00:54
  • 1
    I love how this is pure JVM based – Bhargav May 20 '17 at 13:35
  • But it returns the first address it finds, for ipv4 it's fine since there is only one, but for ipv6 based addresses there are more than one, so how do i make sure that the first address it returns is the correct ipv6 address – Sumit Kumar Saha Sep 17 '17 at 09:16
  • Probably will be good to add !inetAddress.isLinkLocalAddress() check on if (!addr.isLoopbackAddress()) to prevent getting ipv6 link local addresses. – velval Nov 21 '17 at 02:03
  • Keep in that some devices (such as nexus 5x) return the cellular ip first using this way and you are maybe interested in the local/wifi ip... – JanBo Jan 10 '18 at 15:04
  • If you look at this and think it's way too complicated, I posted an answer that simplifies it and adds some explanation here: https://stackoverflow.com/a/51311401/4714742 – Jon McClung Jul 12 '18 at 17:29
  • @Whome Utils.getMACAddress("wlan0"); Utils.getMACAddress("eth0"); both return null when called from mobile which is connected to the internet using 4G mobile data, any other method to get ip in such case ? – Prashant Jul 16 '18 at 05:40
  • @pcj try calling `getMACAddress(null)` and see what's returned. Debug print all interface names to see what your device is using. Modify that same method to print out to a logcat. – Whome Jul 16 '18 at 13:28
  • @Whome I edited to return any available interface to which has mac address, Then for "ccmni4" type of interface I got ip also mac is different based on interface we send as argument this must be behaviour of mac, on one perticular Android device we get changed mac after some time, Can mac address gets changed after some time for the same interface ? – Prashant Jul 17 '18 at 09:57
  • @pcj I have seen chinese Android media sticks devices to change MAC on every reboot. Anything is possible I guess. – Whome Jul 19 '18 at 08:59
  • :) Concluded that mac cannot be used to identify a device ( As it may change ), Thanks for help @Whome!!! – Prashant Jul 19 '18 at 09:56
  • Thanks,But does this still works for new versions of android? Utils.getMACAddress("wlan0"); Utils.getMACAddress("eth0"); Utils.getIPAddress(true); – C Williams Nov 01 '18 at 14:49
  • @CWilliams Some devices have a "random" interface name so wlan0,eth0 may not give anything. `getMACAddress(null)` is using the first interface found. You may need to printout all interface names to see your device naming. – Whome Nov 02 '18 at 08:13
  • @zeleven Most likely your device is using the different network interface names, try `getMACAddress(null)` to use first interface. Also print out all available interface names. Or do you mean `getIPAddress(true)` IP getter is empty? – Whome Aug 19 '19 at 09:34
  • @Whome Yes, I got nothing when I call the `getIPAddress(true)` method, the return value always empty. – zeleven Aug 20 '19 at 03:25
  • 1
    @zeleven strange if no ipv4 addr available and `getIPAddress(false)` to get ipv6 also empty? Then I don't know what is, you should print out an exception if that is to happen, example function silently eats EX. Final reason is to have only a localhost interface, I guess you need to add logcat debug calls to a getter function. – Whome Aug 20 '19 at 06:18
  • @Whome Above method for ipv4 gives different result than what is my IP in google. Above nethod give me IP address of UK and what is my IP in google gives me IP address of India that is correct. Any idea or anyone face this problem ? – Smeet Dec 02 '19 at 06:16
  • 1
    @Smeet most likely your device has a private and public IP infrastructure(NAT, company routing gateway etc.). This method does not see what happens in a routing/NAT etc side. Or your device has multiple IPs. – Whome Dec 02 '19 at 11:45
238

With permission ACCESS_WIFI_STATE declared in AndroidManifest.xml:

<uses-permission
    android:name="android.permission.ACCESS_WIFI_STATE"/>

One can use the WifiManager to obtain the IP address:

Context context = requireContext().getApplicationContext();
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Martin Zeitler
  • 1
  • 19
  • 155
  • 216
Nilesh Tupe
  • 7,655
  • 5
  • 25
  • 30
  • 1
    Great solution! Work well with Android 3.0 when using-NetworkInterface-solution return something like MAC Address – Anh Tuan Jan 30 '12 at 05:02
  • 1
    Why did you use List and wc here? :s – Umair Jabbar Jun 18 '12 at 21:38
  • 10
    this one works for me . however , it needs "ACCESS_WIFI_STATE" permission and as "Umair" wrote , the list usage is not needed. – android developer Oct 07 '12 at 22:39
  • 16
    formatIpAddress is deprecated for some reason. What should be used instead? – android developer Jun 16 '14 at 20:52
  • 8
    From the docs: Use `getHostAddress()`, which supports both IPv4 and IPv6 addresses. This method does not support IPv6 addresses. – Ryan R Sep 10 '14 at 19:19
  • 7
    how to use getHostAddress() in getting the server & client ip address @RyanR ? – gumuruh Sep 11 '14 at 09:10
  • I am using same code within fragment but I am getting WIFI_Service not found cannot resolve – killer Jun 22 '15 at 10:59
  • 53
    will this still work even if the user uses data instead of wifi? – PinoyCoder Oct 30 '15 at 12:34
  • 4
    does this work even if I am connected to LAN and not to wifi? – Benjamin G Oct 10 '17 at 07:01
  • 2
    Android Studio now displays a warning, do `getApplicationContext().getSystemService(WIFI_SERVICE)` – woprandi Feb 12 '18 at 14:48
  • 4
    Nah this not answering directly to OP. Because not all Android devices using WiFi to connect to internet. It might have NATed LAN on Ethernet, or BT and not NATed WAN connection etc. – nyconing Apr 19 '18 at 16:22
  • 1
    This only works for Wifi interface I think. It won't get the correct IP if the phone is connected via an eth cable or for other interfaces (VPN tunnels for instance) – rkachach Sep 27 '19 at 14:03
  • @DivyanshuKushwaha Isn't there a more official way? – android developer Jan 07 '20 at 08:39
  • it returns wifi device ip – user924 Jun 09 '20 at 14:30
  • it return 0.0.0.0 when I switch to using data instead of wifi connection – Frankey Aug 17 '21 at 08:47
  • Kotlin
    fun getdeviceIpAddress_Wifi(): String? { val context: Context = this.applicationContext val wifiManager = context.getSystemService(ComponentActivity.WIFI_SERVICE) as WifiManager val ip = Formatter.formatIpAddress(wifiManager.connectionInfo.ipAddress) return ip; } // import t import android.net.wifi.WifiManager import android.text.format.Formatter import java.net.Inet4Address import java.net.InetAddress import java.net.NetworkInterface import java.net.SocketException import java.util.*
    – lava Sep 05 '21 at 13:28
  • 1
    This method was deprecated in API version 12 https://stackoverflow.com/questions/20846120/alternative-for-formatter-formatipaddressint/26915348 – Shay Ribera Oct 12 '21 at 18:46
88
public static 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() && inetAddress instanceof Inet4Address) {
                    return inetAddress.getHostAddress();
                }
            }
        }
    } catch (SocketException ex) {
        ex.printStackTrace();
    }
    return null;
}

I've added inetAddress instanceof Inet4Address to check if it is a ipv4 address.

biegleux
  • 13,179
  • 11
  • 45
  • 52
evertvandenbruel
  • 1,133
  • 8
  • 13
  • 1
    There's no way to get the public IP other than to hit some external REST endpoint that reports back what it sees as the public IP, for example: https://api.ipify.org/?format=json. The device doesn't even know the public IP address itself. – Jeffrey Blattman Aug 03 '21 at 20:57
67

I used following code: The reason I used hashCode was because I was getting some garbage values appended to the ip address when I used getHostAddress . But hashCode worked really well for me as then I can use Formatter to get the ip address with correct formatting.

Here is the example output :

1.using getHostAddress : ***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2.using hashCode and Formatter : ***** IP=238.194.77.212

As you can see 2nd methods gives me exactly what I need.

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());
                    Log.i(TAG, "***** IP="+ ip);
                    return ip;
                }
            }
        }
    } catch (SocketException ex) {
        Log.e(TAG, ex.toString());
    }
    return null;
}
anargund
  • 3,249
  • 2
  • 21
  • 25
  • 1
    `getHostAddress()` will do the same as the formatter stuff you added. – Phil Dec 27 '12 at 17:03
  • 12
    Using hashCode is plain wrong, and returns nonsense. Use InetAddress.getHostAddress() instead. – Pointer Null Nov 26 '13 at 08:50
  • change this part: if (!inetAddress.isLoopbackAddress()) { String ip = Formatter.formatIpAddress(inetAddress.hashCode()); Log.i(TAG, "***** IP="+ ip); return ip; } with this: if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())) { return inetAddress .getHostAddress().toString(); } this will give you the correct ip format – Chuy47 Jan 14 '16 at 14:46
  • The code only return first IP, a phone may have celluar, WIFI and BT address at same time – reker Jun 14 '18 at 08:04
  • @Chuy47 it says InetAddressUtils cannot be found – FabioR Jul 16 '19 at 19:28
  • @FabioR it seems that the InetAddressUtils class is now gone but you can use "inetAddress.getHostAddress() instanceof Inet4Address" instead of "InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())". More info here: https://stackoverflow.com/questions/32141785/android-api-23-inetaddressutils-replacement – Chuy47 Jul 16 '19 at 19:40
  • @Chuy47 thank you for such quick reply! It works, however, it gets my network IP and I'd need the public one, any idea of how to do it? – FabioR Jul 16 '19 at 20:18
  • @FabioR, sorry, I just saw this last question, maybe this answer can help you https://stackoverflow.com/questions/6308000/determine-device-public-ip – Chuy47 Jul 19 '19 at 14:04
  • @Chuy47 np, thanks for answering! Indeed, I ended up using that same approach, checking my public IP in an API (I used the ipify one), it worked! – FabioR Jul 19 '19 at 15:23
62

Though there's a correct answer, I share my answer here and hope that this way will more convenience.

WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();
int ipAddress = wifiInf.getIpAddress();
String ip = String.format("%d.%d.%d.%d", (ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
CYB
  • 1,106
  • 15
  • 36
  • 6
    Thanks! Formatter is deprecated, and I really didn't feel like writing simple bit logic. – William Morrison Feb 20 '14 at 19:59
  • 7
    Works great, but requires WIFI_STATE permission: `` – Brent Faust Oct 03 '14 at 01:11
  • 1
    I use the formaater but it doesnt work. It is great! Really appreciated. Could you explain what is done in last line. I know %d.%d.%d.%d however others ? Thanks – Günay Gültekin Apr 12 '15 at 20:37
  • 1
    Nah this not answering directly to OP. Because not all Android devices using WiFi to connect to internet. It might have NATed LAN on Ethernet, or BT and not NATed WAN connection etc. – nyconing Apr 19 '18 at 16:24
34

Below code might help you.. Don't forget to add permissions..

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()) {
                return inetAddress.getHostAddress();
                }
           }
       }
       } catch (Exception ex) {
          Log.e("IP Address", ex.toString());
      }
      return null;
}

Add below permission in the manifest file.

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

happy coding!!

Karthik Kompelli
  • 2,104
  • 1
  • 19
  • 22
Satyam
  • 1,672
  • 3
  • 20
  • 34
29

kotlin minimalist version

fun getIpv4HostAddress(): String {
    NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
        networkInterface.inetAddresses?.toList()?.find {
            !it.isLoopbackAddress && it is Inet4Address
        }?.let { return it.hostAddress }
    }
    return ""
}
Raphael C
  • 2,296
  • 1
  • 22
  • 22
18

You do not need to add permissions like what is the case with the solutions provided so far. Download this website as a string:

http://www.ip-api.com/json

or

http://www.telize.com/geoip

Downloading a website as a string can be done with java code:

http://www.itcuties.com/java/read-url-to-string/

Parse the JSON object like this:

https://stackoverflow.com/a/18998203/1987258

The json attribute "query" or "ip" contains the IP address.

Community
  • 1
  • 1
Daan
  • 2,478
  • 3
  • 36
  • 76
  • 2
    this needs Internet Connection. Big problem – David Sep 25 '15 at 14:58
  • 6
    Why is that a big problem? Of course you need an internet connection because an IP address is technically related to such a connecetion. If you leave your house and go to a restaurant you will use another internet connection and thus another IP address. You do not need something to add more like ACCESS_NETWORK_STATE or ACCESS_WIFI_STATE. An internet connection is the only permission you need for the solution provided by me. – Daan Sep 26 '15 at 13:38
  • this not guaranties your app get IP. because there is no guarantee for that domain remain online. – David Sep 26 '15 at 15:55
  • 2
    Which domain? If ip-api.com does not work, you can use telize.com as a fallback. Otherwise you can use https://api.ipify.org/ . It is also available here (not json): http://ip.jsontest.com/?callback=showIP . Many apps use domains that are to guaranteed to remain online; that is normal. However, if you use fallbacks then it becomes highly unlikely that there will be a problem. – Daan Sep 27 '15 at 15:16
  • 3
    David's original point still stands. What if you're on an internal network which doesn't have access to internet. – hiandbaii Oct 14 '16 at 17:18
  • 2
    I never thought about that because I do not know any practical purpose of an app that definitely needs a network but should work without internet (maybe there is but I don't see it for mobile devices). – Daan Oct 15 '16 at 19:47
  • As someone who is currently developing an enterprise app which is not legally allowed to have an internet connection, David's point represents me. – forresthopkinsa Sep 20 '17 at 22:53
  • 1
    Also note that using this method you will get the external IP that the API service sees and not the actual device IP. The device could be on a local network using a private IP and this happens in most WIFI connections so definitely won't be reliable at all. – velval Nov 21 '17 at 01:43
  • NOT WORKING Free, They provide "http" for free, "https" for paid. If you use this free API in Volley for get Json data, It will be redirected to "https" that showing Error because for "https" you need their premium. – TexD May 22 '23 at 18:39
10
private InetAddress getLocalAddress()throws IOException {

            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()) {
                            //return inetAddress.getHostAddress().toString();
                            return inetAddress;
                        }
                    }
                }
            } catch (SocketException ex) {
                Log.e("SALMAN", ex.toString());
            }
            return null;
        }
Azhar
  • 20,500
  • 38
  • 146
  • 211
salman khalid
  • 4,884
  • 4
  • 27
  • 33
  • 1
    is it possible that this would return the private network ip from the wifi interface, like 192.168.0.x? or will it always return the external ip address, that would be used on the internet? – Ben H Nov 04 '11 at 00:18
9

Method getDeviceIpAddress returns device's ip address and prefers wifi interface address if it connected.

  @NonNull
    private String getDeviceIpAddress() {
        String actualConnectedToNetwork = null;
        ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connManager != null) {
            NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWifi.isConnected()) {
                actualConnectedToNetwork = getWifiIp();
            }
        }
        if (TextUtils.isEmpty(actualConnectedToNetwork)) {
            actualConnectedToNetwork = getNetworkInterfaceIpAddress();
        }
        if (TextUtils.isEmpty(actualConnectedToNetwork)) {
            actualConnectedToNetwork = "127.0.0.1";
        }
        return actualConnectedToNetwork;
    }

    @Nullable
    private String getWifiIp() {
        final WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (mWifiManager != null && mWifiManager.isWifiEnabled()) {
            int ip = mWifiManager.getConnectionInfo().getIpAddress();
            return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "."
                    + ((ip >> 24) & 0xFF);
        }
        return null;
    }


    @Nullable
    public String getNetworkInterfaceIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface networkInterface = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        String host = inetAddress.getHostAddress();
                        if (!TextUtils.isEmpty(host)) {
                            return host;
                        }
                    }
                }

            }
        } catch (Exception ex) {
            Log.e("IP Address", "getLocalIpAddress", ex);
        }
        return null;
    }
Ruslan Podurets
  • 151
  • 1
  • 2
  • 9
6

In your activity, the following function getIpAddress(context) returns the phone's IP address:

public static String getIpAddress(Context context) {
    WifiManager wifiManager = (WifiManager) context.getApplicationContext()
                .getSystemService(WIFI_SERVICE);

    String ipAddress = intToInetAddress(wifiManager.getDhcpInfo().ipAddress).toString();

    ipAddress = ipAddress.substring(1);

    return ipAddress;
}

public static InetAddress intToInetAddress(int hostAddress) {
    byte[] addressBytes = { (byte)(0xff & hostAddress),
                (byte)(0xff & (hostAddress >> 8)),
                (byte)(0xff & (hostAddress >> 16)),
                (byte)(0xff & (hostAddress >> 24)) };

    try {
        return InetAddress.getByAddress(addressBytes);
    } catch (UnknownHostException e) {
        throw new AssertionError();
    }
}
matdev
  • 4,115
  • 6
  • 35
  • 56
6

You can use LinkProperties. It's recommended for new Android versions.

This function retrieves local IP address for both WiFi and Mobile Data. It requires Manifest.permission.ACCESS_NETWORK_STATE permission.

@Nullable
public static String getDeviceIpAddress(@NonNull ConnectivityManager connectivityManager) {
    LinkProperties linkProperties = connectivityManager.getLinkProperties(connectivityManager.getActiveNetwork());
    InetAddress inetAddress;
    for(LinkAddress linkAddress : linkProperties.getLinkAddresses()) {
        inetAddress = linkAddress.getAddress();
        if (inetAddress instanceof Inet4Address
                && !inetAddress.isLoopbackAddress()
                && inetAddress.isSiteLocalAddress()) {
            return inetAddress.getHostAddress();
        }
    }
    return null;
}
Atakan Yildirim
  • 684
  • 11
  • 22
  • 1
    "new Android versions" means >= api 21 (android 5, https://developer.android.com/reference/android/net/ConnectivityManager#getLinkProperties(android.net.Network)). This is also the preferred way if you want to receive ip address of specific Network (just pass it as parameter to getLinkProperties). – Maxdestroyer Nov 18 '22 at 06:51
5

This is a rework of this answer which strips out irrelevant information, adds helpful comments, names variables more clearly, and improves the logic.

Don't forget to include the following permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

InternetHelper.java:

public class InternetHelper {

    /**
     * Get IP address from first non-localhost interface
     *
     * @param useIPv4 true=return ipv4, false=return ipv6
     * @return address or empty string
     */
    public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces =
                    Collections.list(NetworkInterface.getNetworkInterfaces());

            for (NetworkInterface interface_ : interfaces) {

                for (InetAddress inetAddress :
                        Collections.list(interface_.getInetAddresses())) {

                    /* a loopback address would be something like 127.0.0.1 (the device
                       itself). we want to return the first non-loopback address. */
                    if (!inetAddress.isLoopbackAddress()) {
                        String ipAddr = inetAddress.getHostAddress();
                        boolean isIPv4 = ipAddr.indexOf(':') < 0;

                        if (isIPv4 && !useIPv4) {
                            continue;
                        }
                        if (useIPv4 && !isIPv4) {
                            int delim = ipAddr.indexOf('%'); // drop ip6 zone suffix
                            ipAddr = delim < 0 ? ipAddr.toUpperCase() :
                                    ipAddr.substring(0, delim).toUpperCase();
                        }
                        return ipAddr;
                    }
                }

            }
        } catch (Exception ignored) { } // if we can't connect, just return empty string
        return "";
    }

    /**
     * Get IPv4 address from first non-localhost interface
     *
     * @return address or empty string
     */
    public static String getIPAddress() {
        return getIPAddress(true);
    }

}
Jon McClung
  • 1,619
  • 20
  • 28
4
public static String getdeviceIpAddress() {
    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() && inetAddress instanceof Inet4Address) {
                    return inetAddress.getHostAddress();
                }
            }
        }
    } catch (SocketException ex) {
        ex.printStackTrace();
    }
    return null;
}
  • This code helped me get the local IP address of the Hotspot. 192.168.55.66 in my case . Thanks! – mihai71 May 10 '23 at 11:06
3
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();
mridul
  • 1,986
  • 9
  • 29
  • 50
2

Recently, an IP address is still returned by getLocalIpAddress() despite being disconnected from the network (no service indicator). It means the IP address displayed in the Settings> About phone> Status was different from what the application thought.

I have implemented a workaround by adding this code before:

ConnectivityManager cm = getConnectivityManager();
NetworkInfo net = cm.getActiveNetworkInfo();
if ((null == net) || !net.isConnectedOrConnecting()) {
    return null;
}

Does that ring a bell to anyone?

slash33
  • 899
  • 1
  • 11
  • 17
2

Simply use Volley to get the ip from this site

RequestQueue queue = Volley.newRequestQueue(this);    
String urlip = "http://checkip.amazonaws.com/";

    StringRequest stringRequest = new StringRequest(Request.Method.GET, urlip, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            txtIP.setText(response);

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            txtIP.setText("didnt work");
        }
    });

    queue.add(stringRequest);
Sohel Mahmud
  • 187
  • 12
  • this is to fetch a public ip, and is dependant on amazon's aws check ip service which might eventually change or disappear one day, and only works if the device has access to internet. on a local network, or when offline, it will not work. furthermore, notice that the checkip service is not secure, and can therefore be faked by a man in the middle. to get the list of IP addresses of a device, we need to query the list of network interfaces of the device(cellular, wifi, etc...), and get the addresses which are not local. – Raphael C Jul 15 '20 at 13:51
2

in Kotlin, without Formatter

private fun getIPAddress(useIPv4 : Boolean): String {
    try {
        var interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
        for (intf in interfaces) {
            var addrs = Collections.list(intf.getInetAddresses());
            for (addr in addrs) {
                if (!addr.isLoopbackAddress()) {
                    var sAddr = addr.getHostAddress();
                    var isIPv4: Boolean
                    isIPv4 = sAddr.indexOf(':')<0
                    if (useIPv4) {
                        if (isIPv4)
                            return sAddr;
                    } else {
                        if (!isIPv4) {
                            var delim = sAddr.indexOf('%') // drop ip6 zone suffix
                            if (delim < 0) {
                                return sAddr.toUpperCase()
                            }
                            else {
                                return sAddr.substring(0, delim).toUpperCase()
                            }
                        }
                    }
                }
            }
        }
    } catch (e: java.lang.Exception) { }
    return ""
}
zeina
  • 41
  • 2
2

A device might have several IP addresses, and the one in use in a particular app might not be the IP that servers receiving the request will see. Indeed, some users use a VPN or a proxy such as Cloudflare Warp.

If your purpose is to get the IP address as shown by servers that receive requests from your device, then the best is to query an IP geolocation service such as Ipregistry (disclaimer: I work for the company) with its Java client:

https://github.com/ipregistry/ipregistry-java

IpregistryClient client = new IpregistryClient("tryout");
RequesterIpInfo requesterIpInfo = client.lookup();
requesterIpInfo.getIp();

In addition to being really simple to use, you get additional information such as country, language, currency, the time zone for the device IP and you can identify whether the user is using a proxy.

Laurent
  • 14,122
  • 13
  • 57
  • 89
2

This is the easiest and simple way ever exist on the internet... First of all, add this permission to your manifest file...

  1. "INTERNET"

  2. "ACCESS_NETWORK_STATE"

add this in onCreate file of Activity..

    getPublicIP();

Now Add this function to your MainActivity.class.

    private void getPublicIP() {
ArrayList<String> urls=new ArrayList<String>(); //to read each line

        new Thread(new Runnable(){
            public void run(){
                //TextView t; //to show the result, please declare and find it inside onCreate()

                try {
                    // Create a URL for the desired page
                    URL url = new URL("https://api.ipify.org/"); //My text file location
                    //First open the connection
                    HttpURLConnection conn=(HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(60000); // timing out in a minute

                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

                    //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
                    String str;
                    while ((str = in.readLine()) != null) {
                        urls.add(str);
                    }
                    in.close();
                } catch (Exception e) {
                    Log.d("MyTag",e.toString());
                }

                //since we are in background thread, to post results we have to go back to ui thread. do the following for that

                PermissionsActivity.this.runOnUiThread(new Runnable(){
                    public void run(){
                        try {
                            Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
                        }
                        catch (Exception e){
                            Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

            }
        }).start();

    }
Zia
  • 705
  • 9
  • 11
1

Here is kotlin version of @Nilesh and @anargund

  fun getIpAddress(): String {
    var ip = ""
    try {
        val wm = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
        ip = Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
    } catch (e: java.lang.Exception) {

    }

    if (ip.isEmpty()) {
        try {
            val en = NetworkInterface.getNetworkInterfaces()
            while (en.hasMoreElements()) {
                val networkInterface = en.nextElement()
                val enumIpAddr = networkInterface.inetAddresses
                while (enumIpAddr.hasMoreElements()) {
                    val inetAddress = enumIpAddr.nextElement()
                    if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                        val host = inetAddress.getHostAddress()
                        if (host.isNotEmpty()) {
                            ip =  host
                            break;
                        }
                    }
                }

            }
        } catch (e: java.lang.Exception) {

        }
    }

   if (ip.isEmpty())
      ip = "127.0.0.1"
    return ip
}
Sumit
  • 1,022
  • 13
  • 19
1

Compiling some of the ideas to get the wifi ip from the WifiManager in a nicer kotlin solution:

private fun getWifiIp(context: Context): String? {
  return context.getSystemService<WifiManager>().let {
     when {
      it == null -> "No wifi available"
      !it.isWifiEnabled -> "Wifi is disabled"
      it.connectionInfo == null -> "Wifi not connected"
      else -> {
        val ip = it.connectionInfo.ipAddress
        ((ip and 0xFF).toString() + "." + (ip shr 8 and 0xFF) + "." + (ip shr 16 and 0xFF) + "." + (ip shr 24 and 0xFF))
      }
    }
  }
}

Alternatively you can get the ip adresses of ip4 loopback devices via the NetworkInterface:

fun getNetworkIp4LoopbackIps(): Map<String, String> = try {
  NetworkInterface.getNetworkInterfaces()
    .asSequence()
    .associate { it.displayName to it.ip4LoopbackIps() }
    .filterValues { it.isNotEmpty() }
} catch (ex: Exception) {
  emptyMap()
}

private fun NetworkInterface.ip4LoopbackIps() =
  inetAddresses.asSequence()
    .filter { !it.isLoopbackAddress && it is Inet4Address }
    .map { it.hostAddress }
    .filter { it.isNotEmpty() }
    .joinToString()
Moritz
  • 10,124
  • 7
  • 51
  • 61
1

Blockquote // get Device Ip Address

open fun getLocalIpAddress(): String? {
    try {
        val en: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
        while (en.hasMoreElements()) {
            val networkInterface: NetworkInterface = en.nextElement()
            val enumerationIpAddress: Enumeration<InetAddress> = networkInterface.inetAddresses
            while (enumerationIpAddress.hasMoreElements()) {
                val inetAddress: InetAddress = enumerationIpAddress.nextElement()
                if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                    return inetAddress.getHostAddress()
                }
            }
        }
    } catch (ex: SocketException) {
        ex.printStackTrace()
    }
    return null
}
0

Please check this code...Using this code. we will get ip from mobile internet...

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()) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }
venkat
  • 157
  • 3
  • 15
0

I don't do Android, but I'd tackle this in a totally different way.

Send a query to Google, something like: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

And refer to the HTML field where the response is posted. You may also query directly to the source.

Google will most like be there for longer than your Application.

Just remember, it could be that your user does not have internet at this time, what would you like to happen !

Good Luck

Makab
  • 42
  • 4
  • Interesting! And I bet that Google has some sort of API call that will return your IP, which will be more stable than scanning HTML. – SMBiggs Feb 19 '17 at 07:33
0

You can do this

String stringUrl = "https://ipinfo.io/ip";
//String stringUrl = "http://whatismyip.akamai.com/";
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.instance);
//String url ="http://www.google.com";

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, stringUrl,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                // Display the first 500 characters of the response string.
                Log.e(MGLogTag, "GET IP : " + response);

            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        IP = "That didn't work!";
    }
});

// Add the request to the RequestQueue.
queue.add(stringRequest);
Pang
  • 9,564
  • 146
  • 81
  • 122
0
 //    @NonNull
    public static String getIPAddress() {
        if (TextUtils.isEmpty(deviceIpAddress))
            new PublicIPAddress().execute();
        return deviceIpAddress;
    }

    public static String deviceIpAddress = "";

    public static class PublicIPAddress extends AsyncTask<String, Void, String> {
        InetAddress localhost = null;

        protected String doInBackground(String... urls) {
            try {
                localhost = InetAddress.getLocalHost();
                URL url_name = new URL("http://bot.whatismyipaddress.com");
                BufferedReader sc = new BufferedReader(new InputStreamReader(url_name.openStream()));
                deviceIpAddress = sc.readLine().trim();
            } catch (Exception e) {
                deviceIpAddress = "";
            }
            return deviceIpAddress;
        }

        protected void onPostExecute(String string) {
            Lg.d("deviceIpAddress", string);
        }
    }
Ashish Kumar
  • 1,088
  • 8
  • 17
0

In all honesty I am only a little familiar with code safety, so this may be hack-ish. But for me this is the most versatile way to do it:

package com.my_objects.ip;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class MyIpByHost 
{
  public static void main(String a[])
  {
   try 
    {
      InetAddress host = InetAddress.getByName("nameOfDevice or webAddress");
      System.out.println(host.getHostAddress());
    } 
   catch (UnknownHostException e) 
    {
      e.printStackTrace();
    }
} }
  • Would InetAddress return IP of the device that the current device is connected to instead of the IP of the current device? – Stigma Jul 21 '21 at 19:42
0

For kotlin language.

fun contextIP(context: Context): String {
    val wm: WifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
    return Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
}
Vahit Keskin
  • 274
  • 1
  • 9
0

If you have a shell ; ifconfig eth0 worked for x86 device too

RzR
  • 3,068
  • 29
  • 26
-2

Based on what I have tested this is my proposal

import java.net.*;
import java.util.*;

public class hostUtil
{
   public static String HOST_NAME = null;
   public static String HOST_IPADDRESS = null;

   public static String getThisHostName ()
   {
      if (HOST_NAME == null) obtainHostInfo ();
      return HOST_NAME;
   }

   public static String getThisIpAddress ()
   {
      if (HOST_IPADDRESS == null) obtainHostInfo ();
      return HOST_IPADDRESS;
   }

   protected static void obtainHostInfo ()
   {
      HOST_IPADDRESS = "127.0.0.1";
      HOST_NAME = "localhost";

      try
      {
         InetAddress primera = InetAddress.getLocalHost();
         String hostname = InetAddress.getLocalHost().getHostName ();

         if (!primera.isLoopbackAddress () &&
             !hostname.equalsIgnoreCase ("localhost") &&
              primera.getHostAddress ().indexOf (':') == -1)
         {
            // Got it without delay!!
            HOST_IPADDRESS = primera.getHostAddress ();
            HOST_NAME = hostname;
            //System.out.println ("First try! " + HOST_NAME + " IP " + HOST_IPADDRESS);
            return;
         }
         for (Enumeration<NetworkInterface> netArr = NetworkInterface.getNetworkInterfaces(); netArr.hasMoreElements();)
         {
            NetworkInterface netInte = netArr.nextElement ();
            for (Enumeration<InetAddress> addArr = netInte.getInetAddresses (); addArr.hasMoreElements ();)
            {
               InetAddress laAdd = addArr.nextElement ();
               String ipstring = laAdd.getHostAddress ();
               String hostName = laAdd.getHostName ();

               if (laAdd.isLoopbackAddress()) continue;
               if (hostName.equalsIgnoreCase ("localhost")) continue;
               if (ipstring.indexOf (':') >= 0) continue;

               HOST_IPADDRESS = ipstring;
               HOST_NAME = hostName;
               break;
            }
         }
      } catch (Exception ex) {}
   }
}
elxala
  • 291
  • 3
  • 5