Como obter o endereço IP do dispositivo a partir do código?


384

É possível obter o endereço IP do dispositivo usando algum código?


5
Não esqueça que esta é uma coleção de tamanho N e você não pode assumir que N == (0 || 1). Em outras palavras, não assuma que um dispositivo tenha apenas uma maneira de conversar com uma rede e não assuma que ele tenha alguma maneira de conversar com uma rede.
— James Moore



Você deve obtê-lo de um serviço externo ipof.in/txt é um desses serviços
— vivekv 28/16

é possível obtê-lo programaticamente no android?
— Tanmay Sahoo

Respostas:


434

Este é o meu utilitário auxiliar para ler endereços IP e MAC. A implementação é java pura, mas eu tenho um bloco de comentários no getMACAddress()qual pode ler o valor do arquivo Linux (Android) especial. Eu executei esse código apenas em alguns dispositivos e emulador, mas deixe-me saber aqui se você encontrar resultados estranhos.

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

}

Isenção de responsabilidade: idéias e códigos de exemplo para esta classe Utils vieram de várias postagens do SO e do Google. Limpei e juntei todos os exemplos.


17
Isso requer o nível 9 da API e acima devido ao getHardwareAddress ().
— Calvin

2
Problemas - avisos de fiapos ativados toUpperCase(). A captura Exceptioné sempre desonesta (e os métodos auxiliares devem ser lançados de qualquer maneira e deixar o chamador lidar com a exceção - embora isso não tenha sido alterado). Formatação: não deve ter mais que 80 linhas. Execução condicional para getHardwareAddress()- patch: github.com/Utumno/AndroidHelpers/commit/… . O que você diz ?
— Mr_and_Mrs_D

5
Se você estiver em uma rede local (por exemplo, Wifi ou emulador), receberá um endereço IP privado. Você pode obter o endereço IP do proxy através de um pedido para um site específico que lhe dá o endereço de proxy, por exemplo whatismyip.akamai.com
— Julien Kronegg

11
Isso funciona perfeito para mim com dispositivo real usando Wifi. Muito obrigado, mano
— Sr. Neo

5
Estou obtendo maus resultados disso em um Nexus 6 ao tentar obter um endereço IP. Eu tenho um NetworkInterface com o nome "name: dummy0 (dummy0)" que fornece um endereço com o formato "/ XX :: XXXX: XXXX: XXXX: XXXX: XXXX% dummy0", também há uma interface de rede real que corresponde a wlan0, mas uma vez que o "dummy" acontece primeiro Eu sempre obter esse endereço fictício
— Julian Suarez

201

Isso funcionou para mim:

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

10
este funciona para mim. no entanto, ele precisa da permissão "ACCESS_WIFI_STATE" e, como escreveu "Umair", o uso da lista não é necessário.
— desenvolvedor android

13
formatIpAddress está obsoleto por algum motivo. O que deve ser usado em seu lugar?
— desenvolvedor android

8
Dos documentos: Use getHostAddress(), que suporta endereços IPv4 e IPv6. Este método não suporta endereços IPv6.
— Ryan R

7
como usar getHostAddress () para obter o endereço IP do servidor e do cliente @RyanR?
— gumuruh

42
isso ainda funcionará mesmo se o usuário usar dados em vez de wifi?
— PinoyCoder

65

Eu usei o seguinte código: O motivo pelo qual eu usei o hashCode foi porque eu estava recebendo alguns valores de lixo anexados ao endereço IP quando eu usei getHostAddress. Mas hashCodefuncionou muito bem para mim, pois posso usar o Formatador para obter o endereço IP com a formatação correta.

Aqui está o exemplo de saída:

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

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

Como você pode ver, os métodos 2 me dão exatamente o que eu preciso.

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

11
getHostAddress()fará o mesmo que o material do formatador que você adicionou.
— 27412 Phil

10
Usar hashCode está completamente errado e retorna um disparate. Use InetAddress.getHostAddress ().
— Ponteiro Nulo

altere esta parte: if (! inetAddress.isLoopbackAddress ()) {String ip = Formatter.formatIpAddress (inetAddress.hashCode ()); Log.i (TAG, "***** IP =" + ip); retorno ip; } com isso: if (! inetAddress.isLoopbackAddress () && InetAddressUtils.isIPv4Address (inetAddress.getHostAddress ())) {retornar inetAddress .getHostAddress (). toString (); } Isso vai lhe dar o formato IP correto
— Chuy47

O código só retornar primeiro IP, um telefone pode ter celluar, Wi-Fi e BT endereço ao mesmo tempo
— Reker

@ Chuy47 diz que InetAddressUtils não pode ser encontrado #
— FabioR 16/07/19

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

Adicionei inetAddressinstanceof Inet4Addresspara verificar se é um endereço ipv4.


salvou o meu dia! obrigado. É o único código trabalhando em samsung S7 borda
— Dhananjay Sarsonia

Esta é uma resposta real, em vez de acima da qual apenas obter interface WiFi.
— Nyconing 19/04

Essa realmente deve ser a resposta correta, funciona para redes WiFi e móveis e usa "getHostAddress" em vez de formatação personalizada.
— Balázs Gerlei

No entanto, ele tem o meu IP local, eu preciso do meu IP público (como eu acredito necessidades OP também)
— FabioR

53

Embora exista uma resposta correta, compartilho minha resposta aqui e espero que dessa maneira seja mais 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));

4
Obrigado! O formatador está obsoleto e eu realmente não queria escrever lógica de bits simples.
— William Morrison

4
Funciona muito bem, mas requer permissão WIFI_STATE:<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
— Brent Faust

11
Eu uso o formaador, mas ele não funciona. Isso é ótimo! Realmente apreciado. Você poderia explicar o que é feito na última linha. Eu sei% d.% D.% D.% D no entanto outros? Obrigado
— Günay Gültekin

11
Nah isso não está respondendo diretamente ao OP. Porque nem todos os dispositivos Android usam Wi-Fi para se conectar à Internet. Ele pode ter NATed LAN em Ethernet, ou BT e não WAN NAT conexão etc.
— nyconing

31

O código abaixo pode ajudá-lo. Não se esqueça de adicionar permissões.

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

Adicione abaixo a permissão no arquivo de manifesto.

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

feliz codificação !!


6
Ei, isso retorna um valor incorreto como: "fe80 :: f225: b7ff: fe8c: d357% wlan0"
— Jorgesys

@Jorgesys verifica a resposta de evertvandenbruel onde adicionou inetAddress instanceof Inet4Address
— temirbek

3
alterar if condição como esta para obter o ip correto: if (! inetAddress.isLoopbackAddress () && inetAddress instanceof Inet4Address)
— Rajesh.k

O código só retornar primeiro IP, um telefone pode ter celluar, Wi-Fi e BT endereço ao mesmo tempo
— Reker

Se você tiver um hotspot, poderá obter mais de um ip
— Harsha

16

Você não precisa adicionar permissões, como é o caso das soluções fornecidas até o momento. Faça o download deste site como uma string:

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

ou

http://www.telize.com/geoip

O download de um site como uma string pode ser feito com o código java:

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

Analise o objeto JSON assim:

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

O atributo json "query" ou "ip" contém o endereço IP.


2
isso precisa de conexão com a Internet. Grande problema
— David

4
Por que isso é um grande problema? É claro que você precisa de uma conexão com a Internet porque um endereço IP está tecnicamente relacionado a essa conexão. Se você sair de casa e for a um restaurante, usará outra conexão à Internet e, portanto, outro endereço IP. Você não precisa adicionar algo como ACCESS_NETWORK_STATE ou ACCESS_WIFI_STATE. Uma conexão com a Internet é a única permissão necessária para a solução fornecida por mim.
— Anónimo

2
Qual domínio? Se o ip-api.com não funcionar, você pode usar o telize.com como um substituto. Caso contrário, você pode usar o api.ipify.org . Também está disponível aqui (não no json): ip.jsontest.com/?callback=showIP . Muitos aplicativos usam domínios que devem permanecer online; isso é normal. No entanto, se você usar fallbacks, é altamente improvável que haja um problema.
— Daan

3
O ponto original de David ainda permanece. E se você estiver em uma rede interna que não tem acesso à Internet.
— hiandbaii

2
Nunca pensei nisso porque não conheço nenhum objetivo prático de um aplicativo que definitivamente precise de uma rede, mas que funcione sem internet (talvez exista, mas não o vejo para dispositivos móveis).
— 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;
        }

11
é possível que isso retorne o ip da rede privada a partir da interface wifi, como 192.168.0.x? ou ele sempre retornará o endereço IP externo, que seria usado na internet?
— Ben H

9

O método getDeviceIpAddress retorna o endereço IP do dispositivo e prefere o endereço da interface wifi, se estiver conectado.

  @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

Este é um retrabalho desta resposta que retira informações irrelevantes, adiciona comentários úteis, nomeia variáveis ​​mais claramente e aprimora a lógica.

Não se esqueça de incluir as seguintes permissões:

<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

versão minimalista do 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 usar o Volley para obter o ip deste site

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

Recentemente, um endereço IP ainda é retornado por getLocalIpAddress() apesar de desconectado da rede (nenhum indicador de serviço). Isso significa que o endereço IP exibido em Configurações> Sobre o telefone> Status foi diferente do que o aplicativo pensava.

Eu implementei uma solução alternativa adicionando este código antes:

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

Isso soa um sino para alguém?


2

no Kotlin, sem formatador

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

Na sua atividade, a seguinte função getIpAddress(context)retorna o endereço IP do telefone:

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

Estou recebendo 0.0.0.0
— natsumiyu 04/07/19

O seu telefone está conectado a uma rede wifi? Qual valor será retornado se você chamar wifiManager.getConnectionInfo (). GetSSID ()?
— matdev

Funcionará no dispositivo conectado ao Mobile Data, não no WiFi?
— Sergey

Não, esse método funciona apenas se o dispositivo estiver conectado ao WiFi
— Matdev 18/07/19

1

Aqui está a versão kotlin de @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
}

11
Se este for o seu estilo de código em projetos reais, eu sugiro que você leia "código limpo", de Robert Martin
— Ahmed Adel Ismail

1

Um dispositivo pode ter vários endereços IP, e aquele em uso em um aplicativo específico pode não ser o IP que os servidores que recebem a solicitação verão. De fato, alguns usuários usam uma VPN ou proxy como o Cloudflare Warp .

Se o seu objetivo é obter o endereço IP conforme mostrado pelos servidores que recebem solicitações do seu dispositivo, o melhor é consultar um serviço de geolocalização IP, como o Ipregistry (aviso: trabalho para a empresa) com seu cliente Java:

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

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

Além de ser realmente simples de usar, você obtém informações adicionais como país, idioma, moeda, fuso horário do IP do dispositivo e pode identificar se o usuário está usando um proxy.


1

Essa é a maneira mais fácil e simples que existe na Internet ... Antes de tudo, adicione essa permissão ao seu arquivo de manifesto ...

  1. "INTERNET"

  2. "ACCESS_NETWORK_STATE"

adicione isso no arquivo onCreate de Activity ..

    getPublicIP();

Agora adicione esta função à sua 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) contém seu endereço IP público.
— Zia Muhammad

Você deve declarar em seu arquivo de atividades assim: ArrayList <String> urls = new ArrayList <String> (); // para ler cada linha
— Zia Muhammad

0

Se você tem uma concha; O ifconfig eth0 também funcionou no dispositivo x86


0

Por favor, verifique este código ... Usando este código. obteremos ip da internet móvel ...

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

Eu não faço o Android, mas lidaria com isso de uma maneira totalmente diferente.

Envie uma consulta ao Google, algo como: https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=my%20ip

E consulte o campo HTML onde a resposta é postada. Você também pode consultar diretamente a fonte.

O Google provavelmente estará lá por mais tempo que o seu Aplicativo.

Lembre-se, pode ser que seu usuário não tenha internet no momento, o que você gostaria que acontecesse!

Boa sorte


Interessante! E aposto que o Google tem algum tipo de chamada de API que retornará seu IP, que será mais estável do que a digitalização de HTML.
— Scott Biggs

0

Você consegue fazer isso

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

Com toda a honestidade, eu estou um pouco familiarizado com a segurança do código, então isso pode ser um hack-ish. Mas, para mim, esta é a maneira mais versátil de fazer isso:

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 algumas das idéias para obter o ip wifi da WifiManagersolução kotlin mais agradável:

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

Como alternativa, você pode obter os endereços IP dos dispositivos de loopback IP4 através do 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

Com base no que testei, esta é a minha 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) {}
   }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.