如何从代码获取设备的IP地址?


383

是否可以使用一些代码获取设备的IP地址?


5
不要忘记这是一个大小为N的集合,并且不能假设N ==(0 || 1)。换句话说,不要假设设备只有一种与网络对话的方式,也不要假设设备完全没有与网络对话的方式。
詹姆斯·摩尔



您应该从外部服务获得它ipof.in/txt是这样的一种服务
vivekv

是否有可能在Android中以编程方式获取它?
Tanmay Sahoo,

Answers:


434

这是我的辅助工具,用于读取IP和MAC地址。实现是纯Java的,但是我有一个注释块getMACAddress(),可以从特殊的Linux(Android)文件中读取值。我仅在少数设备和仿真器上运行此代码,但是如果您发现奇怪的结果,请在这里告诉我。

// 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 

实用工具

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 "";
    }

}

免责声明:此实用程序类的想法和示例代码来自几个SO职位和Google。我已经清理并合并了所有示例。


17
由于getHardwareAddress(),因此需要API级别9和更高级别。
加尔文

2
问题-关于的棉绒警告toUpperCase()。捕获Exception总是狡猾的(辅助方法应该仍然抛出,并让调用者处理Exception-尽管未对此进行修改)。格式:不得超过80行。有条件执行getHardwareAddress()-补丁程序:github.com/Utumno/AndroidHelpers/commit/…。你说的话 ?
Mr_and_Mrs_D 2013年

5
如果您在本地网络(例如Wifi或仿真器)上,则将获得一个专用IP地址。您可以通过对特定网站的请求,让你的代理服务器地址获取代理IP地址,例如whatismyip.akamai.com
朱利安Kronegg

1
这对于使用Wifi的真实设备非常适合我。非常感谢,兄弟
Neo Neo先生

5
尝试获取IP地址时,我在Nexus 6上收到了不好的结果。我有一个名称为“ name:dummy0(dummy0)”的NetworkInterface,其地址格式为“ / XX :: XXXX:XXXX:XXXX:XXXX%dummy0”,还有一个对应于wlan0的真实网络接口,但是因为首先发生了“虚拟”,所以我总是得到那个虚拟地址
朱利安·苏亚雷斯

201

这为我工作:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

10
这个适合我。但是,它需要“ ACCESS_WIFI_STATE”权限,并且如“ Umair”所写,不需要使用列表。
Android开发人员

13
由于某些原因,不赞成formatIpAddress。应该用什么代替呢?
Android开发人员

8
从文档中:Use getHostAddress(),它同时支持IPv4和IPv6地址。此方法不支持IPv6地址。
Ryan R

7
如何在获取服务器和客户端IP地址@RyanR时使用getHostAddress()?
gumuruh 2014年

42
即使用户使用数据而不是wifi,这仍然可以工作吗?
PinoyCoder 2015年

65

我使用以下代码:使用hashCode的原因是因为在使用时,我将一些垃圾值附加到ip地址上getHostAddress。但是hashCode对我来说确实很好,因为那时我可以使用Formatter来获取具有正确格式的ip地址。

这是示例输出:

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

2.使用hashCodeFormatter***** IP=238.194.77.212

如您所见,第二种方法正好满足了我的需求。

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

1
getHostAddress()将与您添加的格式化程序内容相同。
菲尔(Phil)

10
使用hashCode显然是错误的,并返回废话。使用InetAddress.getHostAddress()代替。
指针为空,

更改此部分:if(!inetAddress.isLoopbackAddress()){字符串ip = Formatter.formatIpAddress(inetAddress.hashCode()); Log.i(TAG,“ ***** IP =” + ip); 返回ip; }与此一起:if(!inetAddress.isLoopbackAddress()&& InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())){返回inetAddress .getHostAddress()。toString(); }这将为您提供正确的IP格式
Chuy47 '16

该代码仅返回第一个IP,电话可能同时具有蜂窝,WIFI和BT地址
reker

@ Chuy47,它说找不到InetAddressUtils
FabioR

61
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;
}

我添加了inetAddressinstanceof Inet4Address来检查它是否是ipv4地址。


拯救了我的一天!谢谢。这是在三星s7 edge上运行的唯一代码
Dhananjay Sarsonia

这是真正的答案,而不是仅获得WiFi接口的答案。
nyconing

这确实应该是正确的答案,它适用于WiFi和移动网络,并使用“ getHostAddress”代替自定义格式。
巴拉兹Gerlei

但是,它获得了我的本地IP,我需要我的公共IP(因为我认为OP也需要)
FabioR

53

尽管答案正确,但我在这里分享我的答案,并希望这种方式会带来更多便利。

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

4
谢谢!Formatter已过时,我真的不喜欢编写简单的位逻辑。
威廉·莫里森

4
效果很好,但需要WIFI_STATE许可:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust

1
我使用formaater,但是它不起作用。太好了!非常感谢。您能否解释一下最后一行中的操作。我知道%d。%d。%d。%d但是还有其他人吗?谢谢
居纳伊居尔泰金

1
不,这不是直接回答OP。因为并非所有使用WiFi的Android设备都可以连接到互联网。它可能具有NAT的LAN以太网或BT,而不是NAT的广域网连接等
nyconing

31

下面的代码可能会对您有所帮助。.不要忘记添加权限..

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

在清单文件中添加以下权限。

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

快乐编码!


6
嘿,这返回了一个不正确的值,例如:“ fe80 :: f225:b7ff:fe8c:d357%wlan0”
Jorgesys

@Jorgesys检查evertvandenbruel的答案,他在那里添加了inetAddress instanceof Inet4Address的inetAddress instance
temirbek 17-10-31

3
更改条件,以获取正确的ip:if(!inetAddress.isLoopbackAddress()&& inetAddress instanceof Inet4Address)
Rajesh.k

该代码仅返回第一个IP,电话可能同时具有蜂窝,WIFI和BT地址
reker

如果您有热点,则可能会获得一个以上的IP
Harsha

16

您无需像到目前为止提供的解决方案一样添加权限。以字符串形式下载此网站:

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

要么

http://www.telize.com/geoip

可以使用Java代码以字符串形式下载网站:

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

像这样解析JSON对象:

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

json属性“ query”或“ ip”包含IP地址。


2
这需要Internet连接。大问题
-David

4
为什么这是个大问题?当然,您需要Internet连接,因为IP地址在技术上与这种连接有关。如果您离开家去餐馆,您将使用另一个互联网连接,从而使用另一个IP地址。您不需要添加其他内容,例如ACCESS_NETWORK_STATE或ACCESS_WIFI_STATE。互联网连接是您提供我提供的解决方案所需的唯一权限。
大安2015年

2
哪个域名?如果ip-api.com不起作用,则可以使用telize.com作为后备。否则,您可以使用api.ipify.org。也可以在这里使用(不是json):ip.jsontest.com/?callback=showIP。许多应用程序使用的域必须保证保持在线状态;那是正常的。但是,如果使用后备,则极不可能出现问题。
大安2015年

3
大卫的原始观点仍然存在。如果您使用的是无法访问Internet的内部网络,该怎么办。
hiandbaii

2
我从来没有考虑过这一点,因为我不知道某个应用程序的任何实际用途,该应用程序确实需要网络,但是应该在没有互联网的情况下也可以工作(也许有,但我看不到用于移动设备)。
大安

9
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;
        }

1
是否有可能从wifi接口(如192.168.0.x)返回专用网络ip?还是会始终返回将在互联网上使用的外部IP地址?
本H

9

方法getDeviceIpAddress返回设备的ip地址,并且如果连接则首选wifi接口地址。

  @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;
    }

4

这是对该答案的重做,它去除了不相关的信息,添加了有用的注释,更清楚地命名了变量,并改善了逻辑。

不要忘记包括以下权限:

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

}

4

科特林极简主义版本

fun getIpv4HostAddress(): String {
    NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
        networkInterface.inetAddresses?.toList()?.find {
            !it.isLoopbackAddress && it is Inet4Address
        }?.let { return it.hostAddress }
    }
    return ""
}

3
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();

3

只需使用Volley即可从站点获取IP

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

2

最近,getLocalIpAddress()尽管IP地址已与网络断开连接,但仍返回IP地址(无服务指示灯)。这意味着在“设置”>“关于手机”>“状态”中显示的IP地址与应用程序的想法不同。

我已经通过添加以下代码来实现变通方法:

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

这会给任何人敲响钟声吗?


2

在Kotlin中,没有格式化程序

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 ""
}

2

在您的活动中,以下功能getIpAddress(context)将返回电话的IP地址:

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

我得到0.0.0.0
natsumiyu

您的手机是否连接到wifi网络?如果调用wifiManager.getConnectionInfo()。getSSID(),返回哪个值?
matdev

它适用于连接到移动数据而不是WiFi的设备吗?
谢尔盖

不,仅当设备连接到WiFi时此方法才有效
matdev

1

这是@Nilesh和@anargund的kotlin版本

  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
}

1
如果这是您实际项目中的代码样式,建议您阅读robert martin的“干净代码”
Ahmed Adel Ismail

1

一台设备可能有多个IP地址,而在特定应用中使用的IP地址可能不是接收请求的服务器将看到的IP。实际上,某些用户使用VPN或诸如Cloudflare Warp的代理。

如果您的目的是获取从您的设备接收请求的服务器所显示的IP地址,那么最好的方法是使用Java客户端查询IP地理位置服务,例如Ipregistry(免责声明:我为公司工作)。

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

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

除了非常简单易用之外,您还可以获得其他信息,例如国家/地区,语言,货币,设备IP的时区,并且可以标识用户是否正在使用代理。


1

这是互联网上有史以来最简单的方法...首先,将此权限添加到清单文件中...

  1. “互联网”

  2. “ ACCESS_NETWORK_STATE”

将此添加到Activity的onCreate文件中。

    getPublicIP();

现在,将此函数添加到您的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();

    }


urls.get(0)包含您的公共IP地址。
Zia Muhammad

您必须像这样在活动文件中声明:ArrayList <String> urls = new ArrayList <String>(); //阅读每一行
Zia Muhammad

0

如果你有贝壳; ifconfig eth0也适用于x86设备


0

请检查此代码...使用此代码。我们将从移动互联网获取IP ...

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

0

我没有使用Android,但是我将以完全不同的方式解决这个问题。

向Google发送查询,例如:https : //www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

并参考发布响应的HTML字段。您也可以直接查询源。

Google最希望在那里停留的时间比您的应用程序更长。

请记住,这可能是您的用户目前没有互联网,您想发生什么!

祝好运


有趣!而且我敢打赌Google会通过某种API调用返回您的IP,这比扫描HTML更为稳定。
Scott Biggs

0

你可以这样做

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

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

0

老实说,我对代码安全性只有一点点的熟悉,所以这可能有点骇人听闻。但是对我来说,这是最通用的方法:

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

0

编译一些想法,从WifiManager更好的Kotlin解决方案中获取wifi ip :

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

另外,您可以通过以下方式获取ip4环回设备的ip地址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()

-2

根据我的测试,这是我的建议

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) {}
   }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.