Как получить IP-адрес устройства из кода?

384

Можно ли получить IP-адрес устройства, используя некоторый код?

Нилеш Тупе
источник
5
Не забывайте, что это коллекция размера N, и вы не можете предполагать, что N == (0 || 1). Другими словами, не думайте, что у устройства есть только один способ общения с сетью, и не думайте, что у него вообще есть возможность общаться с сетью.
Джеймс Мур
Связанный: stackoverflow.com/questions/9481865/…
АликЭльзин-Килака
2
непрограммная версия android.stackexchange.com/questions/2984/…
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
Вы должны получить его от внешнего сервиса. 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. Я убрал и объединил все примеры.

Whome
источник
17
Это требует API уровня 9 и выше из-за getHardwareAddress ().
Кальвин
2
Проблемы - предупреждение о задержке toUpperCase(). Поймать Exceptionвсегда хитроумно (и вспомогательные методы должны все равно генерировать и позволить вызывающей стороне иметь дело с Исключением - хотя это и не исправлялось). Форматирование: должно быть не более 80 строк. Условное выполнение getHardwareAddress()- патч: github.com/Utumno/AndroidHelpers/commit/… . Что ты сказал ?
Mr_and_Mrs_D
5
Если вы находитесь в локальной сети (например, Wi-Fi или эмулятор), вы получите частный IP-адрес. Вы можете получить IP-адрес прокси через запрос к определенному веб-сайту, который дает вам адрес прокси-сервера, например whatismyip.akamai.com
Julien Kronegg,
1
Это прекрасно работает для меня с реальным устройством, использующим Wi-Fi. Большое спасибо, братан
Мистер Нео
5
Я получаю плохие результаты на Nexus 6 при попытке получить IP-адрес. У меня есть NetworkInterface с именем «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-разработчик
13
formatIpAddress устарел по некоторым причинам. Что следует использовать вместо этого?
разработчик Android
8
Из документов: Используйте getHostAddress(), который поддерживает адреса IPv4 и IPv6. Этот метод не поддерживает адреса IPv6.
Райан R
7
Как использовать getHostAddress () при получении IP-адреса сервера и клиента @RyanR?
Gumuruh
42
это все еще будет работать, даже если пользователь использует данные вместо Wi-Fi?
PinoyCoder,
65

Я использовал следующий код: причина, по которой я использовал hashCode, была в том, что я получал некоторые значения мусора, добавленные к IP-адресу при использовании getHostAddress. Но hashCodeдля меня это сработало очень хорошо, так как тогда я могу использовать Formatter для получения IP-адреса с правильным форматированием.

Вот пример вывода:

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

2.Using 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;
}
anargund
источник
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.

evertvandenbruel
источник
спас мой день! Спасибо. Это единственный код, работающий над samsung s7 edge
Dhananjay Sarsonia
Это реальный ответ, а не выше, который только получить интерфейс WiFi.
nyconing
Это действительно должен быть правильный ответ, он работает как для WiFi, так и для мобильной сети, и использует «getHostAddress» вместо пользовательского форматирования.
Балаш Герлей
Тем не менее, он получает мой локальный 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));
CYB
источник
4
Спасибо! Formatter устарел, и мне действительно не хотелось писать простую битовую логику.
Уильям Моррисон
4
Прекрасно работает, но требует разрешения WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Брент Фауст
1
Я использую форматер, но он не работает. Это просто супер! Очень ценится Не могли бы вы объяснить, что делается в последней строке. Я знаю% d.% D.% D.% D однако другие? Спасибо
Гюнай Гюльтекин,
1
Нах это не отвечая напрямую на ОП. Потому что не все устройства Android используют WiFi для подключения к интернету. Это может быть NAT-LAN в Ethernet или BT, а не NAT-соединение 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" />

счастливого кодирования !!

Satyam
источник
6
Эй, это возвращает неверное значение, например: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
Jorgesys
@Jorgesys проверяет ответ evertvandenbruel, где он добавил inetAddress instance Inet4Address
temirbek
3
измените условие if, чтобы получить правильный 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
это требует подключения к Интернету. Большая проблема
Дэвид
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 частной сети от интерфейса Wi-Fi, как 192.168.0.x? или он всегда будет возвращать внешний IP-адрес, который будет использоваться в Интернете?
Бен Н
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();
mridul
источник
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;
}

Это звонит кому-нибудь?

slash33
источник
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();
    }
}
matdev
источник
Я получаю 0.0.0.0
нацумию
Ваш телефон подключен к сети Wi-Fi? Какое значение возвращается, если вы вызываете wifiManager.getConnectionInfo (). GetSSID ()?
Матдев
Будет ли это работать для устройства, подключенного к Mobile Data, а не WiFi?
Сергей
Нет, этот метод работает только в том случае, если устройство подключено к WiFi
Matdev
1

Вот котлин версия @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
}
Sumit
источник
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-адреса устройства, и вы можете определить, использует ли пользователь прокси-сервер.

Laurent
источник
1

Это самый простой и простой способ, который когда-либо существовал в Интернете ... Прежде всего, добавьте это разрешение в свой файл манифеста ...

  1. «ИНТЕРНЕТ»

  2. "ACCESS_NETWORK_STATE"

добавьте это в onCreate файл Activity ..

    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

RzR
источник
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();
                    }
                }
            }
Venkat
источник
0

Я не использую Android, но я бы решил это совершенно по-другому.

Отправьте запрос в Google, например, https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip.

И обратитесь к полю HTML, где размещен ответ. Вы также можете запросить напрямую к источнику.

Google, скорее всего, будет там дольше, чем ваше приложение.

Просто помните, что у вашего пользователя в настоящее время нет интернета, что бы вы хотели сделать!

Удачи

Makab
источник
Интересно! Держу пари, что у 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()
Moritz
источник
-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) {}
   }
}
elxala
источник