Як отримати 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.