Получить мой IP-адрес Wi-Fi Android

Как я могу получить IP-адрес моего телефона, когда он подключен через Wi-Fi?

Я нашел метод здесь, но он возвращает что-то вроде 24.182.239.255, даже если я подключен к Wi-Fi и ожидаю что-то вроде 192.168.1.10.

Я хотел бы что-то вроде:

if (you are under wifi)
    String ip4 = getWifiIP()
else
    String ip4 = getIPAddress with the method linked before

Большое спасибо!


person Luigi Tiburzi    schedule 24.05.2013    source источник
comment
Кажется, вы ожидаете частный IP. Это поможет. stackoverflow.com/ вопросы/6064510/   -  person Siddharth N    schedule 24.05.2013


Ответы (9)


Если вы хотите получить частный IP-адрес вашего устройства при подключении к Wi-Fi, вы можете попробовать это.

WifiManager wifiMgr = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
int ip = wifiInfo.getIpAddress();
String ipAddress = Formatter.formatIpAddress(ip);

Обязательно добавьте разрешение

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

к вашему манифесту.

person Siddharth N    schedule 24.05.2013
comment
formatIpAddress() устарел. См. решение Digital Rounin ниже, используя вместо этого InetAddress.getHostAddress(). - person Emmanuel; 20.12.2013
comment
только для новичков: это должно быть getSystemService(Context.WIFI_SERVICE) - person 10101010; 26.12.2013
comment
Endiannes является важным фактором, приведенный выше код вернет обратный IP-адрес на оборудовании с прямым порядком байтов. Проверьте ответ Digital Rounin ниже для правильного метода. Или stackoverflow.com/questions/29937433/ для более короткого метода (который возвращает ip как int, но в правильном порядке). - person Abraham Philip; 03.01.2016
comment
Смотрите мой ответ ниже. Он получит IP-адрес активной ссылки, независимо от Wi-Fi или мобильного телефона. - person Yong; 15.06.2018
comment
Спасибо за этот ответ, он также привел к решению моего вопроса. Я искал тот же ответ, но с Кордовой. Чтобы получить IP-адрес устройства с помощью Cordova, попробуйте использовать следующий модуль: npmjs .com/package/cordova-plugin-android-wifi-manager - person user3067533; 18.06.2019

Поэтому следует учитывать, что Formatter.formatIpAddress(int) устарел:

Этот метод устарел на уровне API 12. Используйте getHostAddress(), который поддерживает адреса IPv4 и IPv6. Этот метод не поддерживает адреса IPv6.

Таким образом, использование formatIpAddress(int), вероятно, не является хорошим долгосрочным решением, хотя оно будет работать.

Вот потенциальное решение, если вы хотите получить IP-адрес для интерфейса WiFi:

protected String wifiIpAddress(Context context) {
    WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
    int ipAddress = wifiManager.getConnectionInfo().getIpAddress();

    // Convert little-endian to big-endianif needed
    if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
        ipAddress = Integer.reverseBytes(ipAddress);
    }

    byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray();

    String ipAddressString;
    try {
        ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress();
    } catch (UnknownHostException ex) {
        Log.e("WIFIIP", "Unable to get host address.");
        ipAddressString = null;
    }

    return ipAddressString;
}

Как указывалось в предыдущих ответах, вам необходимо установить в файле AndroidManifest.xml следующее:

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

Обратите внимание, что это только пример решения. Вы должны потратить время на проверку нулевых значений и т. д., чтобы убедиться, что UX работает гладко.

Ирония заключается в том, что, с одной стороны, Google отказывается от поддержки formatIpAddress(int), но по-прежнему имеет getIpAddress() по-прежнему возвращает целочисленное значение. IP-адрес, являющийся целым числом, также исключает его совместимость с IPv6.

Далее следует тот факт, что порядок байтов может быть проблемой, а может и не быть. Я протестировал только три устройства, и все они были с прямым порядком байтов. Кажется, порядок следования байтов может варьироваться в зависимости от оборудования, даже если мы работаем на виртуальных машинах, это все еще может быть проблемой. Поэтому, чтобы быть в безопасности, я добавил в код проверку порядка байтов.

getByAddress(byte[]) выглядит так: хотите, чтобы целочисленное значение было с обратным порядком байтов. Из исследования этого видно, что сетевой порядок байтов имеет обратный порядок байтов. Имеет смысл, поскольку адрес вроде 192.168.12.22 является числом с обратным порядком байтов.


Ознакомьтесь с проектом HammerNet на GitHub. Он реализует приведенный выше код вместе с кучей проверок работоспособности, возможностью обработки значений по умолчанию для AVD, модульных тестов и других вещей. Мне пришлось реализовать это для моего приложения, и я решил открыть библиотеку.

person pedrohdz    schedule 05.09.2013
comment
невозможно импортировать BigInteger в Android Studio. Я знаю, это странно, но так случилось. - person 10101010; 26.12.2013
comment
Преобразование порядка байтов на самом деле очень важно для устройств Nexus 5 и более. Спасибо ! - person Danpe; 16.07.2015
comment
WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE) Это все еще немного лучше. - person Denis; 15.06.2017
comment
Это приводит к обратному IP-адресу... кто-нибудь еще? - person ElliotM; 16.05.2018
comment
@ElliotM Нет, результатом является правильный удобочитаемый IP-адрес. Вы проводили тест на конкретном/экзотическом устройстве? - person Darkendorf; 18.03.2020
comment
@Darkendorf ага - person ElliotM; 18.03.2020

Это даст вам WiFi IPv4, IPv6 или оба.

public static Enumeration<InetAddress> getWifiInetAddresses(final Context context) {
    final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    final WifiInfo wifiInfo = wifiManager.getConnectionInfo();
    final String macAddress = wifiInfo.getMacAddress();
    final String[] macParts = macAddress.split(":");
    final byte[] macBytes = new byte[macParts.length];
    for (int i = 0; i< macParts.length; i++) {
        macBytes[i] = (byte)Integer.parseInt(macParts[i], 16);
    }
    try {
        final Enumeration<NetworkInterface> e =  NetworkInterface.getNetworkInterfaces();
        while (e.hasMoreElements()) {
            final NetworkInterface networkInterface = e.nextElement();
            if (Arrays.equals(networkInterface.getHardwareAddress(), macBytes)) {
                return networkInterface.getInetAddresses();
            }
        }
    } catch (SocketException e) {
        Log.wtf("WIFIIP", "Unable to NetworkInterface.getNetworkInterfaces()");
    }
    return null;
}

@SuppressWarnings("unchecked")
public static<T extends InetAddress> T getWifiInetAddress(final Context context, final Class<T> inetClass) {
    final Enumeration<InetAddress> e = getWifiInetAddresses(context);
    while (e.hasMoreElements()) {
        final InetAddress inetAddress = e.nextElement();
        if (inetAddress.getClass() == inetClass) {
            return (T)inetAddress;
        }
    }
    return null;
}

Использование:

final Inet4Address inet4Address = getWifiInetAddress(context, Inet4Address.class);
final Inet6Address inet6Address = getWifiInetAddress(context, Inet6Address.class);

И не забывайте:

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
person Dustin    schedule 15.01.2014

Нашел этот хороший ответ, https://gist.github.com/stickupkid/1250733

WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ipString = String.format(“%d.%d.%d.%d”, (ip & 0xff), (ip >> 8 & 0xff), (ip >> 16 & 0xff), (ip >> 24 & 0xff));
person ElliotM    schedule 15.05.2018

Судя по моим журналам сбоев, не каждое устройство возвращает MAC-адрес WiFi.

Вот более чистая версия самого популярного ответа.

final WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
final ByteBuffer byteBuffer = ByteBuffer.allocate(4);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
byteBuffer.putInt(wifiInfo.getIpAddress());
try {
final InetAddress inetAddress = InetAddress.getByAddress(null, byteBuffer.array());
} catch (UnknownHostException e) {
    //TODO: Return null?
}
person Dustin    schedule 23.01.2014
comment
Отсутствует WifiInfo wifiInfo = wifiManager.getConnectionInfo(); - person Java42; 13.04.2020

Если в терминале установлен adb, выполните:

Runtime.getRuntime.exec("adb", "shell", "getprop", "dhcp.wlan0.ipaddress");
person Thejus Krishna    schedule 17.01.2014

Добавить следующее разрешение.

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

WifiManager инициализируется в onCreate.

 WifiManager wifiMgr = (WifiManager) getContext().getSystemService(context.WIFI_SERVICE);

Используйте следующую функцию.

 public void WI-FI_IP() {
    WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
    int ip = wifiInfo.getIpAddress();
    String ipAddress = Formatter.formatIpAddress(ip);
    }
person Quantum4U    schedule 17.01.2018

Следующий код взят из настроек AOSP. Он получает IP-адрес активной ссылки, независимо от того, Wi-Fi или мобильный телефон. Это самый распространенный способ.

http://androidxref.com/8.0.0_r4/xref/packages/apps/Settings/src/com/android/settings/deviceinfo/Status.java#251

/**  
 * Returns the default link's IP addresses, if any, taking into account IPv4 and IPv6 style
 * addresses.
 * @param context the application context
 * @return the formatted and newline-separated IP addresses, or null if none.
 */
public static String getDefaultIpAddresses(ConnectivityManager cm) {                                                                      
    LinkProperties prop = cm.getActiveLinkProperties();
    return formatIpAddresses(prop);
}    

private static String formatIpAddresses(LinkProperties prop) {
    if (prop == null) return null;
    Iterator<InetAddress> iter = prop.getAllAddresses().iterator();
    // If there are no entries, return null
    if (!iter.hasNext()) return null;
    // Concatenate all available addresses, comma separated
    String addresses = "";
    while (iter.hasNext()) {
        addresses += iter.next().getHostAddress();
        if (iter.hasNext()) addresses += "\n";
    }
    return addresses;
}
person Yong    schedule 15.06.2018

Formatter.formatIpAddress(int) устарел:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();
person mridul    schedule 12.05.2015
comment
Ага. Он не будет поддерживать IPv6. - person aclowkay; 10.01.2017