Come ottenere l'indirizzo IP del dispositivo dal codice?


384

È possibile ottenere l'indirizzo IP del dispositivo utilizzando un codice?


5
Non dimenticare che si tratta di una raccolta di dimensioni N e non puoi supporre che N == (0 || 1). In altre parole, non dare per scontato che un dispositivo abbia un solo modo di parlare con una rete e non dare per scontato che abbia un modo di parlare con una rete.
James Moore,



Dovresti ottenerlo da un servizio esterno ipof.in/txt è uno di questi servizi
vivekv,

è possibile ottenerlo programmaticamente su Android?
Tanmay Sahoo,

Risposte:


434

Questo è il mio aiuto helper per leggere indirizzi IP e MAC. L'implementazione è pure-java, ma ho un blocco di commenti in getMACAddress()cui è possibile leggere il valore dallo speciale file Linux (Android). Ho eseguito questo codice solo su pochi dispositivi ed emulatore, ma fammi sapere qui se trovi risultati strani.

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

}

Disclaimer: idee e codice di esempio per questa classe Utils provengono da diversi post SO e Google. Ho pulito e unito tutti gli esempi.


17
Ciò richiede il livello API 9 e superiore a causa di getHardwareAddress ().
Calvin,

2
Problemi: avvertenze su lanugine accese toUpperCase(). La cattura Exceptionè sempre ingannevole (e i metodi di supporto dovrebbero comunque lanciare e lasciare che il chiamante gestisca l'eccezione, sebbene non l'abbia modificata). Formattazione: non dovrebbe essere più di 80 righe. Esecuzione condizionale per getHardwareAddress()- patch: github.com/Utumno/AndroidHelpers/commit/… . Cosa dici ?
Mr_and_Mrs_D,

5
Se ti trovi su una rete locale (es. Wifi o emulatore), otterrai un indirizzo IP privato. È possibile ottenere l'indirizzo IP proxy tramite una richiesta a un sito Web specifico che fornisce l'indirizzo proxy, ad esempio whatismyip.akamai.com
Julien Kronegg,

1
Questo funziona perfettamente per me con un dispositivo reale tramite Wifi. Grazie mille, fratello
Mr Neo,

5
Sto ottenendo risultati negativi da questo su un Nexus 6 quando provo a ottenere un indirizzo IP. Ho un'interfaccia di rete con nome "nome: dummy0 (dummy0)" che fornisce un indirizzo con il formato "/ XX :: XXXX: XXXX: XXXX: XXXX% dummy0", esiste anche una vera interfaccia di rete che corrisponde a wlan0, ma dato che il "manichino" accade per primo, ottengo sempre quell'indirizzo fittizio
Julian Suarez,

201

Questo ha funzionato per me:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

10
questo funziona per me. tuttavia, necessita dell'autorizzazione "ACCESS_WIFI_STATE" e, come ha scritto "Umair", non è necessario l'utilizzo dell'elenco.
sviluppatore Android

13
formatIpAddress è deprecato per qualche motivo. Cosa dovrebbe essere usato invece?
Sviluppatore Android

8
Dai documenti: Usa getHostAddress(), che supporta entrambi gli indirizzi IPv4 e IPv6. Questo metodo non supporta gli indirizzi IPv6.
Ryan R,

7
come utilizzare getHostAddress () per ottenere l'indirizzo IP del server e del client @RyanR?
Gumuruh,

42
funzionerà comunque anche se l'utente utilizza i dati anziché il wifi?
PinoyCoder,

65

Ho usato il seguente codice: Il motivo per cui ho usato hashCode era perché stavo ottenendo alcuni valori di immondizia aggiunti all'indirizzo IP quando l'ho usato getHostAddress. Ma ha hashCodefunzionato davvero bene per me dato che posso usare Formatter per ottenere l'indirizzo IP con una formattazione corretta.

Ecco l'output di esempio:

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

2.utilizzando hashCodee Formatter: ***** IP=238.194.77.212

Come puoi vedere, il 2o metodo mi dà esattamente quello che mi serve.

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

1
getHostAddress()farà lo stesso delle cose formattate che hai aggiunto.
Phil,

10
L'uso di hashCode è semplicemente sbagliato e restituisce sciocchezze. Utilizzare invece InetAddress.getHostAddress ().
Puntatore Null,

cambia questa parte: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); restituire ip; } con questo: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ())) {return inetAddress .getHostAddress (); toString (); } questo ti darà il formato ip corretto
Chuy47

Il codice restituisce solo il primo IP, un telefono può avere contemporaneamente cellulare, WIFI e indirizzo BT
reker

@ Chuy47 dice che InetAddressUtils non può essere trovato
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;
}

Ho aggiunto inetAddressinstanceof Inet4Addressper verificare se si tratta di un indirizzo ipv4.


mi ha salvato la giornata! Grazie. È l'unico codice che funziona sul Samsung S7 Edge
Dhananjay Sarsonia,

Questa è la vera risposta, invece di sopra, che ottiene solo l'interfaccia WiFi.
corso il

Questa dovrebbe davvero essere la risposta corretta, funziona sia per il WiFi che per la rete mobile e utilizza "getHostAddress" invece della formattazione personalizzata.
Balázs Gerlei

Tuttavia, ottiene il mio IP locale, ho bisogno del mio IP pubblico (poiché credo che anche OP abbia bisogno)
FabioR

53

Anche se c'è una risposta corretta, condivido la mia risposta qui e spero che in questo modo sarà più comodo.

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

4
Grazie! Il formattatore è obsoleto e non mi andava proprio di scrivere una semplice logica di bit.
William Morrison,

4
Funziona benissimo, ma richiede l'autorizzazione WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust,

1
Uso il formatore ma non funziona. È grande! Molto apprezzato. Potresti spiegare cosa viene fatto nell'ultima riga. Conosco% d.% D.% D.% D ma altri? Grazie
Günay Gültekin,

1
No, questo non risponde direttamente a OP. Perché non tutti i dispositivi Android utilizzano WiFi per connettersi a Internet. Potrebbe avere una LAN NATed su Ethernet, o BT e non una connessione WAN NAT, ecc.
corso il

31

Il codice di seguito potrebbe aiutarti .. Non dimenticare di aggiungere autorizzazioni ...

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

Aggiungi sotto l'autorizzazione nel file manifest.

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

buona programmazione !!


6
Ehi, questo restituisce un valore errato come: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
Jorgesys,

@Jorgesys controlla la risposta di evertvandenbruel dove ha aggiunto inetIndirizzo dell'istanza di Inet4Address
temirbek

3
cambia se condizione come questa per ottenere l'IP corretto: if (! inetAddress.isLoopbackAddress () && inetAddress instanceof Inet4Address)
Rajesh.k

Il codice restituisce solo il primo IP, un telefono può avere contemporaneamente cellulare, WIFI e indirizzo BT
reker

Se hai un hotspot attivo, potresti ottenere più di un IP
Harsha

16

Non è necessario aggiungere autorizzazioni come nel caso delle soluzioni fornite finora. Scarica questo sito Web come stringa:

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

o

http://www.telize.com/geoip

Il download di un sito Web come stringa può essere eseguito con il codice Java:

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

Analizzare l'oggetto JSON in questo modo:

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

L'attributo json "query" o "ip" contiene l'indirizzo IP.


2
questo richiede una connessione a Internet. Grande problema
David,

4
Perché è un grosso problema? Ovviamente è necessaria una connessione a Internet perché un indirizzo IP è tecnicamente correlato a tale connessione. Se esci di casa e vai in un ristorante, utilizzerai un'altra connessione Internet e quindi un altro indirizzo IP. Non hai bisogno di qualcosa da aggiungere di più come ACCESS_NETWORK_STATE o ACCESS_WIFI_STATE. Una connessione Internet è l'unica autorizzazione necessaria per la soluzione fornita da me.
Daan,

2
Quale dominio? Se ip-api.com non funziona, è possibile utilizzare telize.com come fallback. Altrimenti puoi usare api.ipify.org . È disponibile anche qui (non json): ip.jsontest.com/?callback=showIP . Molte app utilizzano domini che devono essere garantiti per rimanere online; è normale. Tuttavia, se si utilizzano fallback, è altamente improbabile che ci sia un problema.
Daan,

3
Il punto originale di David è ancora valido. Cosa succede se ti trovi su una rete interna che non ha accesso a Internet.
Hiandbaii,

2
Non ci ho mai pensato perché non conosco alcuno scopo pratico di un'app che ha sicuramente bisogno di una rete ma dovrebbe funzionare senza Internet (forse c'è ma non la vedo per i dispositivi mobili).
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;
        }

1
è possibile che ciò restituisca l'ip della rete privata dall'interfaccia wifi, come 192.168.0.x? o restituirà sempre l'indirizzo IP esterno, che verrebbe utilizzato su Internet?
Ben H,

9

Il metodo getDeviceIpAddress restituisce l'indirizzo IP del dispositivo e preferisce l'indirizzo dell'interfaccia wifi se è collegato.

  @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

Questa è una rielaborazione di questa risposta che rimuove le informazioni irrilevanti, aggiunge commenti utili, nomina le variabili in modo più chiaro e migliora la logica.

Non dimenticare di includere le seguenti autorizzazioni:

<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

versione minimalista di 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();

3

Basta usare Volley per ottenere l'ip da questo sito

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

Di recente, un indirizzo IP viene comunque restituito getLocalIpAddress()nonostante sia stato disconnesso dalla rete (nessun indicatore di servizio). Significa che l'indirizzo IP visualizzato in Impostazioni> Informazioni sul telefono> Stato era diverso da quello che pensava l'applicazione.

Ho implementato una soluzione alternativa aggiungendo questo codice prima di:

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

Suona un campanello per qualcuno?


2

a Kotlin, senza Formatter

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

Nella tua attività, la seguente funzione getIpAddress(context)restituisce l'indirizzo IP del telefono:

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

Sto ottenendo 0.0.0.0
natsumiyu il

Il tuo telefono è collegato a una rete wifi? Quale valore viene restituito se si chiama wifiManager.getConnectionInfo (). GetSSID ()?
matdev,

Funzionerà con il dispositivo connesso a Mobile Data, non WiFi?
Sergey,

No, questo metodo funziona solo se il dispositivo è collegato al WiFi
matdev

1

Ecco la versione kotlin di @Nilesh e @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
}

1
Se questo è il tuo stile di codice in progetti reali, ti suggerisco di leggere "codice pulito" di robert martin
Ahmed Adel Ismail,

1

Un dispositivo potrebbe avere diversi indirizzi IP e quello in uso in una particolare app potrebbe non essere l'IP che vedranno i server che ricevono la richiesta. In effetti, alcuni utenti utilizzano una VPN o un proxy come Cloudflare Warp .

Se il tuo scopo è quello di ottenere l'indirizzo IP come mostrato dai server che ricevono richieste dal tuo dispositivo, allora la cosa migliore è interrogare un servizio di geolocalizzazione IP come Ipregistry (disclaimer: lavoro per l'azienda) con il suo client Java:

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

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

Oltre ad essere davvero semplice da usare, ottieni ulteriori informazioni come paese, lingua, valuta, fuso orario per l'IP del dispositivo e puoi identificare se l'utente sta usando un proxy.


1

Questo è il modo più semplice e semplice mai esistito su Internet ... Prima di tutto, aggiungi questa autorizzazione al tuo file manifest ...

  1. "INTERNET"

  2. "ACCESS_NETWORK_STATE"

aggiungilo nel file onCreate di Activity ..

    getPublicIP();

Ora aggiungi questa funzione al tuo 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) contiene il tuo indirizzo IP pubblico.
Zia Muhammad,

È necessario dichiarare nel file di attività in questo modo: ArrayList <String> urls = new ArrayList <String> (); // per leggere ogni riga
Zia Muhammad,

0

Se hai una shell; ifconfig eth0 ha funzionato anche per il dispositivo x86


0

Per favore controlla questo codice ... Usando questo codice. otterremo ip da internet mobile ...

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

0

Non faccio Android, ma lo affronterei in un modo completamente diverso.

Invia una query a Google, ad esempio: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

E fare riferimento al campo HTML in cui è pubblicata la risposta. Puoi anche interrogare direttamente alla fonte.

A Google piacerà di più essere lì più a lungo della tua applicazione.

Ricorda, potrebbe essere che il tuo utente non abbia Internet in questo momento, cosa ti piacerebbe che accadesse!

In bocca al lupo


Interessante! E scommetto che Google ha una sorta di chiamata API che restituirà il tuo IP, che sarà più stabile della scansione di HTML.
Scott Biggs,

0

Puoi farlo

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

In tutta onestà, ho solo un po 'di familiarità con la sicurezza del codice, quindi potrebbe trattarsi di hack-ish. Ma per me questo è il modo più versatile per farlo:

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

Compilando alcune delle idee per ottenere l'ip wifi da WifiManagerin una soluzione kotlin più bella:

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

In alternativa è possibile ottenere gli indirizzi IP dei dispositivi loopback ip4 tramite 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()

-2

Sulla base di ciò che ho testato questa è la mia proposta

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) {}
   }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.