source.rar
source.rar

Reputation: 8090

Determine device public ip

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

Answers (17)

Anukool srivastav
Anukool srivastav

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

Muzaffar Mohamed
Muzaffar Mohamed

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

Muhammad Bilal
Muhammad Bilal

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.

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

Upvotes: 1

Pierre Carrier
Pierre Carrier

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

bormat
bormat

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

user3826696
user3826696

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

duranun
duranun

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

GFuentesDev
GFuentesDev

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

Codelaby
Codelaby

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

jose
jose

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

Khai Nguyen
Khai Nguyen

Reputation: 3061

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

http://freegeoip.net/json

Another solution compare to whatismyip

Upvotes: 0

Gorio
Gorio

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

Brad Christie
Brad Christie

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

Gabriel Klein
Gabriel Klein

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

Eng.Fouad
Eng.Fouad

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

RichieHindle
RichieHindle

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

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

Related Questions