Wie erhalte ich die IP-Adresse des Geräts aus dem Code?

384

Ist es möglich, die IP-Adresse des Geräts mit einem Code abzurufen?

Nilesh Tupe
quelle
5
Vergessen Sie nicht, dass dies eine Sammlung der Größe N ist und Sie nicht davon ausgehen können, dass N == (0 || 1) ist. Mit anderen Worten, nehmen Sie nicht an, dass ein Gerät nur eine Möglichkeit hat, mit einem Netzwerk zu kommunizieren, und gehen Sie nicht davon aus, dass es überhaupt eine Möglichkeit hat, mit einem Netzwerk zu kommunizieren.
James Moore
Siehe auch
AlikElzin-kilaka
2
nicht programmatische Version android.stackexchange.com/questions/2984/…
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功
Sie sollten es von einem externen Dienst erhalten ipof.in/txt ist ein solcher Dienst
vivekv
ist es möglich, es programmgesteuert in Android zu bekommen?
Tanmay Sahoo

Antworten:

434

Dies ist mein Hilfsdienst zum Lesen von IP- und MAC-Adressen. Die Implementierung ist Pure-Java, aber ich habe einen Kommentarblock, in getMACAddress()dem der Wert aus der speziellen Linux-Datei (Android) gelesen werden kann. Ich habe diesen Code nur auf wenigen Geräten und Emulator ausgeführt, aber lassen Sie mich hier wissen, wenn Sie seltsame Ergebnisse finden.

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

}

Haftungsausschluss: Ideen und Beispielcode für diese Utils-Klasse stammen aus mehreren SO-Posts und von Google. Ich habe alle Beispiele bereinigt und zusammengeführt.

Wen
quelle
17
Dies erfordert API-Level 9 und höher aufgrund von getHardwareAddress ().
Calvin
2
Probleme - Flusenwarnungen an toUpperCase(). Das Fangen Exceptionist immer zweifelhaft (und Hilfsmethoden sollten trotzdem werfen und den Anrufer mit der Ausnahme befassen lassen - hat dies jedoch nicht geändert). Formatierung: sollte nicht mehr als 80 Zeilen umfassen. Bedingte Ausführung für getHardwareAddress()- Patch: github.com/Utumno/AndroidHelpers/commit/… . Was du sagst ?
Mr_and_Mrs_D
5
Wenn Sie sich in einem lokalen Netzwerk befinden (z. B. WLAN oder Emulator), erhalten Sie eine private IP-Adresse. Sie können die Proxy-IP-Adresse durch eine Anfrage an eine bestimmte Website erhalten, die Ihnen die Proxy-Adresse gibt, z. B. whatismyip.akamai.com
Julien Kronegg
1
Dies funktioniert perfekt für mich mit einem echten Gerät, das Wifi verwendet. Vielen Dank, Bruder
Herr Neo
5
Ich erhalte auf einem Nexus 6 schlechte Ergebnisse, wenn ich versuche, eine IP-Adresse zu erhalten. Ich habe ein NetworkInterface mit dem Namen "name: dummy0 (dummy0)", das eine Adresse mit dem Format "/ XX :: XXXX: XXXX: XXXX: XXXX% dummy0" angibt. Es gibt aber auch eine echte Netzwerkschnittstelle, die wlan0 entspricht da der "Dummy" zuerst passiert, bekomme ich immer diese Dummy-Adresse
Julian Suarez
201

Das hat bei mir funktioniert:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Nilesh Tupe
quelle
10
Dieser arbeitet für mich. Es benötigt jedoch die Berechtigung "ACCESS_WIFI_STATE" und wie "Umair" schrieb, ist die Verwendung der Liste nicht erforderlich.
Android-Entwickler
13
formatIpAddress ist aus irgendeinem Grund veraltet. Was sollte stattdessen verwendet werden?
Android-Entwickler
8
Aus den Dokumenten: Verwenden Sie getHostAddress()diese Option , die sowohl IPv4- als auch IPv6-Adressen unterstützt. Diese Methode unterstützt keine IPv6-Adressen.
Ryan R
7
Wie verwende ich getHostAddress (), um die Server- und Client-IP-Adresse @RyanR abzurufen?
Gumuruh
42
Funktioniert dies auch dann, wenn der Benutzer Daten anstelle von WLAN verwendet?
PinoyCoder
65

Ich habe folgenden Code verwendet: Der Grund, warum ich hashCode verwendet habe, war, dass bei der Verwendung einige Garbage-Werte an die IP-Adresse angehängt wurden getHostAddress. AberhashCode hat wirklich gut für mich funktioniert, da ich dann Formatter verwenden kann, um die IP-Adresse mit der richtigen Formatierung zu erhalten.

Hier ist die Beispielausgabe:

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

2.Verwenden hashCodeund Formatter: ***** IP=238.194.77.212

Wie Sie sehen können, gibt mir die 2. Methode genau das, was ich brauche.

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
quelle
1
getHostAddress()wird das gleiche tun wie das Formatierungsmaterial, das Sie hinzugefügt haben.
Phil
10
Die Verwendung von hashCode ist einfach falsch und gibt Unsinn zurück. Verwenden Sie stattdessen InetAddress.getHostAddress ().
Zeiger Null
Ändern Sie diesen Teil: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); return ip; } mit diesem: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ())) {return inetAddress .getHostAddress (). toString (); } Dies gibt Ihnen das richtige IP-Format
Chuy47
Der Code gibt nur die erste IP zurück, ein Telefon kann gleichzeitig Celluar-, WIFI- und BT-Adresse haben
reker
@ Chuy47 es heißt InetAddressUtils kann nicht gefunden werden
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;
}

Ich habe inetAddressinstanceof hinzugefügt Inet4Address, um zu überprüfen, ob es sich um eine IPv4-Adresse handelt.

evertvandenbruel
quelle
hat meinen Tag gerettet! Vielen Dank. Es ist der einzige Code, der an Samsung S7 Edge arbeitet
Dhananjay Sarsonia
Dies ist eine echte Antwort, anstatt oben nur die WiFi-Schnittstelle zu bekommen.
Nyconing
Dies sollte wirklich die richtige Antwort sein. Es funktioniert sowohl für WLAN als auch für Mobilfunknetze und verwendet "getHostAddress" anstelle einer benutzerdefinierten Formatierung.
Balázs Gerlei
Allerdings bekommt es meine lokale IP, ich brauche meine öffentliche IP (wie ich glaube, OP braucht auch)
FabioR
53

Obwohl es eine richtige Antwort gibt, teile ich meine Antwort hier und hoffe, dass dieser Weg mehr Komfort bietet.

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
quelle
4
Vielen Dank! Der Formatierer ist veraltet und ich hatte wirklich keine Lust, einfache Bitlogik zu schreiben.
William Morrison
4
Funktioniert hervorragend, erfordert jedoch die Erlaubnis von WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust
1
Ich benutze den Formaater, aber er funktioniert nicht. Es ist toll! Sehr geschätzt. Können Sie erklären, was in der letzten Zeile getan wird? Ich kenne% d.% D.% D.% D aber andere? Danke
Günay Gültekin
1
Nein, das antwortet nicht direkt auf OP. Weil nicht alle Android-Geräte WiFi verwenden, um eine Verbindung zum Internet herzustellen. Möglicherweise hat es NATed LAN über Ethernet oder BT und keine NATed WAN-Verbindung usw.
Nyconing
31

Der folgende Code könnte Ihnen helfen. Vergessen Sie nicht, Berechtigungen hinzuzufügen.

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

Fügen Sie die unten stehende Berechtigung in die Manifestdatei ein.

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

Viel Spaß beim Codieren !!

Satyam
quelle
6
Hey, das gibt einen falschen Wert zurück wie: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
Jorgesys
@Jorgesys überprüfen Sie auf evertvandenbruels Antwort, wo er inetAddress Instanz von Inet4Address hinzufügte
temirbek
3
Ändern Sie die if-Bedingung wie folgt, um die korrekte IP zu erhalten: if (! inetAddress.isLoopbackAddress () && inetAddress-Instanz von Inet4Address)
Rajesh.k
Der Code gibt nur die erste IP zurück, ein Telefon kann gleichzeitig eine Handy-, WIFI- und BT-Adresse haben
reker
Wenn Sie einen Hotspot haben, erhalten Sie möglicherweise mehr als eine IP
Harsha
16

Sie müssen keine Berechtigungen hinzufügen, wie dies bei den bisher bereitgestellten Lösungen der Fall ist. Laden Sie diese Website als Zeichenfolge herunter:

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

oder

http://www.telize.com/geoip

Das Herunterladen einer Website als Zeichenfolge kann mit Java-Code erfolgen:

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

Analysieren Sie das JSON-Objekt folgendermaßen:

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

Das json-Attribut "query" oder "ip" enthält die IP-Adresse.

Daan
quelle
2
Dies erfordert eine Internetverbindung. Großes Problem
David
4
Warum ist das ein großes Problem? Natürlich benötigen Sie eine Internetverbindung, da eine IP-Adresse technisch mit einer solchen Verbindung zusammenhängt. Wenn Sie Ihr Haus verlassen und in ein Restaurant gehen, verwenden Sie eine andere Internetverbindung und damit eine andere IP-Adresse. Sie brauchen nichts hinzuzufügen, um mehr wie ACCESS_NETWORK_STATE oder ACCESS_WIFI_STATE hinzuzufügen. Eine Internetverbindung ist die einzige Erlaubnis, die Sie für die von mir bereitgestellte Lösung benötigen.
Daan
2
Welche Domain? Wenn ip-api.com nicht funktioniert, können Sie telize.com als Fallback verwenden. Andernfalls können Sie api.ipify.org verwenden . Es ist auch hier verfügbar (nicht json): ip.jsontest.com/?callback=showIP . Viele Apps verwenden Domains, die garantiert online bleiben. das ist normal. Wenn Sie jedoch Fallbacks verwenden, ist es sehr unwahrscheinlich, dass ein Problem auftritt.
Daan
3
Davids ursprünglicher Punkt steht noch. Was ist, wenn Sie sich in einem internen Netzwerk befinden, das keinen Internetzugang hat?
Hiandbaii
2
Ich habe nie darüber nachgedacht, weil ich keinen praktischen Zweck einer App kenne, die definitiv ein Netzwerk benötigt, aber ohne Internet funktionieren sollte (vielleicht gibt es sie, aber ich sehe sie nicht für mobile Geräte).
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
quelle
1
Ist es möglich, dass dies die IP des privaten Netzwerks von der WLAN-Schnittstelle zurückgibt, wie z. B. 192.168.0.x? oder wird immer die externe IP-Adresse zurückgegeben, die im Internet verwendet wird?
Ben H
9

Die Methode getDeviceIpAddress gibt die IP-Adresse des Geräts zurück und bevorzugt die WLAN-Schnittstellenadresse, wenn eine Verbindung besteht.

  @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
quelle
4

Dies ist eine Überarbeitung dieser Antwort, bei der irrelevante Informationen entfernt, hilfreiche Kommentare hinzugefügt, Variablen klarer benannt und die Logik verbessert werden.

Vergessen Sie nicht, die folgenden Berechtigungen anzugeben:

<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
quelle
4

Kotlin minimalistische Version

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

Verwenden Sie einfach Volley, um die IP von dieser Seite zu erhalten

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
quelle
2

In letzter Zeit wird eine IP-Adresse immer noch zurückgegeben, getLocalIpAddress()obwohl sie vom Netzwerk getrennt wurde (keine Dienstanzeige). Dies bedeutet, dass die unter Einstellungen> Über Telefon> Status angezeigte IP-Adresse von der Meinung der Anwendung abweicht.

Ich habe eine Problemumgehung implementiert, indem ich diesen Code zuvor hinzugefügt habe:

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

Läutet das jemandem eine Glocke?

slash33
quelle
2

in Kotlin ohne Formatierer

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
quelle
2

In Ihrer Aktivität gibt die folgende Funktion getIpAddress(context)die IP-Adresse des Telefons zurück:

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
quelle
Ich bekomme
0.0.0.0
Ist Ihr Telefon mit einem WLAN verbunden? Welcher Wert wird zurückgegeben, wenn Sie wifiManager.getConnectionInfo (). GetSSID () aufrufen?
Matdev
Funktioniert es für Geräte, die mit mobilen Daten verbunden sind, nicht für WLAN?
Sergey
Nein, diese Methode funktioniert nur, wenn das Gerät mit WiFi verbunden ist
matdev
1

Hier ist die Kotlin-Version von @Nilesh und @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
quelle
1
Wenn dies Ihr Codestil in realen Projekten ist, empfehle ich Ihnen, "sauberen Code" von Robert Martin
Ahmed Adel Ismail
1

Ein Gerät verfügt möglicherweise über mehrere IP-Adressen, und die in einer bestimmten App verwendete IP-Adresse ist möglicherweise nicht die IP-Adresse, die Server, die die Anforderung empfangen, sehen. In der Tat verwenden einige Benutzer ein VPN oder einen Proxy wie Cloudflare Warp .

Wenn Sie die IP-Adresse abrufen möchten , die von Servern angezeigt wird, die Anforderungen von Ihrem Gerät empfangen, sollten Sie am besten einen IP- Geolokalisierungsdienst wie Ipregistry abfragen (Haftungsausschluss: Ich arbeite für das Unternehmen) mit seinem Java-Client :

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

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

Sie sind nicht nur sehr einfach zu bedienen, sondern erhalten auch zusätzliche Informationen wie Land, Sprache, Währung, Zeitzone für die Geräte-IP und können feststellen, ob der Benutzer einen Proxy verwendet.

Laurent
quelle
1

Dies ist der einfachste und einfachste Weg, den es jemals im Internet gab ... Fügen Sie zunächst diese Berechtigung zu Ihrer Manifestdatei hinzu ...

  1. "INTERNET"

  2. "ACCESS_NETWORK_STATE"

Fügen Sie dies in die onCreate-Datei von Activity ein.

    getPublicIP();

Fügen Sie diese Funktion nun Ihrer MainActivity.class hinzu.

    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
quelle
urls.get (0) enthält Ihre öffentliche IP-Adresse.
Zia Muhammad
Sie müssen in Ihrer Aktivitätsdatei Folgendes deklarieren: ArrayList <String> urls = new ArrayList <String> (); // um jede Zeile zu lesen
Zia Muhammad
0

Wenn Sie eine Muschel haben; ifconfig eth0 funktionierte auch für x86-Geräte

RzR
quelle
0

Bitte überprüfen Sie diesen Code ... Verwenden Sie diesen Code. Wir werden IP aus dem mobilen Internet bekommen ...

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
quelle
0

Ich mache kein Android, aber ich würde das ganz anders angehen.

Senden Sie eine Anfrage an Google, etwa: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

Lesen Sie auch das HTML-Feld, in dem die Antwort veröffentlicht wird. Sie können auch direkt an die Quelle abfragen.

Google wird am liebsten länger als Ihre Anwendung dort sein.

Denken Sie daran, es könnte sein, dass Ihr Benutzer zu diesem Zeitpunkt kein Internet hat. Was möchten Sie tun?

Viel Glück

Makab
quelle
Interessant! Und ich wette, dass Google eine Art API-Aufruf hat, der Ihre IP zurückgibt, was stabiler ist als das Scannen von HTML.
Scott Biggs
0

Du kannst das

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
quelle
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
quelle
0

Ehrlich gesagt bin ich mit der Codesicherheit nur wenig vertraut, daher kann dies hackig sein. Aber für mich ist dies der vielseitigste Weg, dies zu tun:

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
quelle
0

Zusammenstellung einiger Ideen, um die WLAN-IP- WifiManagerAdresse in einer schöneren Kotlin-Lösung zu erhalten:

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

Alternativ können Sie die IP-Adressen von IP4-Loopback-Geräten über Folgendes abrufen 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
quelle
-2

Basierend auf dem, was ich getestet habe, ist dies mein Vorschlag

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
quelle