Jak uzyskać adres IP urządzenia z kodu?

383

Czy można uzyskać adres IP urządzenia za pomocą kodu?

Nilesh Tupe
źródło
5
Nie zapominaj, że jest to kolekcja o rozmiarze N i nie możesz założyć, że N == (0 || 1). Innymi słowy, nie zakładaj, że urządzenie ma tylko jeden sposób komunikowania się z siecią i nie zakładaj, że w ogóle może rozmawiać z siecią.
James Moore,
Powiązane: stackoverflow.com/questions/9481865/…
AlikElzin-kilaka
2
wersja nieprogramowa android.stackexchange.com/questions/2984/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Powinieneś dostać to z zewnętrznego serwisu ipof.in/txt jest jednym z takich serwisów
vivekv
czy można to zrobić programowo w Androidzie?
Tanmay Sahoo,

Odpowiedzi:

434

To jest mój pomocnik używany do odczytu adresów IP i MAC. Implementacja jest czysta java, ale mam blok komentarzy, w getMACAddress()którym można odczytać wartość ze specjalnego pliku systemu Linux (Android). Uruchomiłem ten kod tylko na kilku urządzeniach i emulatorze, ale daj mi znać, jeśli znajdziesz dziwne wyniki.

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

}

Uwaga: Pomysły i przykładowy kod do tej klasy Utils pochodzą z kilku postów SO i Google. Wyczyściłem i połączyłem wszystkie przykłady.

Kto ja
źródło
17
Wymaga to interfejsu API w wersji 9 i wyższej z powodu getHardwareAddress ().
Calvin
2
Problemy - ostrzeżenia o strzale włączone toUpperCase(). Łapanie Exceptionjest zawsze niejasne (a metody pomocnicze i tak powinny rzucać i pozwolić osobie dzwoniącej poradzić sobie z wyjątkiem - jednak tego nie zmieniło). Formatowanie: nie powinno przekraczać 80 linii. Warunkowe wykonanie getHardwareAddress()- łatka: github.com/Utumno/AndroidHelpers/commit/… . Co mówisz ?
Mr_and_Mrs_D
5
Jeśli jesteś w sieci lokalnej (np. Wi-Fi lub emulator), otrzymasz prywatny adres IP. Można uzyskać adres IP serwera proxy poprzez zamówienie na stronie internetowej określonej który daje adres proxy, np whatismyip.akamai.com
Julien Kronegg
1
Działa to idealnie dla mnie z prawdziwym urządzeniem korzystającym z Wi-Fi. Wielkie dzięki, stary
Pan Neo
5
Otrzymuję złe wyniki na Nexusie 6 podczas próby uzyskania adresu IP. Mam interfejs sieciowy o nazwie „nazwa: dummy0 (dummy0)”, który podaje adres w formacie „/ XX :: XXXX: XXXX: XXXX: XXXX% dummy0”, istnieje również prawdziwy interfejs sieciowy, który odpowiada wlan0, ale ponieważ „manekin” zdarza się jako pierwszy, zawsze otrzymuję ten adres manekina
Julian Suarez
201

To działało dla mnie:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Nilesh Tupe
źródło
10
ten działa dla mnie. wymaga jednak uprawnienia „ACCESS_WIFI_STATE” i jak napisał „Umair”, użycie listy nie jest potrzebne.
deweloper Androida
13
formatIpAddress jest z jakiegoś powodu nieaktualny. Co zamiast tego należy zastosować?
programista Androida
8
Z dokumentacji: Użyj getHostAddress(), która obsługuje zarówno adresy IPv4, jak i IPv6. Ta metoda nie obsługuje adresów IPv6.
Ryan R
7
jak korzystać z getHostAddress () w celu uzyskania adresu IP serwera i klienta @RyanR?
gumuruh
42
czy to nadal będzie działać, nawet jeśli użytkownik używa danych zamiast Wi-Fi?
PinoyCoder,
65

Użyłem następującego kodu: Powodem, dla którego użyłem hashCode, było to, że dostawałem pewne wartości śmieci dołączane do adresu IP, gdy go używałem getHostAddress. Ale hashCodedziałało dla mnie naprawdę dobrze, ponieważ wtedy mogę użyć Formattera, aby uzyskać adres IP z prawidłowym formatowaniem.

Oto przykładowy wynik:

1. przy użyciu getHostAddress:***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2. korzystanie hashCodei Formatter: ***** IP=238.194.77.212

Jak widać 2. metody dają mi dokładnie to, czego potrzebuję.

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
źródło
1
getHostAddress()zrobi to samo co dodane przez ciebie narzędzie do formatowania.
Phil
10
Używanie hashCode jest po prostu błędne i zwraca bzdury. Zamiast tego użyj InetAddress.getHostAddress ().
Pointer Null
zmień tę część: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, „***** IP =” + ip); return ip; } z tym: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ())) {return inetAddress .getHostAddress (). toString (); } da ci to prawidłowy format ip
Chuy47
Kod zwraca tylko pierwszy adres IP, telefon może mieć jednocześnie adres do telefonu komórkowego, WIFI i BT
reker
@ Chuy47 mówi, że nie można znaleźć
adresu
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;
}

Dodałem inetAddressinstanceof, Inet4Addressaby sprawdzić, czy jest to adres IPv4.

evertvandenbruel
źródło
uratował mi dzień! dzięki. To jedyny kod działający na samsung s7 edge
Dhananjay Sarsonia,
To jest prawdziwa odpowiedź, a nie powyżej, która ma tylko interfejs WiFi.
nigoning
To naprawdę powinna być poprawna odpowiedź, działa zarówno w przypadku sieci Wi-Fi, jak i mobilnej i używa „getHostAddress” zamiast niestandardowego formatowania.
Balázs Gerlei
Jednak pobiera moje lokalne IP, potrzebuję mojego publicznego IP (jak wierzę, OP również potrzebuje)
FabioR
53

Chociaż istnieje poprawna odpowiedź, dzielę się tutaj moją odpowiedzią i mam nadzieję, że w ten sposób będzie wygodniej.

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
źródło
4
Dzięki! Formater jest przestarzały i naprawdę nie miałem ochoty pisać prostej logiki bitowej.
William Morrison
4
Działa świetnie, ale wymaga pozwolenia WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust
1
Używam formatu, ale to nie działa. To jest wspaniałe! Naprawdę doceniony. Czy możesz wyjaśnić, co zostało zrobione w ostatniej linii. Wiem% d.% D.% D.% D jakkolwiek inni? Dzięki
Günay Gültekin
1
Nie, to nie odpowiada bezpośrednio na OP. Ponieważ nie wszystkie urządzenia z Androidem używają Wi-Fi do łączenia się z Internetem. Może mieć NATed LAN w sieci Ethernet lub BT, a nie NATed WAN itp.
nyconing
31

Poniższy kod może ci pomóc. Nie zapomnij dodać uprawnień ..

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

Dodaj poniżej uprawnienia w pliku manifestu.

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

szczęśliwego kodowania !!

Satyam
źródło
6
Hej, to zwraca niepoprawną wartość, taką jak: „fe80 :: f225: b7ff: fe8c: d357% wlan0”
Jorgesys
@Jorgesys sprawdza odpowiedź evertvandenbruel, gdzie dodał inetAddress instanceof Inet4Address
temirbek
3
zmień jeśli warunek taki jak ten, aby uzyskać poprawny adres ip: if (! inetAddress.isLoopbackAddress () && inetAddress instanceof Inet4Address)
Rajesh.k
Kod zwraca tylko pierwszy adres IP, telefon może mieć jednocześnie adres do telefonu komórkowego, WIFI i BT
reker
Jeśli masz hotspot, możesz uzyskać więcej niż jeden ip
Harsha
16

Nie trzeba dodawać uprawnień, jak w przypadku dotychczas dostarczonych rozwiązań. Pobierz tę stronę jako ciąg:

http://www.ip-api.com/json

lub

http://www.telize.com/geoip

Pobieranie strony internetowej jako ciągu można wykonać za pomocą kodu Java:

http://www.itcuties.com/java/read-url-to-string/

Analizuj obiekt JSON w następujący sposób:

https://stackoverflow.com/a/18998203/1987258

Atrybut json „zapytanie” lub „ip” zawiera adres IP.

Daan
źródło
2
to wymaga połączenia z Internetem. Duży problem
David,
4
Dlaczego to duży problem? Oczywiście potrzebujesz połączenia z Internetem, ponieważ adres IP jest technicznie powiązany z takim połączeniem. Jeśli wyjdziesz z domu i pójdziesz do restauracji, użyjesz innego połączenia internetowego, a tym samym innego adresu IP. Nie potrzebujesz niczego, aby dodać więcej, takich jak ACCESS_NETWORK_STATE lub ACCESS_WIFI_STATE. Połączenie internetowe to jedyne pozwolenie, którego potrzebujesz do dostarczonego przeze mnie rozwiązania.
Daan,
2
Która domena? Jeśli ip-api.com nie działa, możesz użyć telize.com jako rezerwowego. W przeciwnym razie możesz użyć api.ipify.org . Jest również dostępny tutaj (nie json): ip.jsontest.com/?callback=showIP . Wiele aplikacji korzysta z domen, które mają gwarantować pozostanie online; to normalne. Jeśli jednak użyjesz opcji awaryjnych, jest bardzo mało prawdopodobne, że wystąpi problem.
Daan
3
Oryginalny punkt Davida nadal obowiązuje. Co jeśli jesteś w sieci wewnętrznej, która nie ma dostępu do Internetu.
hiandbaii
2
Nigdy o tym nie myślałem, ponieważ nie znam żadnego praktycznego celu aplikacji, która zdecydowanie potrzebuje sieci, ale powinna działać bez internetu (może jest, ale nie widzę tego na urządzeniach mobilnych).
Daan
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;
        }
Salman Khalid
źródło
1
czy to możliwe, że zwróciłoby to prywatną sieć ip z interfejsu Wi-Fi, np. 192.168.0.x? czy zawsze zwróci zewnętrzny adres IP, który byłby używany w Internecie?
Ben H
9

Metoda getDeviceIpAddress zwraca adres IP urządzenia i preferuje adres interfejsu Wi-Fi, jeśli jest podłączony.

  @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;
    }
Ruslan Podurets
źródło
4

Jest to przeróbka tej odpowiedzi, która usuwa nieistotne informacje, dodaje pomocne komentarze, jaśniej nazywa zmienne i poprawia logikę.

Nie zapomnij podać następujących uprawnień:

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

}
Jon McClung
źródło
4

minimalistyczna wersja kotlin

fun getIpv4HostAddress(): String {
    NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
        networkInterface.inetAddresses?.toList()?.find {
            !it.isLoopbackAddress && it is Inet4Address
        }?.let { return it.hostAddress }
    }
    return ""
}
Raphael C.
źródło
3
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();
mridul
źródło
3

Wystarczy użyć Volley, aby uzyskać adres IP z tej strony

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);
Sohel Mahmud
źródło
2

Ostatnio adres IP jest nadal zwracany przez getLocalIpAddress()pomimo odłączenia od sieci (brak wskaźnika usługi). Oznacza to, że adres IP wyświetlany w Ustawieniach> Informacje o telefonie> Status różni się od tego, co myślała aplikacja.

Zaimplementowałem obejście, dodając ten kod przed:

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

Czy to komukolwiek dzwoni?

slash33
źródło
2

w Kotlinie, bez Formatera

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 ""
}
zeina
źródło
2

W Twojej aktywności następująca funkcja getIpAddress(context)zwraca adres IP telefonu:

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
źródło
Dostaję 0.0.0.0
natsumiyu
Czy Twój telefon jest podłączony do sieci Wi-Fi? Która wartość jest zwracana, jeśli wywołasz wifiManager.getConnectionInfo (). GetSSID ()?
matdev
Czy będzie działać na urządzeniu podłączonym do danych mobilnych, a nie WiFi?
Sergey
Nie, ta metoda działa tylko wtedy, gdy urządzenie jest podłączone do Wi
matdev
1

Oto wersja @Nilesh i @anargund firmy Kotlin

  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
źródło
1
Jeśli taki jest twój styl kodu w prawdziwych projektach, sugeruję przeczytanie „czystego kodu” przez Roberta Martina
Ahmed Adel Ismail
1

Urządzenie może mieć kilka adresów IP, a używany w konkretnej aplikacji może nie być adresem IP, który zobaczą serwery odbierające żądanie. Rzeczywiście, niektórzy użytkownicy używają VPN lub proxy, takich jak Cloudflare Warp .

Jeśli Twoim celem jest uzyskanie adresu IP pokazanego przez serwery odbierające żądania z Twojego urządzenia, najlepiej jest wysłać zapytanie do usługi geolokalizacji IP, takiej jak Ipregistry (zastrzeżenie: pracuję dla firmy), za pomocą jej klienta Java:

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

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

Oprócz tego, że jest naprawdę prosty w użyciu, otrzymujesz dodatkowe informacje, takie jak kraj, język, walutę, strefę czasową adresu IP urządzenia i możesz określić, czy użytkownik korzysta z serwera proxy.

Laurent
źródło
1

Jest to najłatwiejszy i najprostszy sposób, jaki kiedykolwiek istnieje w Internecie ... Po pierwsze, dodaj to uprawnienie do pliku manifestu ...

  1. "INTERNET"

  2. „ACCESS_NETWORK_STATE”

dodaj to do pliku onCreate działania ...

    getPublicIP();

Teraz dodaj tę funkcję do swojej klasy 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();

    }

Zia Muhammad
źródło
urls.get (0) zawiera twój publiczny adres IP.
Zia Muhammad
Musisz zadeklarować w swoim pliku aktywności w następujący sposób: ArrayList <String> urls = new ArrayList <String> (); // przeczytanie każdej linii
Zia Muhammad
0

Jeśli masz powłokę; ifconfig eth0 działał również na urządzeniu x86

RzR
źródło
0

Sprawdź ten kod ... Za pomocą tego kodu. dostaniemy ip z mobilnego internetu ...

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
źródło
0

Nie używam Androida, ale poradzę sobie z tym w zupełnie inny sposób.

Wyślij zapytanie do Google, na przykład: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

I odnieś się do pola HTML, w którym zamieszczona jest odpowiedź. Możesz również wysłać zapytanie bezpośrednio do źródła.

Google najbardziej lubi przebywać tam dłużej niż Twoja aplikacja.

Pamiętaj tylko, że być może Twój użytkownik nie ma w tym momencie Internetu, co chciałbyś mieć!

Powodzenia

Makab
źródło
Ciekawy! I założę się, że Google ma jakieś wywołanie API, które zwróci twój adres IP, który będzie bardziej stabilny niż skanowanie HTML.
Scott Biggs,
0

Możesz to zrobić

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);
Raphaël Maguet
źródło
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);
        }
    }
Ashish Kumar
źródło
0

Szczerze mówiąc, jestem trochę zaznajomiony z bezpieczeństwem kodu, więc może to być hackowanie. Ale dla mnie jest to najbardziej wszechstronny sposób:

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();
    }
} }
Tyler Depies-Bobrowitz
źródło
0

Kompilowanie niektórych pomysłów na uzyskanie ip wifi z WifiManagerładniejszego rozwiązania 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))
      }
    }
  }
}

Alternatywnie można uzyskać adresy IP urządzeń zwrotnych ip4 za pośrednictwem 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
źródło
-2

Na podstawie tego, co przetestowałem, jest to moja propozycja

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
źródło