Як отримати IP-адресу пристрою з коду?


383

Чи можливо отримати IP-адресу пристрою, використовуючи якийсь код?


5
Не забувайте, що це колекція розміром N, і ви не можете припустити, що N == (0 || 1). Іншими словами, не припускайте, що пристрій має лише один спосіб спілкування з мережею і не вважайте, що він взагалі має можливість спілкуватися з мережею.
Джеймс Мур



Ви повинні отримати його від зовнішньої служби ipof.in/txt - це одна така послуга
vivekv

чи можливо це отримати програмно в android?
Tanmay Sahoo

Відповіді:


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 

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

}

Відмова: Ідеї та приклад коду до цього класу Utils надходили з декількох публікацій SO та Google. Я очистив і з’єднав усі приклади.


17
Для цього потрібен API рівня 9 і вище через getHardwareAddress ().
Кальвін

2
Проблеми - попередження про вказівки на toUpperCase(). Ловля Exceptionзавжди хитрий (і допоміжні методи повинні кинути все-таки і дозволити абоненту розібратися з Винятком - не змінював це, хоча). Форматування: має бути не більше 80 рядків. Умовне виконання для getHardwareAddress()- patch: github.com/Utumno/AndroidHelpers/commit/… . Що ти сказав ?
Mr_and_Mrs_D

5
Якщо ви перебуваєте в локальній мережі (наприклад, Wi-Fi або емуляторі), ви отримаєте приватну IP-адресу. IP-адресу проксі можна отримати за допомогою запиту на певний веб-сайт, який надає вам проксі-адресу, наприклад, whatismyip.akamai.com
Julien Kronegg

1
Це ідеально підходить для мене з реальним пристроєм, що використовує Wifi. Дуже дякую, брате
містере Нео

5
Я отримую погані результати від Nexus 6 при спробі отримати IP-адресу. У мене є мережевий інтерфейс з назвою "name: dummy0 (dummy0)", який дає адресу у форматі "/ 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 developer

13
З певних причин formatIpAddress застарілий. Що слід використовувати замість цього?
андроїд розробник

8
З Документів: Використовуйте getHostAddress(), що підтримує як IPv4, так і IPv6 адреси. Цей метод не підтримує адреси IPv6.
Ryan R

7
як використовувати getHostAddress () для отримання ip-адреси сервера та клієнта @RyanR?
гумарух

42
це все ще буде працювати, навіть якщо користувач використовує дані замість wifi?
PinoyCoder

65

Я використовував наступний код: Причиною того, що я використовував hashCode, було те, що я отримував деякі значення сміття, додані до ip-адреси, коли я використовував getHostAddress. АлеhashCode працював дуже добре для мене, оскільки тоді я можу використовувати Formatter, щоб отримати IP-адресу з правильним форматуванням.

Ось приклад результату:

1.використовуючи getHostAddress :***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2.користування hashCodeіFormatter : ***** IP=238.194.77.212

Як ви бачите, 2-й метод дає мені саме те, що мені потрібно.

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()зробить те саме, що додані вами дані форматера.
Філ

10
Використання hashCode - це неправильно, і повертає дурниці. Використовуйте натомість InetAddress.getHostAddress ().
Покажчик Нуль

змінити цю частину: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); повернути ip; } з цим: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ()) {return inetAddress .getHostAddress (). toString (); } це дасть вам правильний формат ip
Chuy47

Код повертає лише перший 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-адреса.


врятував мій день! Дякую. Це єдиний код, який працює на samsung s7 edge
Dhananjay Sarsonia,

Це реальна відповідь, замість якої вище лише отримати інтерфейс WiFi.
ньяконінг

Це дійсно має бути правильною відповіддю, вона працює як для WiFi, так і для мобільної мережі, а використовує "getHostAddress" замість власного форматування.
Balázs Gerlei

Однак він отримує свій локальний IP, мені потрібен мій загальнодоступний IP (як я вважаю, потрібен і ОП)
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
Дякую! Форматер застарілий, і мені дуже не подобалося писати просту логічну біт.
Вільям Моррісон

4
Працює чудово, але вимагає дозволу WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust

1
Я використовую форматер, але це не працює. Це здорово! Дуже цінується. Чи можете ви пояснити, що робиться в останньому рядку. Я знаю,% d.% D.% D.% D, проте інші? Спасибі
Günay Gültekin

1
Ні, це не відповідає безпосередньо ОП. Тому що не всі пристрої Android, які використовують WiFi для підключення до Інтернету. Це може бути NATED LAN на Ethernet або BT, а не NATED WAN-з'єднання і т. Д.
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 екземпляр Inet4Address
temirbek

3
змінити, якщо така умова, щоб отримати правильний ip: if (! inetAddress.isLoopbackAddress () && inetAddress instanceof Inet4Address)
Rajesh.k

Код повертає лише перший IP-адресу, телефон може мати стільниковий, WIFI та BT адресу одночасно
reker

Якщо у вас є точка доступу, ви можете отримати більше одного ip
Харша,

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 "запит" або "ip" містить IP-адресу.


2
для цього потрібно підключення до Інтернету. Велика проблема
Девід

4
Чому це велика проблема? Звичайно, вам потрібне підключення до Інтернету, оскільки IP-адреса технічно пов'язана з таким з'єднанням. Якщо ви виходите з дому і заходите в ресторан, ви скористаєтесь іншим підключенням до Інтернету і, таким чином, ще однією IP-адресою. Вам не потрібно щось додати, як-от ACCESS_NETWORK_STATE або ACCESS_WIFI_STATE. Підключення до Інтернету - єдиний дозвіл, який вам потрібен для рішення, наданого мною.
Даан,

2
Який домен? Якщо ip-api.com не працює, ви можете використовувати telize.com як резервний. В іншому випадку ви можете використовувати api.ipify.org . Він також доступний тут (не json): ip.jsontest.com/?callback=showIP . Багато додатків використовують домени, які гарантовано залишаються в Інтернеті; це нормально. Однак, якщо ви використовуєте резервні копії, то це малоймовірно, що виникне проблема.
Даан

3
Початкова точка Давида досі стоїть. Що робити, якщо ви знаходитесь у внутрішній мережі, яка не має доступу до Інтернету.
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
чи можливо, що це поверне приватну мережу ip з інтерфейсу wifi, як-от 192.168.0.x? чи завжди буде повертати зовнішню ip-адресу, яка буде використовуватися в Інтернеті?
Ben H

9

Метод getDeviceIpAddress повертає ip-адресу пристрою та надає перевагу адресу Wi-Fi інтерфейсу, якщо він підключений.

  @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

kotlin мінімалістична версія

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

Останнім часом IP-адресу все одно повертається, getLocalIpAddress()незважаючи на те, що вона відключена від мережі (немає індикатора обслуговування). Це означає, що IP-адреса, що відображається в Налаштуваннях> Про телефон> Статус, відрізнялася від того, що думала програма.

Я реалізував рішення, додавши цей код раніше:

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

Це дзвонить комусь у дзвін?


2

у Котліні, без форматерів

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
натсумію

Ваш телефон підключений до мережі Wi-Fi? Яке значення повертається, якщо ви викликаєте wifiManager.getConnectionInfo (). GetSSID ()?
matdev

Чи буде це працювати для пристрою, підключеного до мобільних даних, а не Wi-Fi?
Сергій

Ні, цей метод працює лише в тому випадку, якщо пристрій підключено до WiFi
matdev

1

Ось kotlin версія @Nilesh та @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
}

1
Якщо це ваш стиль коду в реальних проектах, я пропоную вам прочитати "чистий код" від Роберта Мартіна
Ахмед Адель Ісмаїл

1

У пристрої може бути декілька IP-адрес, і тим, що використовується у певній програмі, може бути не той IP, який бачитимуть сервери, які отримують запит. Дійсно, деякі користувачі використовують VPN або проксі-сервер, наприклад Cloudflare Warp .

Якщо ваша мета - отримати IP-адресу, як показано серверами, які отримують запити від вашого пристрою, то найкраще - запитувати службу геолокації IP, наприклад Ipregistry (відмова від відповідальності: я працюю в компанії) зі своїм клієнтом Java:

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

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

Окрім того, що це дуже просто у використанні, ви отримуєте додаткову інформацію, таку як країна, мова, валюта, часовий пояс для IP пристрою, і ви можете визначити, користувач використовує проксі.


1

Це найпростіший і простий спосіб, який коли-небудь існує в Інтернеті ... Перш за все, додайте цей дозвіл у свій файл маніфесту ...

  1. "ІНТЕРНЕТ"

  2. "ACCESS_NETWORK_STATE"

додайте це до файлу 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-адресу.
Зія Мухаммад

Ви повинні оголосити у вашому файлі активності так: ArrayList <String> urls = new ArrayList <String> (); // читати кожен рядок
Зія Мухаммед

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.
Скотт Біггс

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

Складання деяких ідей, щоб отримати Wi-Fi ip з WifiManagerприємного рішення kotlin:

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

Крім того, ви можете отримати адреси ip на пристроях із зворотним зв'язком ip4 через 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) {}
   }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.