コードからデバイスのIPアドレスを取得する方法


384

コードを使用してデバイスのIPアドレスを取得することは可能ですか?


5
これはサイズNのコレクションであることを忘れないでください。N==(0 || 1)であるとは想定できません。言い換えれば、デバイスがネットワークと通信する方法が1つしかないことを想定したり、ネットワークと通信する方法をまったく想定したりしないでください。
James Moore



外部サービスから取得する必要がありますipof.in/txtはそのようなサービスの1つです
vivekv

それをアンドロイドでプログラム的に取得することは可能ですか?
Tanmay Sahoo 16年

回答:


434

これは、IPおよびMACアドレスを読み取るための私のヘルパーユーティリティです。実装はpure-javaですがgetMACAddress()、特別なLinux(Android)ファイルから値を読み取ることができるコメントブロックがあります。私はこのコードをいくつかのデバイスとエミュレータでのみ実行しましたが、奇妙な結果が見つかった場合はここでお知らせください。

// AndroidManifest.xml permissions
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

// test functions
Utils.getMACAddress("wlan0");
Utils.getMACAddress("eth0");
Utils.getIPAddress(true); // IPv4
Utils.getIPAddress(false); // IPv6 

Utils.java

import java.io.*;
import java.net.*;
import java.util.*;   
//import org.apache.http.conn.util.InetAddressUtils;

public class Utils {

    /**
     * Convert byte array to hex string
     * @param bytes toConvert
     * @return hexValue
     */
    public static String bytesToHex(byte[] bytes) {
        StringBuilder sbuf = new StringBuilder();
        for(int idx=0; idx < bytes.length; idx++) {
            int intVal = bytes[idx] & 0xff;
            if (intVal < 0x10) sbuf.append("0");
            sbuf.append(Integer.toHexString(intVal).toUpperCase());
        }
        return sbuf.toString();
    }

    /**
     * Get utf8 byte array.
     * @param str which to be converted
     * @return  array of NULL if error was found
     */
    public static byte[] getUTF8Bytes(String str) {
        try { return str.getBytes("UTF-8"); } catch (Exception ex) { return null; }
    }

    /**
     * Load UTF8withBOM or any ansi text file.
     * @param filename which to be converted to string
     * @return String value of File
     * @throws java.io.IOException if error occurs
     */
    public static String loadFileAsString(String filename) throws java.io.IOException {
        final int BUFLEN=1024;
        BufferedInputStream is = new BufferedInputStream(new FileInputStream(filename), BUFLEN);
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream(BUFLEN);
            byte[] bytes = new byte[BUFLEN];
            boolean isUTF8=false;
            int read,count=0;           
            while((read=is.read(bytes)) != -1) {
                if (count==0 && bytes[0]==(byte)0xEF && bytes[1]==(byte)0xBB && bytes[2]==(byte)0xBF ) {
                    isUTF8=true;
                    baos.write(bytes, 3, read-3); // drop UTF8 bom marker
                } else {
                    baos.write(bytes, 0, read);
                }
                count+=read;
            }
            return isUTF8 ? new String(baos.toByteArray(), "UTF-8") : new String(baos.toByteArray());
        } finally {
            try{ is.close(); } catch(Exception ignored){} 
        }
    }

    /**
     * Returns MAC address of the given interface name.
     * @param interfaceName eth0, wlan0 or NULL=use first interface 
     * @return  mac address or empty string
     */
    public static String getMACAddress(String interfaceName) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                if (interfaceName != null) {
                    if (!intf.getName().equalsIgnoreCase(interfaceName)) continue;
                }
                byte[] mac = intf.getHardwareAddress();
                if (mac==null) return "";
                StringBuilder buf = new StringBuilder();
                for (byte aMac : mac) buf.append(String.format("%02X:",aMac));  
                if (buf.length()>0) buf.deleteCharAt(buf.length()-1);
                return buf.toString();
            }
        } catch (Exception ignored) { } // for now eat exceptions
        return "";
        /*try {
            // this is so Linux hack
            return loadFileAsString("/sys/class/net/" +interfaceName + "/address").toUpperCase().trim();
        } catch (IOException ex) {
            return null;
        }*/
    }

    /**
     * Get IP address from first non-localhost interface
     * @param useIPv4   true=return ipv4, false=return ipv6
     * @return  address or empty string
     */
    public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
                for (InetAddress addr : addrs) {
                    if (!addr.isLoopbackAddress()) {
                        String sAddr = addr.getHostAddress();
                        //boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
                        boolean isIPv4 = sAddr.indexOf(':')<0;

                        if (useIPv4) {
                            if (isIPv4) 
                                return sAddr;
                        } else {
                            if (!isIPv4) {
                                int delim = sAddr.indexOf('%'); // drop ip6 zone suffix
                                return delim<0 ? sAddr.toUpperCase() : sAddr.substring(0, delim).toUpperCase();
                            }
                        }
                    }
                }
            }
        } catch (Exception ignored) { } // for now eat exceptions
        return "";
    }

}

免責事項:このUtilsクラスのアイデアとサンプルコードは、いくつかのSO投稿とGoogleからのものです。すべての例をクリーンアップしてマージしました。


17
getHardwareAddress()のため、これにはAPIレベル9以上が必要です。
Calvin

2
問題-に関する糸くずの警告toUpperCase()。キャッチExceptionは常に危険です(そしてヘルパーメソッドはとにかくスローし、呼び出し元に例外を処理させる必要があります-これは修正しませんでした)。書式設定:80行以下にする必要があります。getHardwareAddress()-パッチの条件付き実行:github.com/Utumno/AndroidHelpers/commit/…。あなたが言うこと ?
Mr_and_Mrs_D 2013

5
ローカルネットワーク(Wifiやエミュレーターなど)を使用している場合は、プライベートIPアドレスを取得します。プロキシIPアドレスは、プロキシアドレスを提供する特定のWebサイトへの要求を通じて取得できます。たとえば、whatismyip.akamai.com
Julien Kronegg

1
これは、Wifiを使用する実際のデバイスで完璧に機能します。どうもありがとうございました
Mr Neo

5
IPアドレスを取得しようとすると、Nexus 6でこれから悪い結果が出ます。「name:dummy0(dummy0)」という名前のNetworkInterfaceがあり、これは「/ XX :: XXXX:XXXX:XXXX:XXXX%dummy0」という形式のアドレスを提供します。wlan0に対応する実際のネットワークインターフェイスもありますが、 「ダミー」が最初に発生するので、私は常にそのダミーアドレスを取得します
Julian Suarez

201

これは私のために働きました:

WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());

10
これは私のために働きます。ただし、「ACCESS_WIFI_STATE」権限が必要であり、「Umair」が書いたように、リストの使用は必要ありません。
Android開発者

13
formatIpAddressは、何らかの理由で廃止されました。代わりに何を使用する必要がありますか?
Android開発者

8
ドキュメントから:getHostAddress()IPv4アドレスとIPv6アドレスの両方をサポートするを使用します。このメソッドはIPv6アドレスをサポートしていません。
Ryan R

7
サーバーとクライアントのIPアドレス@RyanRを取得するときにgetHostAddress()を使用する方法
gumuruh 2014

42
ユーザーがWi-Fiではなくデータを使用していても、これは機能しますか?
PinoyCoder 2015年

65

私は次のコードを使用しました:hashCodeを使用した理由は、を使用しgetHostAddressたときにIPアドレスにガベージ値が追加されていたためです。しかしhashCode、私はFormatterを使用して正しいフォーマットでIPアドレスを取得できるので、本当にうまくいきました。

次に出力例を示します。

1.使用 getHostAddress***** IP=fe80::65ca:a13d:ea5a:233d%rmnet_sdio0

2.使用 hashCodeFormatter***** IP=238.194.77.212

ご覧のとおり、2番目の方法で必要なものが正確に得られます。

public String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress()) {
                    String ip = Formatter.formatIpAddress(inetAddress.hashCode());
                    Log.i(TAG, "***** IP="+ ip);
                    return ip;
                }
            }
        }
    } catch (SocketException ex) {
        Log.e(TAG, ex.toString());
    }
    return null;
}

1
getHostAddress()追加したフォーマッタと同じことを行います。
Phil

10
hashCodeの使用は明らかに間違っており、ナンセンスを返します。代わりにInetAddress.getHostAddress()を使用してください。
Pointer Null

この部分を変更します:if(!inetAddress.isLoopbackAddress()){String ip = Formatter.formatIpAddress(inetAddress.hashCode()); Log.i(TAG、 "***** IP =" + ip); リターンIP; }これで:if(!inetAddress.isLoopbackAddress()&& InetAddressUtils.isIPv4Address(inetAddress.getHostAddress())){return inetAddress .getHostAddress()。toString(); }これにより、正しいIP形式が得られます
Chuy47

コードは最初のIPのみを返します。電話には、セルラー、WIFI、BTアドレスが同時に含まれる場合があります
reker

@ Chuy47は、InetAddressUtilsが見つからないことを示しています
FabioR

61
public static String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                    return inetAddress.getHostAddress();
                }
            }
        }
    } catch (SocketException ex) {
        ex.printStackTrace();
    }
    return null;
}

ipv4アドレスかどうかを確認するためにinetAddressinstanceof Inet4Addressを追加しました。


私の日を救った!ありがとう。samsung s7エッジで動作する唯一のコードです
Dhananjay Sarsonia

これは本当の答えですが、WiFiインターフェイスのみを取得するだけではありません。
nyconing

これは正解です。WiFiとモバイルネットワークの両方で機能し、カスタムフォーマットの代わりに「getHostAddress」を使用します。
バラージュGerlei

しかし、それは私のローカルIPを取得します、私は私のパブリックIPが必要です(OPも必要だと思います)
FabioR

53

正しい答えはありますが、ここで私の答えを共有し、この方法がより便利になることを願っています。

WifiManager wifiMan = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInf = wifiMan.getConnectionInfo();
int ipAddress = wifiInf.getIpAddress();
String ip = String.format("%d.%d.%d.%d", (ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));

4
ありがとう!Formatterは非推奨であり、単純なビットロジックを書く気にはなれませんでした。
ウィリアムモリソン

4
:素晴らしい作品が、WIFI_STATE許可が必要<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
ブレント・ファウスト

1
フォーマッタを使用していますが、機能しません。それは素晴らしいです!本当に感謝。最後の行で何が行われるのか説明してもらえますか?私は%d。%d。%d。%dを知っていますが、他の人ですか?おかげで
GünayGültekin

1
いや、これはOPに直接答えません。WiFiを使用してインターネットに接続するすべてのAndroidデバイスではないからです。それは、などのイーサネット上のNAT変換LAN、またはBTはなくNAT変換WAN接続を持っているかもしれません
nyconing

31

以下のコードが役立つかもしれません。許可を追加することを忘れないでください。

public String getLocalIpAddress(){
   try {
       for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();  
       en.hasMoreElements();) {
       NetworkInterface intf = en.nextElement();
           for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
           InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress()) {
                return inetAddress.getHostAddress();
                }
           }
       }
       } catch (Exception ex) {
          Log.e("IP Address", ex.toString());
      }
      return null;
}

マニフェストファイルに以下の権限を追加します。

 <uses-permission android:name="android.permission.INTERNET" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

ハッピーコーディング!!


6
"fe80 :: f225:b7ff:fe8c:d357%wlan0"
Jorgesys

@Jorgesysは、彼がinetAddress instanceof Inet4Addressを追加したevertvandenbruelの回答を確認します
temirbek 2017年

3
このようなif条件を変更して、正しいip:if(!inetAddress.isLoopbackAddress()&& inetAddress instanceof Inet4Address)を取得します
Rajesh.k

コードは最初のIPのみを返します。電話は、セルラー、WIFI、BTアドレスを同時に持つことができます
reker

ホットスポットを使用している場合、複数のIPを取得する可能性があります
Harsha

16

これまでに提供されたソリューションの場合のように、権限を追加する必要はありません。このWebサイトを文字列としてダウンロードします。

http://www.ip-api.com/json

または

http://www.telize.com/geoip

ウェブサイトを文字列としてダウンロードするには、Javaコードを使用します。

http://www.itcuties.com/java/read-url-to-string/

次のようにJSONオブジェクトを解析します。

https://stackoverflow.com/a/18998203/1987258

json属性「query」または「ip」にはIPアドレスが含まれています。


2
これにはインターネット接続が必要です。大きな問題
デビッド

4
なぜそれが大きな問題なのですか?もちろん、IPアドレスはそのような接続に技術的に関連しているため、インターネット接続が必要です。家を出てレストランに行く場合は、別のインターネット接続、つまり別のIPアドレスを使用します。ACCESS_NETWORK_STATEやACCESS_WIFI_STATEなどを追加する必要はありません。インターネット接続は、私が提供するソリューションに必要な唯一の許可です。
Daan

2
どのドメイン?ip-api.comが機能しない場合は、telize.comをフォールバックとして使用できます。それ以外の場合は、api.ipify.orgを使用できます。こちら(jsonではありません):ip.jsontest.com/?callback=showIPでも入手できます。多くのアプリは、オンラインのままであることが保証されているドメインを使用しています。それは正常です。ただし、フォールバックを使用すると、問題が発生する可能性が非常に低くなります。
大安

3
デビッドの元のポイントはまだ残っています。インターネットにアクセスできない内部ネットワークを使用している場合はどうでしょうか。
hiandbaii 2016年

2
私はそのことについて考えたことはありません。ネットワークが絶対に必要だがインターネットなしで動作するはずのアプリの実用的な目的がわからないからです(たぶん、モバイルデバイスでは見られません)。
Daan

9
private InetAddress getLocalAddress()throws IOException {

            try {
                for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                    NetworkInterface intf = en.nextElement();
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()) {
                            //return inetAddress.getHostAddress().toString();
                            return inetAddress;
                        }
                    }
                }
            } catch (SocketException ex) {
                Log.e("SALMAN", ex.toString());
            }
            return null;
        }

1
これが192.168.0.xのようなwifiインターフェイスからプライベートネットワークIPを返す可能性はありますか?それともインターネットで使用される外部IPアドレスを常に返しますか?
ベンH

9

メソッドgetDeviceIpAddressはデバイスのIPアドレスを返し、接続されている場合はwifiインターフェイスアドレスを優先します。

  @NonNull
    private String getDeviceIpAddress() {
        String actualConnectedToNetwork = null;
        ConnectivityManager connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connManager != null) {
            NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWifi.isConnected()) {
                actualConnectedToNetwork = getWifiIp();
            }
        }
        if (TextUtils.isEmpty(actualConnectedToNetwork)) {
            actualConnectedToNetwork = getNetworkInterfaceIpAddress();
        }
        if (TextUtils.isEmpty(actualConnectedToNetwork)) {
            actualConnectedToNetwork = "127.0.0.1";
        }
        return actualConnectedToNetwork;
    }

    @Nullable
    private String getWifiIp() {
        final WifiManager mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (mWifiManager != null && mWifiManager.isWifiEnabled()) {
            int ip = mWifiManager.getConnectionInfo().getIpAddress();
            return (ip & 0xFF) + "." + ((ip >> 8) & 0xFF) + "." + ((ip >> 16) & 0xFF) + "."
                    + ((ip >> 24) & 0xFF);
        }
        return null;
    }


    @Nullable
    public String getNetworkInterfaceIpAddress() {
        try {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface networkInterface = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                        String host = inetAddress.getHostAddress();
                        if (!TextUtils.isEmpty(host)) {
                            return host;
                        }
                    }
                }

            }
        } catch (Exception ex) {
            Log.e("IP Address", "getLocalIpAddress", ex);
        }
        return null;
    }

4

これは、無関係な情報を取り除き、役立つコメントを追加し、変数をより明確に命名し、ロジックを改善するこの回答の書き直しです。

次の権限を含めることを忘れないでください。

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

InternetHelper.java:

public class InternetHelper {

    /**
     * Get IP address from first non-localhost interface
     *
     * @param useIPv4 true=return ipv4, false=return ipv6
     * @return address or empty string
     */
    public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces =
                    Collections.list(NetworkInterface.getNetworkInterfaces());

            for (NetworkInterface interface_ : interfaces) {

                for (InetAddress inetAddress :
                        Collections.list(interface_.getInetAddresses())) {

                    /* a loopback address would be something like 127.0.0.1 (the device
                       itself). we want to return the first non-loopback address. */
                    if (!inetAddress.isLoopbackAddress()) {
                        String ipAddr = inetAddress.getHostAddress();
                        boolean isIPv4 = ipAddr.indexOf(':') < 0;

                        if (isIPv4 && !useIPv4) {
                            continue;
                        }
                        if (useIPv4 && !isIPv4) {
                            int delim = ipAddr.indexOf('%'); // drop ip6 zone suffix
                            ipAddr = delim < 0 ? ipAddr.toUpperCase() :
                                    ipAddr.substring(0, delim).toUpperCase();
                        }
                        return ipAddr;
                    }
                }

            }
        } catch (Exception ignored) { } // if we can't connect, just return empty string
        return "";
    }

    /**
     * Get IPv4 address from first non-localhost interface
     *
     * @return address or empty string
     */
    public static String getIPAddress() {
        return getIPAddress(true);
    }

}

4

kotlinミニマリストバージョン

fun getIpv4HostAddress(): String {
    NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
        networkInterface.inetAddresses?.toList()?.find {
            !it.isLoopbackAddress && it is Inet4Address
        }?.let { return it.hostAddress }
    }
    return ""
}

3
WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = BigInteger.valueOf(wm.getDhcpInfo().netmask).toString();

3

このサイトからIPを取得するには、Volleyを使用するだけです

RequestQueue queue = Volley.newRequestQueue(this);    
String urlip = "http://checkip.amazonaws.com/";

    StringRequest stringRequest = new StringRequest(Request.Method.GET, urlip, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            txtIP.setText(response);

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            txtIP.setText("didnt work");
        }
    });

    queue.add(stringRequest);

2

最近、getLocalIpAddress()ネットワークから切断されているにもかかわらず(サービスインジケータなし)、IPアドレスが返されます。これは、[設定]> [端末情報]> [ステータス]に表示されるIPアドレスが、アプリケーションの想定と異なっていたことを意味します。

前にこのコードを追加して回避策を実装しました:

ConnectivityManager cm = getConnectivityManager();
NetworkInfo net = cm.getActiveNetworkInfo();
if ((null == net) || !net.isConnectedOrConnecting()) {
    return null;
}

それは誰かにベルを鳴らしますか?


2

Kotlinで、フォーマッターなし

private fun getIPAddress(useIPv4 : Boolean): String {
    try {
        var interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
        for (intf in interfaces) {
            var addrs = Collections.list(intf.getInetAddresses());
            for (addr in addrs) {
                if (!addr.isLoopbackAddress()) {
                    var sAddr = addr.getHostAddress();
                    var isIPv4: Boolean
                    isIPv4 = sAddr.indexOf(':')<0
                    if (useIPv4) {
                        if (isIPv4)
                            return sAddr;
                    } else {
                        if (!isIPv4) {
                            var delim = sAddr.indexOf('%') // drop ip6 zone suffix
                            if (delim < 0) {
                                return sAddr.toUpperCase()
                            }
                            else {
                                return sAddr.substring(0, delim).toUpperCase()
                            }
                        }
                    }
                }
            }
        }
    } catch (e: java.lang.Exception) { }
    return ""
}

2

アクティビティでは、次の関数getIpAddress(context)が電話のIPアドレスを返します。

public static String getIpAddress(Context context) {
    WifiManager wifiManager = (WifiManager) context.getApplicationContext()
                .getSystemService(WIFI_SERVICE);

    String ipAddress = intToInetAddress(wifiManager.getDhcpInfo().ipAddress).toString();

    ipAddress = ipAddress.substring(1);

    return ipAddress;
}

public static InetAddress intToInetAddress(int hostAddress) {
    byte[] addressBytes = { (byte)(0xff & hostAddress),
                (byte)(0xff & (hostAddress >> 8)),
                (byte)(0xff & (hostAddress >> 16)),
                (byte)(0xff & (hostAddress >> 24)) };

    try {
        return InetAddress.getByAddress(addressBytes);
    } catch (UnknownHostException e) {
        throw new AssertionError();
    }
}

私は0.0.0.0を取得しています
夏みゆ

スマートフォンはWi-Fiネットワークに接続されていますか?wifiManager.getConnectionInfo()。getSSID()を呼び出すと、どの値が返されますか?
matdev

WiFiではなく、モバイルデータに接続されたデバイスで機能しますか?
セルゲイ

いいえ、この方法はデバイスがWiFiに接続されている場合にのみ機能します
matdev

1

@Nileshと@anargundのKotlinバージョンは次のとおりです

  fun getIpAddress(): String {
    var ip = ""
    try {
        val wm = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
        ip = Formatter.formatIpAddress(wm.connectionInfo.ipAddress)
    } catch (e: java.lang.Exception) {

    }

    if (ip.isEmpty()) {
        try {
            val en = NetworkInterface.getNetworkInterfaces()
            while (en.hasMoreElements()) {
                val networkInterface = en.nextElement()
                val enumIpAddr = networkInterface.inetAddresses
                while (enumIpAddr.hasMoreElements()) {
                    val inetAddress = enumIpAddr.nextElement()
                    if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                        val host = inetAddress.getHostAddress()
                        if (host.isNotEmpty()) {
                            ip =  host
                            break;
                        }
                    }
                }

            }
        } catch (e: java.lang.Exception) {

        }
    }

   if (ip.isEmpty())
      ip = "127.0.0.1"
    return ip
}

1
これが実際のプロジェクトのコードスタイルである場合は、robert martinによる「クリーンコード」を読むことをお勧めします
Ahmed Adel Ismail

1

デバイスには複数のIPアドレスがあり、特定のアプリで使用されているものは、リクエストを受信するサーバーが表示するIPではない場合があります。実際、一部のユーザーはVPNやプロキシなどを使用しています Cloudflare Warp

デバイスからリクエストを受信するサーバーが示すIPアドレスを取得することが目的である場合、JavaクライアントでIpregistry(免責事項:私は会社で働いています)などのIP地理位置情報サービスにクエリを実行するのが最適です。

https://github.com/ipregistry/ipregistry-java

IpregistryClient client = new IpregistryClient("tryout");
RequesterIpInfo requesterIpInfo = client.lookup();
requesterIpInfo.getIp();

本当に使いやすいだけでなく、国、言語、通貨、デバイスIPのタイムゾーンなどの追加情報を取得し、ユーザーがプロキシを使用しているかどうかを確認できます。


1

これは、インターネット上に存在する最も簡単でシンプルな方法です...まず、この許可をマニフェストファイルに追加します...

  1. "インターネット"

  2. 「ACCESS_NETWORK_STATE」

これをアクティビティのonCreateファイルに追加します。

    getPublicIP();

次に、この関数をMainActivity.classに追加します。

    private void getPublicIP() {
ArrayList<String> urls=new ArrayList<String>(); //to read each line

        new Thread(new Runnable(){
            public void run(){
                //TextView t; //to show the result, please declare and find it inside onCreate()

                try {
                    // Create a URL for the desired page
                    URL url = new URL("https://api.ipify.org/"); //My text file location
                    //First open the connection
                    HttpURLConnection conn=(HttpURLConnection) url.openConnection();
                    conn.setConnectTimeout(60000); // timing out in a minute

                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));

                    //t=(TextView)findViewById(R.id.TextView1); // ideally do this in onCreate()
                    String str;
                    while ((str = in.readLine()) != null) {
                        urls.add(str);
                    }
                    in.close();
                } catch (Exception e) {
                    Log.d("MyTag",e.toString());
                }

                //since we are in background thread, to post results we have to go back to ui thread. do the following for that

                PermissionsActivity.this.runOnUiThread(new Runnable(){
                    public void run(){
                        try {
                            Toast.makeText(PermissionsActivity.this, "Public IP:"+urls.get(0), Toast.LENGTH_SHORT).show();
                        }
                        catch (Exception e){
                            Toast.makeText(PermissionsActivity.this, "TurnOn wiffi to get public ip", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

            }
        }).start();

    }


urls.get(0)には、パブリックIPアドレスが含まれています。
Zia Muhammad

次のようにアクティビティファイルで宣言する必要があります。ArrayList <String> urls = new ArrayList <String>(); //各行を読み取る
Zia Muhammad

0

シェルがある場合; ifconfig eth0はx86デバイスでも動作しました


0

このコードを確認してください...このコードを使用します。モバイルインターネットからIPを取得します...

for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
                NetworkInterface intf = en.nextElement();
                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                    InetAddress inetAddress = enumIpAddr.nextElement();
                    if (!inetAddress.isLoopbackAddress()) {
                        return inetAddress.getHostAddress().toString();
                    }
                }
            }

0

私はAndroidを使用していませんが、まったく異なる方法でこれに取り組みます。

次のようなクエリをGoogleに送信します。https//www.google.com/webhp?sourceid = chrome-instant&ion = 1&espv = 2&ie = UTF-8#q = my%20ip

そして、応答が投稿されるHTMLフィールドを参照してください。ソースに直接問い合わせることもできます。

Googleは、あなたのアプリケーションよりも長く存在することを望んでいます。

現時点では、ユーザーがインターネットに接続していない可能性があります。どうしますか?

幸運を


面白い!そして、Googleには、HTMLをスキャンするよりも安定したIPを返すようなAPI呼び出しがあると思います。
Scott Biggs

0

あなたはこれを行うことができます

String stringUrl = "https://ipinfo.io/ip";
//String stringUrl = "http://whatismyip.akamai.com/";
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(MainActivity.instance);
//String url ="http://www.google.com";

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, stringUrl,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                // Display the first 500 characters of the response string.
                Log.e(MGLogTag, "GET IP : " + response);

            }
        }, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        IP = "That didn't work!";
    }
});

// Add the request to the RequestQueue.
queue.add(stringRequest);

0
 //    @NonNull
    public static String getIPAddress() {
        if (TextUtils.isEmpty(deviceIpAddress))
            new PublicIPAddress().execute();
        return deviceIpAddress;
    }

    public static String deviceIpAddress = "";

    public static class PublicIPAddress extends AsyncTask<String, Void, String> {
        InetAddress localhost = null;

        protected String doInBackground(String... urls) {
            try {
                localhost = InetAddress.getLocalHost();
                URL url_name = new URL("http://bot.whatismyipaddress.com");
                BufferedReader sc = new BufferedReader(new InputStreamReader(url_name.openStream()));
                deviceIpAddress = sc.readLine().trim();
            } catch (Exception e) {
                deviceIpAddress = "";
            }
            return deviceIpAddress;
        }

        protected void onPostExecute(String string) {
            Lg.d("deviceIpAddress", string);
        }
    }

0

正直なところ、私はコードの安全性に少しだけ精通しているので、これはハックっぽいかもしれません。しかし、私にとっては、これが最も用途の広い方法です。

package com.my_objects.ip;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class MyIpByHost 
{
  public static void main(String a[])
  {
   try 
    {
      InetAddress host = InetAddress.getByName("nameOfDevice or webAddress");
      System.out.println(host.getHostAddress());
    } 
   catch (UnknownHostException e) 
    {
      e.printStackTrace();
    }
} }

0

いくつかのアイデアをコンパイルWifiManagerして、より良いkotlinソリューションでwifi IPを取得します。

private fun getWifiIp(context: Context): String? {
  return context.getSystemService<WifiManager>().let {
     when {
      it == null -> "No wifi available"
      !it.isWifiEnabled -> "Wifi is disabled"
      it.connectionInfo == null -> "Wifi not connected"
      else -> {
        val ip = it.connectionInfo.ipAddress
        ((ip and 0xFF).toString() + "." + (ip shr 8 and 0xFF) + "." + (ip shr 16 and 0xFF) + "." + (ip shr 24 and 0xFF))
      }
    }
  }
}

または、NetworkInterface次を介してip4ループバックデバイスのIPアドレスを取得できます。

fun getNetworkIp4LoopbackIps(): Map<String, String> = try {
  NetworkInterface.getNetworkInterfaces()
    .asSequence()
    .associate { it.displayName to it.ip4LoopbackIps() }
    .filterValues { it.isNotEmpty() }
} catch (ex: Exception) {
  emptyMap()
}

private fun NetworkInterface.ip4LoopbackIps() =
  inetAddresses.asSequence()
    .filter { !it.isLoopbackAddress && it is Inet4Address }
    .map { it.hostAddress }
    .filter { it.isNotEmpty() }
    .joinToString()

-2

私がテストしたものに基づいて、これは私の提案です

import java.net.*;
import java.util.*;

public class hostUtil
{
   public static String HOST_NAME = null;
   public static String HOST_IPADDRESS = null;

   public static String getThisHostName ()
   {
      if (HOST_NAME == null) obtainHostInfo ();
      return HOST_NAME;
   }

   public static String getThisIpAddress ()
   {
      if (HOST_IPADDRESS == null) obtainHostInfo ();
      return HOST_IPADDRESS;
   }

   protected static void obtainHostInfo ()
   {
      HOST_IPADDRESS = "127.0.0.1";
      HOST_NAME = "localhost";

      try
      {
         InetAddress primera = InetAddress.getLocalHost();
         String hostname = InetAddress.getLocalHost().getHostName ();

         if (!primera.isLoopbackAddress () &&
             !hostname.equalsIgnoreCase ("localhost") &&
              primera.getHostAddress ().indexOf (':') == -1)
         {
            // Got it without delay!!
            HOST_IPADDRESS = primera.getHostAddress ();
            HOST_NAME = hostname;
            //System.out.println ("First try! " + HOST_NAME + " IP " + HOST_IPADDRESS);
            return;
         }
         for (Enumeration<NetworkInterface> netArr = NetworkInterface.getNetworkInterfaces(); netArr.hasMoreElements();)
         {
            NetworkInterface netInte = netArr.nextElement ();
            for (Enumeration<InetAddress> addArr = netInte.getInetAddresses (); addArr.hasMoreElements ();)
            {
               InetAddress laAdd = addArr.nextElement ();
               String ipstring = laAdd.getHostAddress ();
               String hostName = laAdd.getHostName ();

               if (laAdd.isLoopbackAddress()) continue;
               if (hostName.equalsIgnoreCase ("localhost")) continue;
               if (ipstring.indexOf (':') >= 0) continue;

               HOST_IPADDRESS = ipstring;
               HOST_NAME = hostName;
               break;
            }
         }
      } catch (Exception ex) {}
   }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.