Determine device public ip
Asked Answered
G

17

19

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

Glaciate answered 10/6, 2011 at 14:46 Comment(0)
T
13

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.

Truong answered 10/6, 2011 at 14:50 Comment(9)
Or if you want an api with unlimited usage: exip.org (instructions on site)Foret
@brad does whatismyip.com gives public ipForetopgallant
@Brad, your first link is brokenMartian
@Martian indeed, but there is now a developer APITruong
ipify and ip-api seem to be better choices. I haven't decided which one I'll use but ipify seems better as it says You can use it without limit and No visitor information is ever logged. Best of both worlds.Haggard
ip-api is much better if you need more info than just a public IP address. You get lots of info by default, but can pick yourself via Field generator.Haggard
You must be a Gold Level Member to access the APIBarocchio
@Barocchio even as of today, you're allowed 12 requests per day. Not sure the significance of the comment. Regardless, there are hundreds of services that do this now, including icanhazip.comTruong
I'd suggest a service I maintain, designed for programmatic access with no limitations or API keys, api.ident.me; note in particular that api.tnedi.me is available for redundancy.Lyle
D
12

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();
}
Dilemma answered 27/5, 2013 at 23:3 Comment(1)
checkip.org does not appear to be an active site.Cousingerman
O
7

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.

Outland answered 8/5, 2017 at 18:41 Comment(0)
B
6

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.

Boast answered 10/6, 2011 at 14:48 Comment(0)
G
4

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.

Gossoon answered 10/6, 2011 at 14:49 Comment(6)
The socket will be sourced from a public ip address if it goes through a NAT deviceAmritsar
@Mike Pennington: But that doesn't help if the aim to use the IP address to connect another device to. My PC here connects to stackoverflow.com via a NAT router, and there's no way for stackoverflow.com (or anyone else outside of my local network) to open a connection to my PC.Gossoon
@RichieHindle, it's possible he plans to use NAT traversal techniques such as UDP hole punching; this does allow bidirectional communication through a NATAmritsar
@Mike Pennington: Given the tone of the question ("just experimenting with simple p2p") I'd be surprised. :-)Gossoon
@Richie, if he reads my comment it will not be long before he will be hole-punching, even if that wasn't his original intent ;-)Amritsar
Turns out you were right :). I did try running the ServerSocket but apparently carriers usually block incoming access. So I was looking into hole punching (thanks to your comment), and would like to know if you have any more info on how this works (reading wikipedia currently).Glaciate
S
4
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);
    }
}
Spoke answered 26/8, 2015 at 20:0 Comment(1)
This works cool. But all api includes f**k word. how can we use this in production environment?Rahman
O
3

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

}
Ovary answered 21/3, 2014 at 11:11 Comment(1)
It is a alternative way to implement and more reliable. Thanks.Oriole
C
3

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 "";
    }
}
Coercion answered 16/6, 2017 at 3:27 Comment(0)
F
2

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());
    }
}
Flophouse answered 26/2, 2017 at 15:50 Comment(1)
What is verbose here that you have checked true or false?Chlorothiazide
H
2
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;
    }

}
Hydroxide answered 5/6, 2017 at 16:20 Comment(0)
P
1

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.

Planarian answered 20/10, 2016 at 0:20 Comment(1)
checkip.org does not appear to be an active site.Cousingerman
A
1
 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) {
                        }
                }
                }
    }
}
Alderney answered 4/7, 2017 at 13:27 Comment(0)
A
1

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.

  1. 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" }
  }
}
  1. 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?

  1. Initialize Ipify in your application class of Android app's onCreate() method
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
    }
    ... 
}
  1. Observe IP addresses anywhere in your application. This function will provide you an observer to observe the IP address while changing the network connection from mobile data to Wi-Fi or any other Wi-Fi.
Ipfy.getInstance().getPublicIpObserver().observe(this, { ipData ->
      ipData.currentIpAddress
      ipData.lastStoredIpAddress
})
Adalard answered 31/5, 2022 at 7:19 Comment(0)
P
0

I use FreeGeoIP, and receive IP->GEO too.

http://freegeoip.net/json

Another solution compare to whatismyip

Puccini answered 19/11, 2016 at 23:20 Comment(1)
The link is brokenPotter
D
0

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();
    }
}
Drooff answered 20/3, 2021 at 11:58 Comment(0)
L
0

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.

Lyle answered 26/2, 2022 at 17:56 Comment(0)
P
0

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;
    }
Panicle answered 21/12, 2022 at 5:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.