Вернуть внутренний IP из NetworkInterface Android

Я использую код для захвата IPv4-адреса, который использует мое устройство:

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().toUpperCase();
                    boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr); 
                    if (useIPv4) {
                        if (isIPv4) 
                            return sAddr;
                    } else {
                        if (!isIPv4) {
                            int delim = sAddr.indexOf('%'); // drop ip6 port suffix
                            return delim<0 ? sAddr : sAddr.substring(0, delim);
                        }
                    }
                }
            }
        }
    } catch (Exception ex) { } // for now eat exceptions
    return "";
}

Мой Samsung Galaxy Express подключен к Wi-Fi и имеет сим-карту с включенной мобильной связью.

IP-адрес, который я получаю из приведенного выше кода, — это 10-й адрес, который указывает, что телефон использует сигнал сотовой связи, когда мне нужно использовать 192-й адрес, доступный в сети.

Есть ли способ изменить приведенный выше код, чтобы выбрать 192., если он доступен? Или это телефон виноват?

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

Единственное, что помогло, это извлечь сим-карту! Я не могу ожидать, что пользователи сделают это только для того, чтобы получить внутренний адрес?

Спасибо


person Dan James Palmer    schedule 10.01.2014    source источник
comment
Эм, вы пробовали проверить все интерфейсы? Ваш код игнорирует все, кроме первого, если только это не петлевой интерфейс.   -  person CommonsWare    schedule 10.01.2014
comment
Теперь у меня есть код, который может поместить все IP-адреса в список, который включает 192. адрес. Однако я хочу автоматически выбрать этот IP-адрес, если он доступен. Есть много способов найти индекс элемента в массиве, но я хочу найти этот элемент на основе половинного совпадения. Например, я хочу, чтобы поиск 192 в массиве не возвращался как -1, а возвращался как позиция, в которой появляется полный адрес 192, имеет ли это смысл?   -  person Dan James Palmer    schedule 10.01.2014
comment
Имеет ли это смысл? -- нет, извините, не так. У меня возникли некоторые трудности с интерпретацией вашей проблемы.   -  person CommonsWare    schedule 10.01.2014
comment
@DanJamesPalmer - Если у вас есть жестко запрограммированная зависимость от значения 192, это неправильный способ сделать это. Некоторые маршрутизаторы Wi-Fi используют диапазоны адресов 10.xyz, а другие — 172.xyz. Я дал вам код ниже, чтобы определить IP-адрес адаптера wlan0. Возможно, вы захотите изменить его, чтобы отфильтровать интерфейсы, которых вы хотите избежать, вместо того, чтобы пытаться угадать адаптер Wi-Fi. Но позвольте мне задать следующий вопрос: Что вы на самом деле пытаетесь сделать? То есть, зачем вам для начала нужно узнать свой собственный локальный IP-адрес? Возможно, есть лучший способ получить то, что вам нужно.   -  person selbie    schedule 11.01.2014
comment
Обратите внимание, что собственные интернет-операции вашего приложения будут проходить через Wi-Fi, если есть активное соединение Wi-Fi, поэтому для этого вам не нужен IP-адрес.   -  person CommonsWare    schedule 11.01.2014


Ответы (1)


Мне было бы интересно узнать, есть ли лучший способ....

Но пока ищите адрес «wlan0». Кроме того, приведенный ниже код отфильтрует для вас петлевые адреса.

List<NetworkInterface> interfaces;
try {
    interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
    for (NetworkInterface ni : interfaces)
    {
        if ((ni.isLoopback() == false) && ni.isUp() && (ni.getName().equals("wlan0")))
        {

            // enumerate ip addresses on this network interface (e.g. ni.getInetAddresses()

            // return the first one that is is Ipv4

        }
    }

Вы должны объединить приведенный выше код с вызовами android.net.ConnectivityManager, чтобы подтвердить, что вы подключены к Wi-Fi.

person selbie    schedule 10.01.2014
comment
Обратите внимание, что этот алгоритм будет иметь проблемы с устройствами, использующими Ethernet (например, OUYA, Android TV) и, возможно, другими сценариями. Рассчитывать на то, что wlan0 будет правильным именем, рискованно. При этом я не знаю ничего лучше. - person CommonsWare; 10.01.2014
comment
@CommonsWare - согласен на 100%. В идеале лучший способ найти наилучший интерфейс (и IP) — это просмотреть таблицу маршрутизации и найти все строки с 0.0.0.0 в столбце адреса назначения, а затем выбрать строку с наименьшей метрикой (и использовать столбец IFace таблицы маршрутизации). этот выбор). Это может работать, если перейти к NDK и выполнить все обычные системные вызовы Linux/Unix. - person selbie; 11.01.2014
comment
Но ОП сказал, что ему нужен адрес Wi-Fi, не обязательно лучший адрес. Я попросил ОП в комментариях к его вопросу определить, что он действительно пытается сделать. - person selbie; 11.01.2014