How to rescue external IP address on Android?

1

The IPV4 local address is not too complex to redeem, you can do this by using the NetworkInterface . But in addition to the site, there is also the external IP , where I noticed that some people use some APIs , such as the WhatIsMyIP , to return information about the network. In WhatIsMyIP there is the free version, but very limited.

Is there a way to rescue external IP without the need for an external service? If so, how could I do this? If not, what viable way to do it?

    
asked by anonymous 26.04.2017 / 02:01

1 answer

3

As explained in this response it is not possible to do this without relying on a service external:

  

No, it is not possible. Your machine has access only to the local IP, provided by the internal DNS service or set manually.

     

External IP is, for the most part, the one provided by your ISP to be accessible via Network Address Translation (NAT), as in the image below:

     

    

NAT categorization according to RFC , Wikipedia

     

In this case you will always need an external service that tells you from his point of view , with which IP you are connecting.

How to get IP with external services

There are several third-party services that make this available, for example:

However they all have points in common, being a third party service can occur from many people around the world using one hour the service stop, I am not saying not to use, but it is always good to have a fallback.

I would say that a good way would be to have a server of its own, usually mobile apps use the internet, if your app will provide access to some data online for the user, it would be best to check the IP at the moment on the server itself, example using DefaultHttpClient :

HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://meuservidor/api/ip");

try
{
    HttpResponse response = client.execute(request);

    //Resposta, pode ser uma String
    EntityUtils.toString(response.getEntity());
}
catch (IOException e)
{
    Log.d("error", e.getLocalizedMessage());
}

However, if the application does not actually have any servers for whatever reason, "there is no harm" in using third-party services, as long as there is at least one fallback, for example you try service 1 if it fails because it's out of breath, you try service 2 and so on.

In this case it would be interesting to also put a very short timeout so it does not seem like the application is slow, for example:

//Configura
HttpParams parameters = new BasicHttpParams();

int timeoutConnection = 2000;
HttpConnectionParams.setConnectionTimeout(parameters, timeoutConnection);

int timeoutSocket = 2000;
HttpConnectionParams.setSoTimeout(parameters, timeoutSocket);

DefaultHttpClient client = new DefaultHttpClient(parameters);

// Começa a requisição a partir daqui...
HttpGet request = new HttpGet(urlDoServico);

Overall the code looks like this:

String myIp;

String[] toppings = { "http://servico1.com", "http://servico2.com", "http://servico3.com" };

//Configura
HttpParams parameters = new BasicHttpParams();

int timeoutConnection = 2000;
HttpConnectionParams.setConnectionTimeout(parameters, timeoutConnection);

int timeoutSocket = 2000;
HttpConnectionParams.setSoTimeout(parameters, timeoutSocket);

DefaultHttpClient client = new DefaultHttpClient(parameters);

// Começa a requisição a partir daqui...
HttpGet request;

final Pattern regexValidateIp = Pattern.compile("^\d{1,3}\.d{1,3}\.\d{1,3}$");

for (int i = 0; i < services.length; i++) {
    request = new HttpGet(services[i]);

    try {
        HttpResponse response = client.execute(request);

        //Pode tratar a a resposta aqui
        String resposeData = EntityUtils.toString(response.getEntity());

        if (regexValidateIp.matcher(resposeData).find()) {
             myIp = resposeData;
             break; //Finaliza o loop
        }
    } catch (IOException e) {}
}

//Exibe o IP
Log.d("IP:", myIp);

Of course it's good to remember that some returns JSON, others return HTML, so maybe you can get the header Content-Type and check this, you can put it inside a Thread or something, since the check can take some time.

    
26.04.2017 / 03:03