As explained in this reply it is not possible do this without relying on an external service:
No, it is not possible. Your machine has access to local IP only, provided by the internal DNS service or set manually.
The external IP is, in most of the times, the one provided by your provider for you to be accessible via NAT (Network address Translation), 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 provide this, for example:
However they all have points in common, being a third party service can occur to many people around the world using a stop service hour, I’m not saying not to use, but it’s always good to have a fallback.
I would say that a good way would be to have a server of your own, usually mobile apps use internet, if your app will provide access to some data online for the user the best would be to check the IP at this time on the server itself, an 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 really does not have any server 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 is out of the air, you try Service 2 and so on.
In this case it would be interesting to also put a very short timeout to not seem that 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);
In general the code would look 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 may take some time.
It seems that this is not possible, since who is in front of the network is the router/modem. Alias, not even a computer is able to determine the external ip by itself behind a NAT.
– user28595
@diegofm I had not seen that reply from Soen! Maybe there is some low cost service that will possibly solve this problem. I’ll do some research. = P
– viana
Related Recover External IP without third party services
– Guilherme Nascimento