Reputation: 8090
Does anyone know how I could get the public ip address of an android device?
I am trying to run a server socket (just experimenting with simple p2p).
This requires informing the local and remote users of each others public ip. I did find this thread How to get IP address of the device from code? which contains a link to an article (http://www.droidnova.com/get-the-ip-address-of-your-device,304.html) that shows how to get the IP. However this returns the local ip when connected through a router and I would like to get the actual public IP instead.
TIA
Upvotes: 19
Views: 43090
Reputation: 797
For getting the public IP address, you need to have some WebService (API) deployed on your server that will return the clients public IP address.
If you can not have your own service deployed, you can use any public available services like used in this sample code.
public static String getPublicIPAddress() {
try {
new AsyncTask<String, String, String>() {
@Override
protected String doInBackground(String... strings) {
String publicIP = "";
try {
java.util.Scanner s = new java.util.Scanner(
new java.net.URL(
"https://ifcfg.me/me") // returns public IP address
.openStream(), "UTF-8")
.useDelimiter("\\A");
publicIP = s.next();
} catch (Exception e) {
e.printStackTrace();
}
return publicIP;
}
@Override
protected void onPostExecute(String publicIp) {
super.onPostExecute(publicIp);
Log.e("PublicIP", publicIp);
}
}.execute();
} catch (Exception e) {
e.printStackTrace();
}
return ipAddress;
}
Upvotes: 0
Reputation: 73
This is continuation for Eng.Fouad answer, which is by Parse the public IP address from checkip.org (Using JSoup)::
Method (Incase if you receive exception error from previous method):
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.IOException;
**********
public static String getPublicIp()
{
String myip="";
try{
Document doc = Jsoup.connect("http://www.checkip.org").get();
myip = doc.getElementById("yourip").select("h1").first().select("span").text();
}
catch(IOException e){
e.printStackTrace();
}
return myip;
}
Calling method example:
<your class name> wifiInfo = new <your class name>();
String myIP = wifiInfo.getPublicIp();
Compile following library in your build.gradle dependencies
compile 'org.jsoup:jsoup:1.9.2'
JSoup is compiled using Java API Version 8, so add following inside build.gradle defaultConfig {}
jackOptions{
enabled true
}
and change compile option to:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Last but not least, place following code under the onCreate() method, as by default you're not supposed to run network operation by UI (recomended via services or AsyncTask) then rebuild the code.
StrictMode.enableDefaults();
Tested and working on Lolipop and Kitkat.
Upvotes: 1
Reputation: 51
Ipify provides an API to get a public IP address. Go through the link here and enjoy the library with hassle-free code and the rest will be handled by the library itself. This library Ipify-Android is specially made for #Android #developers.
Add it to your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}}
Note: In New Android studio updates, now allProjects block has been removed from the root build.gradle file. So you must add this repository to your root settings.gradle as below:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
...
maven { url "https://jitpack.io" }
}
}
Add the dependency in your module's (e.g. app or any other) build.gradle file:
dependencies {
...
implementation 'com.github.chintan369:Ipify-Android:<latest-version>'}
How do I use Ipify-Android?
public class MyApplication : Application() { ... override fun onCreate() { super.onCreate(); Ipfy.init(this) // this is a context of application //or you can also pass IpfyClass type to get either IPv4 address only or universal address IPv4/v6 as Ipfy.init(this,IpfyClass.IPv4) //to get only IPv4 address //and Ipfy.init(this,IpfyClass.UniversalIP) //to get Universal address in IPv4/v6 } ... }
Ipfy.getInstance().getPublicIpObserver().observe(this, { ipData -> ipData.currentIpAddress ipData.lastStoredIpAddress })
Upvotes: 1
Reputation: 414
https://api.ident.me offers plenty of mechanisms (HTTP(S), DNS, SSH) and redundancy (tnedi.me). I'm the author. It's non-commercial, designed to be used programmatically, and does not require API keys.
Upvotes: 0
Reputation: 1379
this is an api without limit or authentification needed
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
and
URL url = null;
try {
url = new URL("https://api.ipify.org");
String ip = getUrlContent(url);
Log.d("ip is", ip);
} catch (IOException e) {
e.printStackTrace();
}
and
private String getUrlContent(URL u) throws IOException {
java.net.URLConnection c = u.openConnection();
c.setConnectTimeout(2000);
c.setReadTimeout(2000);
c.connect();
try (InputStream in = c.getInputStream()) {
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
byte b = (byte)result;
buf.write(b);
result = bis.read();
}
return buf.toString();
}
}
Upvotes: 0
Reputation: 1135
public class Test extends AsyncTask {
@Override
protected Object doInBackground(Object[] objects) {
URL whatismyip = null;
try {
whatismyip = new URL("http://icanhazip.com/");
try {
BufferedReader in = new BufferedReader(new InputStreamReader(
whatismyip.openStream()));
String ip = in.readLine(); //you get the IP as a String
Log.i(TAG, "EXT IP: " + ip);
} catch (IOException e) {
e.printStackTrace();
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
}
Upvotes: 2
Reputation: 331
public class getIp extends AsyncTask<String, String, String> {
String result;
@Override
protected String doInBackground(String... strings) {
CustomHttpClient client = new CustomHttpClient();
try {
result = client.executeGet("http://checkip.amazonaws.com/");
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
and call in anywhere
try {
ip = new getIp().execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
CustomHttpClient.java
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class CustomHttpClient {
private static HttpClient custHttpClient;
public static final int MAX_TOTAL_CONNECTIONS = 1000;
public static final int MAX_CONNECTIONS_PER_ROUTE = 1500;
public static final int TIMEOUT_CONNECT = 150000;
public static final int TIMEOUT_READ = 150000;
public static HttpClient getHttpClient() {
if (custHttpClient == null) {
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https",SSLSocketFactory.getSocketFactory(), 443));
HttpParams connManagerParams = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(connManagerParams, MAX_TOTAL_CONNECTIONS);
ConnManagerParams.setMaxConnectionsPerRoute(connManagerParams, new ConnPerRouteBean(MAX_CONNECTIONS_PER_ROUTE));
HttpConnectionParams.setConnectionTimeout(connManagerParams, TIMEOUT_CONNECT);
HttpConnectionParams.setSoTimeout(connManagerParams, TIMEOUT_READ);
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(new BasicHttpParams(), schemeRegistry);
custHttpClient = new DefaultHttpClient(cm, null);
HttpParams para = custHttpClient.getParams();
HttpConnectionParams.setConnectionTimeout(para, (30 * 10000));
HttpConnectionParams.setSoTimeout(para, (30 * 10000));
ConnManagerParams.setTimeout(para, (30 * 10000));
}
return custHttpClient;
}
public static String executePost(String urlPostFix,ArrayList<NameValuePair> postedValues)
throws Exception {
String url = urlPostFix;
BufferedReader in = null;
try {
System.setProperty("http.keepAlive", "false");
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(url);
request.setHeader("Accept", "application/json");
request.setHeader("Content-Type", "application/x-www-form-urlencoded");
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postedValues);
formEntity.setContentType("application/json");
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String result = sb.toString();
return result;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
public static String executeGet(String urlPostFix)
throws Exception {
String url = urlPostFix;
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpGet request = new HttpGet( url);
request.setHeader("Accept", "application/json");
request.setHeader("Content-Type", "application/x-www-form-urlencoded");
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String result = sb.toString();
return result;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
public static Bitmap executeImageGet(String urlPostFix)
throws Exception {
String url = urlPostFix;
InputStream in = null;
try {
HttpClient client = getHttpClient();
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);
in = bufHttpEntity.getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
in.close();
return bitmap;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
}
}
}
Upvotes: 1
Reputation: 31
Using org.springframework.web.client.RestTemplate
and Amazon API you can easily get your public IP.
public static String getPublicIP() {
try {
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject("http://checkip.amazonaws.com/", String.class).replace("\n","");
} catch ( Exception e ) {
return "";
}
}
Upvotes: 3
Reputation: 2893
I use this function to get the public IP address, check first if there is connectivity and then request the request to return the public IP address
public static String getPublicIPAddress(Context context) {
//final NetworkInfo info = NetworkUtils.getNetworkInfo(context);
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo info = cm.getActiveNetworkInfo();
RunnableFuture<String> futureRun = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
if ((info != null && info.isAvailable()) && (info.isConnected())) {
StringBuilder response = new StringBuilder();
try {
HttpURLConnection urlConnection = (HttpURLConnection) (
new URL("http://checkip.amazonaws.com/").openConnection());
urlConnection.setRequestProperty("User-Agent", "Android-device");
//urlConnection.setRequestProperty("Connection", "close");
urlConnection.setReadTimeout(15000);
urlConnection.setConnectTimeout(15000);
urlConnection.setRequestMethod("GET");
urlConnection.setRequestProperty("Content-type", "application/json");
urlConnection.connect();
int responseCode = urlConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
}
urlConnection.disconnect();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
}
} else {
//Log.w(TAG, "No network available INTERNET OFF!");
return null;
}
return null;
}
});
new Thread(futureRun).start();
try {
return futureRun.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return null;
}
}
Surely it can be optimized, I leave it for the masters who contribute their solutions.
Upvotes: 7
Reputation: 217
I am simply doing an HTTP GET to ipinfo.io/ip
Here's the implementation:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.HttpURLConnection;
public class PublicIP {
public static String get() {
return PublicIP.get(false);
}
public static String get(boolean verbose) {
String stringUrl = "https://ipinfo.io/ip";
try {
URL url = new URL(stringUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
if(verbose) {
int responseCode = conn.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
}
StringBuffer response = new StringBuffer();
BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
if(verbose) {
//print result
System.out.println("My Public IP address:" + response.toString());
}
return response.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
System.out.println(PublicIP.get());
}
}
Upvotes: 2
Reputation: 3061
I use FreeGeoIP, and receive IP->GEO too.
http://freegeoip.net/json
Another solution compare to whatismyip
Upvotes: 0
Reputation: 1646
private class ExternalIP extends AsyncTask<Void, Void, String> {
protected String doInBackground(Void... urls) {
String ip = "Empty";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://wtfismyip.com/text");
HttpResponse response;
response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
if (entity != null) {
long len = entity.getContentLength();
if (len != -1 && len < 1024) {
String str = EntityUtils.toString(entity);
ip = str.replace("\n", "");
} else {
ip = "Response too long or error.";
}
} else {
ip = "Null:" + response.getStatusLine().toString();
}
} catch (Exception e) {
ip = "Error";
}
return ip;
}
protected void onPostExecute(String result) {
// External IP
Log.d("ExternalIP", result);
}
}
Upvotes: 4
Reputation: 101614
Just visit http://automation.whatismyip.com/n09230945.asp and scrape it?
whatismyip.com is perfect for getting the IP, though the site requests you only hit it about once every 5 minutes.
UPDATE FEB 2015
WhatIsMyIp now exposes a developer API that you can use.
Upvotes: 13
Reputation: 544
Here is my way I'm doing it.
I have the DNS records
ip4 IN A 91.123.123.123
ip6 IN AAAA 1234:1234:1234:1234::1
Then I have a PHP scripts on my PHP enabled website. (You need to adapt this script)
< ?PHP
echo $_SERVER['REMOTE_ADDR'];? >
If I call ip6.mydomain.com/ip/, I have the IPv6 public ip. If I call ip4.mydomain.com/ip/, I have the IPv4 public ip.
Then I have the following java class.
public class IPResolver {
private HttpClient client = null;
private final Context context;
public IPResolver(Context context) {
this.context = context;
}
public String getIp4() {
String ip4 = getPage("http://ip4.mysite.ch/scripts/ip");
return ip4;
}
public String getIp6() {
String ip6 = getPage("http://ip6.mysite.ch/scripts/ip");
return ip6;
}
private String getPage(String url) {
// Set params of the http client
if (client == null) {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 2000;
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 2000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
client = new DefaultHttpClient(httpParameters);
}
try {
HttpGet request = new HttpGet(url);
HttpResponse response = client.execute(request);
String html = "";
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
str.append(line);
}
in.close();
html = str.toString();
return html.trim();
} catch (Throwable t) {
// t.printStackTrace();
}
return null;
}
}
Upvotes: 3
Reputation: 117627
Parse the public IP address from checkip.org (Using JSoup):
public static String getPublicIP() throws IOException
{
Document doc = Jsoup.connect("http://www.checkip.org").get();
return doc.getElementById("yourip").select("h1").first().select("span").text();
}
Upvotes: 12
Reputation: 281695
In the general case, you can't. Quite possibly, the device doesn't have a public IP address (or at least, not one that you can open a connection to). If it's connecting through NAT router then it won't have one.
The IP address returned by a tool like http://touch.whatsmyip.org/ will be the public-facing address of the NAT router, not of the device.
Most home and corporate networks use NAT routers, as do many mobile carriers.
Upvotes: 4
Reputation: 5572
To find the public IP you need to call an external service like http://www.whatismyip.com/ and get the external IP back as response.
Upvotes: 6