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.