¿Cómo obtener la dirección IP del dispositivo a partir del código?

384

¿Es posible obtener la dirección IP del dispositivo usando algún código?

Nilesh Tupe
fuente
55
No olvide que esta es una colección de tamaño N, y no puede suponer que N == (0 || 1). En otras palabras, no asuma que un dispositivo solo tiene una forma de hablar con una red y no asuma que tiene alguna forma de hablar con una red.
James Moore
Relacionado: stackoverflow.com/questions/9481865/…
AlikElzin-kilaka
2
versión no programática android.stackexchange.com/questions/2984/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
Debe obtenerlo de un servicio externo ipof.in/txt es uno de esos servicios
vivekv
¿Es posible obtenerlo programáticamente en Android?
Tanmay Sahoo

Respuestas:

434

Esta es mi utilidad auxiliar para leer direcciones IP y MAC. La implementación es puramente java, pero tengo un bloque de comentarios en el getMACAddress()que podría leer el valor del archivo especial de Linux (Android). Ejecuté este código solo en algunos dispositivos y en el emulador, pero avíseme aquí si encuentra resultados extraños.

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

}

Descargo de responsabilidad: las ideas y el código de ejemplo para esta clase de Utils provienen de varias publicaciones SO y Google. He limpiado y fusionado todos los ejemplos.

Quien
fuente
17
Esto requiere API nivel 9 y superior debido a getHardwareAddress ().
Calvin
2
Problemas: advertencias de pelusa toUpperCase(). La captura Exceptionsiempre es dudosa (y los métodos de ayuda deberían arrojarse de todos modos y dejar que la persona que llama lidie con la Excepción, aunque no lo modificó). Formato: no debe tener más de 80 líneas. Ejecución condicional para getHardwareAddress()- parche: github.com/Utumno/AndroidHelpers/commit/… . Que dices ?
Mr_and_Mrs_D
55
Si está en una red local (por ejemplo, Wifi o emulador), obtendrá una dirección IP privada. Puede obtener la dirección IP de proxy a través de una solicitud a un sitio web específico que le proporciona la dirección de proxy, por ejemplo whatismyip.akamai.com
Julien Kronegg
1
Esto funciona perfecto para mí con un dispositivo real usando Wifi. Muchas gracias, hermano
Sr. Neo
55
Estoy obteniendo malos resultados de esto en un Nexus 6 cuando intento obtener una dirección IP. Tengo un NetworkInterface con el nombre "nombre: dummy0 (dummy0)" que da una dirección con el formato "/ XX :: XXXX: XXXX: XXXX: XXXX% dummy0", también hay una interfaz de red real que corresponde a wlan0, pero dado que el "dummy" ocurre primero, siempre obtengo esa dirección ficticia
Julian Suarez
201

Esto funcionó para mí:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
Nilesh Tupe
fuente
10
Esta funciona para mí . sin embargo, necesita el permiso "ACCESS_WIFI_STATE" y, como escribió "Umair", el uso de la lista no es necesario.
Desarrollador de Android
13
formatIpAddress está en desuso por alguna razón. ¿Qué se debe usar en su lugar?
Desarrollador de Android
8
De los documentos: Uso getHostAddress(), que admite direcciones IPv4 e IPv6. Este método no es compatible con direcciones IPv6.
Ryan R
77
¿Cómo usar getHostAddress () para obtener la dirección IP del servidor y del cliente @RyanR?
gumuruh
42
¿funcionará esto incluso si el usuario usa datos en lugar de wifi?
PinoyCoder
65

Usé el siguiente código: La razón por la que usé hashCode fue porque estaba obteniendo algunos valores basura añadidos a la dirección IP cuando lo usé getHostAddress. Pero hashCodefuncionó muy bien para mí, ya que puedo usar Formatter para obtener la dirección IP con el formato correcto.

Aquí está el resultado de ejemplo:

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

2.uso hashCodey Formatter: ***** IP=238.194.77.212

Como puede ver, el segundo método me da exactamente lo que necesito.

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
fuente
1
getHostAddress()hará lo mismo que el formateador que agregaste.
Phil
10
Usar hashCode es simplemente incorrecto y devuelve tonterías. Utilice InetAddress.getHostAddress () en su lugar.
Puntero nulo el
cambie esta parte: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); volver ip; } con esto: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ())) {return inetAddress .getHostAddress (). toString (); } esto le dará el formato de IP correcto
Chuy47
El código solo devuelve la primera IP, un teléfono puede tener celluar, WIFI y dirección BT al mismo tiempo
reker
@ Chuy47 dice que InetAddressUtils no se puede encontrar
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;
}

He agregado inetAddressinstanceof Inet4Addresspara verificar si es una dirección ipv4.

Evertvandenbruel
fuente
me salvó el día! Gracias. Es el único código que funciona en samsung s7 edge
Dhananjay Sarsonia
Esta es la respuesta real, en lugar de la anterior, que solo obtiene la interfaz WiFi.
nyconing
Esta realmente debería ser la respuesta correcta, funciona tanto para WiFi como para redes móviles, y utiliza "getHostAddress" en lugar de formato personalizado.
Balázs Gerlei
Sin embargo, obtiene mi IP local, necesito mi IP pública (como creo que OP también)
FabioR
53

Aunque hay una respuesta correcta, comparto mi respuesta aquí y espero que de esta manera sea más conveniente.

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
fuente
44
¡Gracias! El formateador está en desuso, y realmente no tenía ganas de escribir lógica de bits simple.
William Morrison
44
Funciona muy bien, pero requiere el permiso WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Brent Faust
1
Yo uso el formateador pero no funciona. ¡Eso es genial! Muy apreciado. ¿Podría explicar lo que se hace en la última línea? ¿Sé% d.% D.% D.% D sin embargo otros? Gracias
Günay Gültekin
1
No, esto no responde directamente a OP. Porque no todos los dispositivos Android usan WiFi para conectarse a Internet. Podría tener LAN NATed en Ethernet, o BT y no una conexión WAN NATed, etc.
nyconing
31

El siguiente código puede ayudarlo. No olvide agregar permisos.

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

Agregue el siguiente permiso en el archivo de manifiesto.

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

feliz codificación !!

Satyam
fuente
66
Hola, esto devuelve un valor incorrecto como: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
Jorgesys
@Jorgesys busca la respuesta de evertvandenbruel donde agregó inetAddress instanceof Inet4Address
temirbek
3
cambie si una condición como esta para obtener la IP correcta: if (! inetAddress.isLoopbackAddress () && inetAddress instanceof Inet4Address)
Rajesh.k
El código solo devuelve la primera IP, un teléfono puede tener celluar, WIFI y dirección BT al mismo tiempo
reker
Si tiene un punto de acceso activo, puede obtener más de una ip
Harsha
16

No necesita agregar permisos, como es el caso con las soluciones proporcionadas hasta ahora. Descargue este sitio web como una cadena:

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

o

http://www.telize.com/geoip

La descarga de un sitio web como una cadena se puede hacer con el código de Java:

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

Analiza el objeto JSON así:

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

El atributo json "query" o "ip" contiene la dirección IP.

Daan
fuente
2
Esto necesita conexión a Internet. Gran problema
David
44
¿Por qué es eso un gran problema? Por supuesto, necesita una conexión a Internet porque una dirección IP está técnicamente relacionada con dicha conexión. Si sale de su casa y va a un restaurante, utilizará otra conexión a Internet y, por lo tanto, otra dirección IP. No necesita algo para agregar más como ACCESS_NETWORK_STATE o ACCESS_WIFI_STATE. Una conexión a internet es el único permiso que necesita para la solución provista por mí.
Daan
2
Cual dominio Si ip-api.com no funciona, puede usar telize.com como alternativa. De lo contrario, puede usar api.ipify.org . También está disponible aquí (no json): ip.jsontest.com/?callback=showIP . Muchas aplicaciones usan dominios que se garantiza que permanecerán en línea; eso es normal. Sin embargo, si usa retrocesos, es muy poco probable que haya un problema.
Daan
3
El punto original de David sigue en pie. ¿Qué pasa si estás en una red interna que no tiene acceso a internet?
hiandbaii
2
Nunca pensé en eso porque no conozco ningún propósito práctico de una aplicación que definitivamente necesita una red pero debería funcionar sin internet (tal vez sí, pero no la veo para dispositivos móviles).
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
fuente
1
¿Es posible que esto devuelva la IP de la red privada desde la interfaz wifi, como 192.168.0.x? o siempre devolverá la dirección IP externa, que se usaría en Internet?
Ben H
9

El método getDeviceIpAddress devuelve la dirección IP del dispositivo y prefiere la dirección de la interfaz wifi si está conectada.

  @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;
    }
Podurets Ruslan
fuente
4

Esta es una revisión de esta respuesta que elimina la información irrelevante, agrega comentarios útiles, nombra las variables más claramente y mejora la lógica.

No olvide incluir los siguientes permisos:

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

versión minimalista de kotlin

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

Simplemente use Volley para obtener la ip de este sitio

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

Recientemente, aún se devuelve una dirección IP a getLocalIpAddress()pesar de estar desconectada de la red (sin indicador de servicio). Significa que la dirección IP que se muestra en Configuración> Acerca del teléfono> Estado era diferente de lo que pensaba la aplicación.

He implementado una solución agregando este código antes:

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

¿Le suena eso a alguien?

slash33
fuente
2

en Kotlin, sin formateador

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

En su actividad, la siguiente función getIpAddress(context)devuelve la dirección IP del teléfono:

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
fuente
Estoy obteniendo 0.0.0.0
natsumiyu
¿Tu teléfono está conectado a una red wifi? ¿Qué valor se devuelve si llama a wifiManager.getConnectionInfo (). GetSSID ()?
matdev
¿Funcionará para dispositivos conectados a datos móviles, no WiFi?
Sergey
No, este método funciona solo si el dispositivo está conectado a WiFi
matdev
1

Aquí está la versión de Kotlin de @Nilesh y @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
fuente
1
Si este es su estilo de código en proyectos reales, le sugiero que lea "código limpio" por Robert Martin
Ahmed Adel Ismail
1

Un dispositivo puede tener varias direcciones IP, y la que está en uso en una aplicación en particular puede no ser la IP que verán los servidores que reciben la solicitud. De hecho, algunos usuarios usan una VPN o un proxy como Cloudflare Warp .

Si su propósito es obtener la dirección IP como se muestra en los servidores que reciben solicitudes de su dispositivo, lo mejor es consultar un servicio de geolocalización IP como Ipregistry (descargo de responsabilidad: trabajo para la empresa) con su cliente Java:

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

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

Además de ser realmente fácil de usar, obtiene información adicional como el país, el idioma, la moneda, la zona horaria de la IP del dispositivo y puede identificar si el usuario está usando un proxy.

Laurent
fuente
1

Esta es la forma más fácil y simple que existe en Internet ... En primer lugar, agregue este permiso a su archivo de manifiesto ...

  1. "INTERNET"

  2. "ACCESS_NETWORK_STATE"

agregue esto en el archivo onCreate de Activity ..

    getPublicIP();

Ahora agregue esta función a su 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
fuente
urls.get (0) contiene su dirección IP pública.
Zia Muhammad
Debe declarar en su archivo de actividad de esta manera: ArrayList <String> urls = new ArrayList <String> (); // para leer cada línea
Zia Muhammad
0

Si tienes una concha; ifconfig eth0 también funcionó para dispositivos x86

RzR
fuente
0

Por favor verifique este código ... Usando este código. obtendremos ip de internet móvil ...

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

No hago Android, pero abordaría esto de una manera totalmente diferente.

Envíe una consulta a Google, algo así como: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

Y consulte el campo HTML donde se publica la respuesta. También puede consultar directamente a la fuente.

A Google le gustará más estar allí por más tiempo que su Aplicación.

Solo recuerde, es posible que su usuario no tenga Internet en este momento, ¡qué le gustaría que pasara!

Buena suerte

Makab
fuente
¡Interesante! Y apuesto a que Google tiene algún tipo de llamada API que devolverá su IP, que será más estable que escanear HTML.
Scott Biggs
0

Puedes hacerlo

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

Honestamente, solo estoy un poco familiarizado con la seguridad del código, por lo que esto puede ser hack-ish. Pero para mí esta es la forma más versátil de hacerlo:

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

Compilando algunas de las ideas para obtener la ip wifi de WifiManageruna solución kotlin más agradable:

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

Alternativamente, puede obtener las direcciones IP de los dispositivos de bucle invertido ip4 a través de 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
fuente
-2

Basado en lo que he probado, esta es mi propuesta

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
fuente